ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / scsi / advansys.c
1 #define ASC_VERSION "3.3GJ"    /* AdvanSys Driver Version */
2
3 /*
4  * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
5  *
6  * Copyright (c) 1995-2000 Advanced System Products, Inc.
7  * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
8  * All Rights Reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that redistributions of source
12  * code retain the above copyright notice and this comment without
13  * modification.
14  *
15  * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
16  * changed its name to ConnectCom Solutions, Inc.
17  *
18  * There is an AdvanSys Linux WWW page at:
19  *  http://www.connectcom.net/downloads/software/os/linux.html
20  *  http://www.advansys.com/linux.html
21  *
22  * The latest released version of the AdvanSys driver is available at:
23  *  ftp://ftp.advansys.com/pub/linux/linux.tgz
24  *  ftp://ftp.connectcom.net/pub/linux/linux.tgz
25  *
26  * Please send questions, comments, bug reports to:
27  *  support@connectcom.net
28  */
29
30 /*
31
32   Documentation for the AdvanSys Driver
33
34   A. Linux Kernels Supported by this Driver
35   B. Adapters Supported by this Driver
36   C. Linux source files modified by AdvanSys Driver
37   D. Source Comments
38   E. Driver Compile Time Options and Debugging
39   F. Driver LILO Option
40   G. Tests to run before releasing new driver
41   H. Release History
42   I. Known Problems/Fix List
43   J. Credits (Chronological Order)
44   K. ConnectCom (AdvanSys) Contact Information
45
46   A. Linux Kernels Supported by this Driver
47
48      This driver has been tested in the following Linux kernels: v2.2.18
49      v2.4.0. The driver is supported on v2.2 and v2.4 kernels and on x86,
50      alpha, and PowerPC platforms.
51
52   B. Adapters Supported by this Driver
53
54      AdvanSys (Advanced System Products, Inc.) manufactures the following
55      RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow
56      (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI
57      buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit
58      transfer) SCSI Host Adapters for the PCI bus.
59
60      The CDB counts below indicate the number of SCSI CDB (Command
61      Descriptor Block) requests that can be stored in the RISC chip
62      cache and board LRAM. A CDB is a single SCSI command. The driver
63      detect routine will display the number of CDBs available for each
64      adapter detected. The number of CDBs used by the driver can be
65      lowered in the BIOS by changing the 'Host Queue Size' adapter setting.
66
67      Laptop Products:
68         ABP-480 - Bus-Master CardBus (16 CDB) (2.4 kernel and greater)
69
70      Connectivity Products:
71         ABP510/5150 - Bus-Master ISA (240 CDB)
72         ABP5140 - Bus-Master ISA PnP (16 CDB)
73         ABP5142 - Bus-Master ISA PnP with floppy (16 CDB)
74         ABP902/3902 - Bus-Master PCI (16 CDB)
75         ABP3905 - Bus-Master PCI (16 CDB)
76         ABP915 - Bus-Master PCI (16 CDB)
77         ABP920 - Bus-Master PCI (16 CDB)
78         ABP3922 - Bus-Master PCI (16 CDB)
79         ABP3925 - Bus-Master PCI (16 CDB)
80         ABP930 - Bus-Master PCI (16 CDB)
81         ABP930U - Bus-Master PCI Ultra (16 CDB)
82         ABP930UA - Bus-Master PCI Ultra (16 CDB)
83         ABP960 - Bus-Master PCI MAC/PC (16 CDB)
84         ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
85
86      Single Channel Products:
87         ABP542 - Bus-Master ISA with floppy (240 CDB)
88         ABP742 - Bus-Master EISA (240 CDB)
89         ABP842 - Bus-Master VL (240 CDB)
90         ABP940 - Bus-Master PCI (240 CDB)
91         ABP940U - Bus-Master PCI Ultra (240 CDB)
92         ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB)
93         ABP970 - Bus-Master PCI MAC/PC (240 CDB)
94         ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
95         ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB)
96         ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB)
97         ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB)
98         ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB)
99
100      Multi-Channel Products:
101         ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
102         ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
103         ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
104         ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel)
105         ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
106         ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
107         ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.)
108         ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB)
109         ABP3950U3W - Bus-Master PCI Dual LVD2/Ultra3-Wide (253 CDB)
110
111   C. Linux source files modified by AdvanSys Driver
112
113      This section for historical purposes documents the changes
114      originally made to the Linux kernel source to add the advansys
115      driver. As Linux has changed some of these files have also
116      been modified.
117
118      1. linux/arch/i386/config.in:
119
120           bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
121
122      2. linux/drivers/scsi/hosts.c:
123
124           #ifdef CONFIG_SCSI_ADVANSYS
125           #include "advansys.h"
126           #endif
127
128         and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
129
130           #ifdef CONFIG_SCSI_ADVANSYS
131           ADVANSYS,
132           #endif
133
134      3. linux/drivers/scsi/Makefile:
135
136           ifdef CONFIG_SCSI_ADVANSYS
137           SCSI_SRCS := $(SCSI_SRCS) advansys.c
138           SCSI_OBJS := $(SCSI_OBJS) advansys.o
139           else
140           SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
141           endif
142
143      4. linux/init/main.c:
144
145           extern void advansys_setup(char *str, int *ints);
146
147         and add the following lines to the bootsetups[] array.
148
149           #ifdef CONFIG_SCSI_ADVANSYS
150              { "advansys=", advansys_setup },
151           #endif
152
153   D. Source Comments
154
155      1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
156
157      2. This driver should be maintained in multiple files. But to make
158         it easier to include with Linux and to follow Linux conventions,
159         the whole driver is maintained in the source files advansys.h and
160         advansys.c. In this file logical sections of the driver begin with
161         a comment that contains '---'. The following are the logical sections
162         of the driver below.
163
164            --- Linux Version
165            --- Linux Include File
166            --- Driver Options
167            --- Debugging Header
168            --- Asc Library Constants and Macros
169            --- Adv Library Constants and Macros
170            --- Driver Constants and Macros
171            --- Driver Structures
172            --- Driver Data
173            --- Driver Function Prototypes
174            --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
175            --- Loadable Driver Support
176            --- Miscellaneous Driver Functions
177            --- Functions Required by the Asc Library
178            --- Functions Required by the Adv Library
179            --- Tracing and Debugging Functions
180            --- Asc Library Functions
181            --- Adv Library Functions
182
183      3. The string 'XXX' is used to flag code that needs to be re-written
184         or that contains a problem that needs to be addressed.
185
186      4. I have stripped comments from and reformatted the source for the
187         Asc Library and Adv Library to reduce the size of this file. This
188         source can be found under the following headings. The Asc Library
189         is used to support Narrow Boards. The Adv Library is used to
190         support Wide Boards.
191
192            --- Asc Library Constants and Macros
193            --- Adv Library Constants and Macros
194            --- Asc Library Functions
195            --- Adv Library Functions
196
197   E. Driver Compile Time Options and Debugging
198
199      In this source file the following constants can be defined. They are
200      defined in the source below. Both of these options are enabled by
201      default.
202
203      1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled)
204
205         Enabling this option adds assertion logic statements to the
206         driver. If an assertion fails a message will be displayed to
207         the console, but the system will continue to operate. Any
208         assertions encountered should be reported to the person
209         responsible for the driver. Assertion statements may proactively
210         detect problems with the driver and facilitate fixing these
211         problems. Enabling assertions will add a small overhead to the
212         execution of the driver.
213
214      2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled)
215
216         Enabling this option adds tracing functions to the driver and
217         the ability to set a driver tracing level at boot time. This
218         option will also export symbols not required outside the driver to
219         the kernel name space. This option is very useful for debugging
220         the driver, but it will add to the size of the driver execution
221         image and add overhead to the execution of the driver.
222
223         The amount of debugging output can be controlled with the global
224         variable 'asc_dbglvl'. The higher the number the more output. By
225         default the debug level is 0.
226
227         If the driver is loaded at boot time and the LILO Driver Option
228         is included in the system, the debug level can be changed by
229         specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
230         first three hex digits of the pseudo I/O Port must be set to
231         'deb' and the fourth hex digit specifies the debug level: 0 - F.
232         The following command line will look for an adapter at 0x330
233         and set the debug level to 2.
234
235            linux advansys=0x330,0,0,0,0xdeb2
236
237         If the driver is built as a loadable module this variable can be
238         defined when the driver is loaded. The following insmod command
239         will set the debug level to one.
240
241            insmod advansys.o asc_dbglvl=1
242
243         Debugging Message Levels:
244            0: Errors Only
245            1: High-Level Tracing
246            2-N: Verbose Tracing
247
248         To enable debug output to console, please make sure that:
249
250         a. System and kernel logging is enabled (syslogd, klogd running).
251         b. Kernel messages are routed to console output. Check
252            /etc/syslog.conf for an entry similar to this:
253
254                 kern.*                  /dev/console
255
256         c. klogd is started with the appropriate -c parameter
257            (e.g. klogd -c 8)
258
259         This will cause printk() messages to be be displayed on the
260         current console. Refer to the klogd(8) and syslogd(8) man pages
261         for details.
262
263         Alternatively you can enable printk() to console with this
264         program. However, this is not the 'official' way to do this.
265         Debug output is logged in /var/log/messages.
266
267           main()
268           {
269                   syscall(103, 7, 0, 0);
270           }
271
272         Increasing LOG_BUF_LEN in kernel/printk.c to something like
273         40960 allows more debug messages to be buffered in the kernel
274         and written to the console or log file.
275
276      3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0)
277
278         Enabling this option adds statistics collection and display
279         through /proc to the driver. The information is useful for
280         monitoring driver and device performance. It will add to the
281         size of the driver execution image and add minor overhead to
282         the execution of the driver.
283
284         Statistics are maintained on a per adapter basis. Driver entry
285         point call counts and transfer size counts are maintained.
286         Statistics are only available for kernels greater than or equal
287         to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured.
288
289         AdvanSys SCSI adapter files have the following path name format:
290
291            /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
292
293         This information can be displayed with cat. For example:
294
295            cat /proc/scsi/advansys/0
296
297         When ADVANSYS_STATS is not defined the AdvanSys /proc files only
298         contain adapter and device configuration information.
299
300   F. Driver LILO Option
301
302      If init/main.c is modified as described in the 'Directions for Adding
303      the AdvanSys Driver to Linux' section (B.4.) above, the driver will
304      recognize the 'advansys' LILO command line and /etc/lilo.conf option.
305      This option can be used to either disable I/O port scanning or to limit
306      scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
307      PCI boards will still be searched for and detected. This option only
308      affects searching for ISA and VL boards.
309
310      Examples:
311        1. Eliminate I/O port scanning:
312             boot: linux advansys=
313               or
314             boot: linux advansys=0x0
315        2. Limit I/O port scanning to one I/O port:
316             boot: linux advansys=0x110
317        3. Limit I/O port scanning to four I/O ports:
318             boot: linux advansys=0x110,0x210,0x230,0x330
319
320      For a loadable module the same effect can be achieved by setting
321      the 'asc_iopflag' variable and 'asc_ioport' array when loading
322      the driver, e.g.
323
324            insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
325
326      If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1)
327      I/O Port may be added to specify the driver debug level. Refer to
328      the 'Driver Compile Time Options and Debugging' section above for
329      more information.
330
331   G. Tests to run before releasing new driver
332
333      1. In the supported kernels verify there are no warning or compile
334         errors when the kernel is built as both a driver and as a module
335         and with the following options:
336
337         ADVANSYS_DEBUG - enabled and disabled
338         CONFIG_SMP - enabled and disabled
339         CONFIG_PROC_FS - enabled and disabled
340
341      2. Run tests on an x86, alpha, and PowerPC with at least one narrow
342         card and one wide card attached to a hard disk and CD-ROM drive:
343         fdisk, mkfs, fsck, bonnie, copy/compare test from the
344         CD-ROM to the hard drive.
345
346   H. Release History
347
348      BETA-1.0 (12/23/95):
349          First Release
350
351      BETA-1.1 (12/28/95):
352          1. Prevent advansys_detect() from being called twice.
353          2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
354
355      1.2 (1/12/96):
356          1. Prevent re-entrancy in the interrupt handler which
357             resulted in the driver hanging Linux.
358          2. Fix problem that prevented ABP-940 cards from being
359             recognized on some PCI motherboards.
360          3. Add support for the ABP-5140 PnP ISA card.
361          4. Fix check condition return status.
362          5. Add conditionally compiled code for Linux v1.3.X.
363
364      1.3 (2/23/96):
365          1. Fix problem in advansys_biosparam() that resulted in the
366             wrong drive geometry being returned for drives > 1GB with
367             extended translation enabled.
368          2. Add additional tracing during device initialization.
369          3. Change code that only applies to ISA PnP adapter.
370          4. Eliminate 'make dep' warning.
371          5. Try to fix problem with handling resets by increasing their
372             timeout value.
373
374      1.4 (5/8/96):
375          1. Change definitions to eliminate conflicts with other subsystems.
376          2. Add versioning code for the shared interrupt changes.
377          3. Eliminate problem in asc_rmqueue() with iterating after removing
378             a request.
379          4. Remove reset request loop problem from the "Known Problems or
380             Issues" section. This problem was isolated and fixed in the
381             mid-level SCSI driver.
382
383      1.5 (8/8/96):
384          1. Add support for ABP-940U (PCI Ultra) adapter.
385          2. Add support for IRQ sharing by setting the SA_SHIRQ flag for
386             request_irq and supplying a dev_id pointer to both request_irq()
387             and free_irq().
388          3. In AscSearchIOPortAddr11() restore a call to check_region() which
389             should be used before I/O port probing.
390          4. Fix bug in asc_prt_hex() which resulted in the displaying
391             the wrong data.
392          5. Incorporate miscellaneous Asc Library bug fixes and new microcode.
393          6. Change driver versioning to be specific to each Linux sub-level.
394          7. Change statistics gathering to be per adapter instead of global
395             to the driver.
396          8. Add more information and statistics to the adapter /proc file:
397             /proc/scsi/advansys[0...].
398          9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list.
399             This problem has been addressed with the SCSI mid-level changes
400             made in v1.3.89. The advansys_select_queue_depths() function
401             was added for the v1.3.89 changes.
402
403      1.6 (9/10/96):
404          1. Incorporate miscellaneous Asc Library bug fixes and new microcode.
405
406      1.7 (9/25/96):
407          1. Enable clustering and optimize the setting of the maximum number
408             of scatter gather elements for any particular board. Clustering
409             increases CPU utilization, but results in a relatively larger
410             increase in I/O throughput.
411          2. Improve the performance of the request queuing functions by
412             adding a last pointer to the queue structure.
413          3. Correct problems with reset and abort request handling that
414             could have hung or crashed Linux.
415          4. Add more information to the adapter /proc file:
416             /proc/scsi/advansys[0...].
417          5. Remove the request timeout issue form the driver issues list.
418          6. Miscellaneous documentation additions and changes.
419
420      1.8 (10/4/96):
421          1. Make changes to handle the new v2.1.0 kernel memory mapping
422             in which a kernel virtual address may not be equivalent to its
423             bus or DMA memory address.
424          2. Change abort and reset request handling to make it yet even
425             more robust.
426          3. Try to mitigate request starvation by sending ordered requests
427             to heavily loaded, tag queuing enabled devices.
428          4. Maintain statistics on request response time.
429          5. Add request response time statistics and other information to
430             the adapter /proc file: /proc/scsi/advansys[0...].
431
432      1.9 (10/21/96):
433          1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to
434             make use of mid-level SCSI driver device queue depth flow
435             control mechanism. This will eliminate aborts caused by a
436             device being unable to keep up with requests and eliminate
437             repeat busy or QUEUE FULL status returned by a device.
438          2. Incorporate miscellaneous Asc Library bug fixes.
439          3. To allow the driver to work in kernels with broken module
440             support set 'cmd_per_lun' if the driver is compiled as a
441             module. This change affects kernels v1.3.89 to present.
442          4. Remove PCI BIOS address from the driver banner. The PCI BIOS
443             is relocated by the motherboard BIOS and its new address can
444             not be determined by the driver.
445          5. Add mid-level SCSI queue depth information to the adapter
446             /proc file: /proc/scsi/advansys[0...].
447
448      2.0 (11/14/96):
449          1. Change allocation of global structures used for device
450             initialization to guarantee they are in DMA-able memory.
451             Previously when the driver was loaded as a module these
452             structures might not have been in DMA-able memory, causing
453             device initialization to fail.
454
455      2.1 (12/30/96):
456          1. In advansys_reset(), if the request is a synchronous reset
457             request, even if the request serial number has changed, then
458             complete the request.
459          2. Add Asc Library bug fixes including new microcode.
460          3. Clear inquiry buffer before using it.
461          4. Correct ifdef typo.
462
463      2.2 (1/15/97):
464          1. Add Asc Library bug fixes including new microcode.
465          2. Add synchronous data transfer rate information to the
466             adapter /proc file: /proc/scsi/advansys[0...].
467          3. Change ADVANSYS_DEBUG to be disabled by default. This
468             will reduce the size of the driver image, eliminate execution
469             overhead, and remove unneeded symbols from the kernel symbol
470             space that were previously added by the driver.
471          4. Add new compile-time option ADVANSYS_ASSERT for assertion
472             code that used to be defined within ADVANSYS_DEBUG. This
473             option is enabled by default.
474
475      2.8 (5/26/97):
476          1. Change version number to 2.8 to synchronize the Linux driver
477             version numbering with other AdvanSys drivers.
478          2. Reformat source files without tabs to present the same view
479             of the file to everyone regardless of the editor tab setting
480             being used.
481          3. Add Asc Library bug fixes.
482
483      3.1A (1/8/98):
484          1. Change version number to 3.1 to indicate that support for
485             Ultra-Wide adapters (ABP-940UW) is included in this release.
486          2. Add Asc Library (Narrow Board) bug fixes.
487          3. Report an underrun condition with the host status byte set
488             to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which
489             causes the underrun condition to be ignored. When Linux defines
490             its own DID_UNDERRUN the constant defined in this file can be
491             removed.
492          4. Add patch to AscWaitTixISRDone().
493          5. Add support for up to 16 different AdvanSys host adapter SCSI
494             channels in one system. This allows four cards with four channels
495             to be used in one system.
496
497      3.1B (1/9/98):
498          1. Handle that PCI register base addresses are not always page
499             aligned even though ioremap() requires that the address argument
500             be page aligned.
501
502      3.1C (1/10/98):
503          1. Update latest BIOS version checked for from the /proc file.
504          2. Don't set microcode SDTR variable at initialization. Instead
505             wait until device capabilities have been detected from an Inquiry
506             command.
507
508      3.1D (1/21/98):
509          1. Improve performance when the driver is compiled as module by
510             allowing up to 64 scatter-gather elements instead of 8.
511
512      3.1E (5/1/98):
513          1. Set time delay in AscWaitTixISRDone() to 1000 ms.
514          2. Include SMP locking changes.
515          3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS
516             access functions.
517          4. Update board serial number printing.
518          5. Try allocating an IRQ both with and without the SA_INTERRUPT
519             flag set to allow IRQ sharing with drivers that do not set
520             the SA_INTERRUPT flag. Also display a more descriptive error
521             message if request_irq() fails.
522          6. Update to latest Asc and Adv Libraries.
523
524      3.2A (7/22/99):
525          1. Update Adv Library to 4.16 which includes support for
526             the ASC38C0800 (Ultra2/LVD) IC.
527
528      3.2B (8/23/99):
529          1. Correct PCI compile time option for v2.1.93 and greater
530             kernels, advansys_info() string, and debug compile time
531             option.
532          2. Correct DvcSleepMilliSecond() for v2.1.0 and greater
533             kernels. This caused an LVD detection/BIST problem problem
534             among other things.
535          3. Sort PCI cards by PCI Bus, Slot, Function ascending order
536             to be consistent with the BIOS.
537          4. Update to Asc Library S121 and Adv Library 5.2.
538
539      3.2C (8/24/99):
540          1. Correct PCI card detection bug introduced in 3.2B that
541             prevented PCI cards from being detected in kernels older
542             than v2.1.93.
543
544      3.2D (8/26/99):
545          1. Correct /proc device synchronous speed information display.
546             Also when re-negotiation is pending for a target device
547             note this condition with an * and footnote.
548          2. Correct initialization problem with Ultra-Wide cards that
549             have a pre-3.2 BIOS. A microcode variable changed locations
550             in 3.2 and greater BIOSes which caused WDTR to be attempted
551             erroneously with drives that don't support WDTR.
552
553      3.2E (8/30/99):
554          1. Fix compile error caused by v2.3.13 PCI structure change.
555          2. Remove field from ASCEEP_CONFIG that resulted in an EEPROM
556             checksum error for ISA cards.
557          3. Remove ASC_QUEUE_FLOW_CONTROL conditional code. The mid-level
558             SCSI changes that it depended on were never included in Linux.
559
560      3.2F (9/3/99):
561          1. Handle new initial function code added in v2.3.16 for all
562             driver versions.
563
564      3.2G (9/8/99):
565          1. Fix PCI board detection in v2.3.13 and greater kernels.
566          2. Fix comiple errors in v2.3.X with debugging enabled.
567
568      3.2H (9/13/99):
569          1. Add 64-bit address, long support for Alpha and UltraSPARC.
570             The driver has been verified to work on an Alpha system.
571          2. Add partial byte order handling support for Power PC and
572             other big-endian platforms. This support has not yet been
573             completed or verified.
574          3. For wide boards replace block zeroing of request and
575             scatter-gather structures with individual field initialization
576             to improve performance.
577          4. Correct and clarify ROM BIOS version detection.
578
579      3.2I (10/8/99):
580          1. Update to Adv Library 5.4.
581          2. Add v2.3.19 underrun reporting to asc_isr_callback() and
582             adv_isr_callback().  Remove DID_UNDERRUN constant and other
583             no longer needed code that previously documented the lack
584             of underrun handling.
585
586      3.2J (10/14/99):
587          1. Eliminate compile errors for v2.0 and earlier kernels.
588
589      3.2K (11/15/99):
590          1. Correct debug compile error in asc_prt_adv_scsi_req_q().
591          2. Update Adv Library to 5.5.
592          3. Add ifdef handling for /proc changes added in v2.3.28.
593          4. Increase Wide board scatter-gather list maximum length to
594             255 when the driver is compiled into the kernel.
595
596      3.2L (11/18/99):
597          1. Fix bug in adv_get_sglist() that caused an assertion failure
598             at line 7475. The reqp->sgblkp pointer must be initialized
599             to NULL in adv_get_sglist().
600
601      3.2M (11/29/99):
602          1. Really fix bug in adv_get_sglist().
603          2. Incorporate v2.3.29 changes into driver.
604
605      3.2N (4/1/00):
606          1. Add CONFIG_ISA ifdef code.
607          2. Include advansys_interrupts_enabled name change patch.
608          3. For >= v2.3.28 use new SCSI error handling with new function
609             advansys_eh_bus_reset(). Don't include an abort function
610             because of base library limitations.
611          4. For >= v2.3.28 use per board lock instead of io_request_lock.
612          5. For >= v2.3.28 eliminate advansys_command() and
613             advansys_command_done().
614          6. Add some changes for PowerPC (Big Endian) support, but it isn't
615             working yet.
616          7. Fix "nonexistent resource free" problem that occurred on a module
617             unload for boards with an I/O space >= 255. The 'n_io_port' field
618             is only one byte and can not be used to hold an ioport length more
619             than 255.
620
621      3.3A (4/4/00):
622          1. Update to Adv Library 5.8.
623          2. For wide cards add support for CDBs up to 16 bytes.
624          3. Eliminate warnings when CONFIG_PROC_FS is not defined.
625
626      3.3B (5/1/00):
627          1. Support for PowerPC (Big Endian) wide cards. Narrow cards
628             still need work.
629          2. Change bitfields to shift and mask access for endian
630             portability.
631
632      3.3C (10/13/00):
633          1. Update for latest 2.4 kernel.
634          2. Test ABP-480 CardBus support in 2.4 kernel - works!
635          3. Update to Asc Library S123.
636          4. Update to Adv Library 5.12.
637
638      3.3D (11/22/00):
639          1. Update for latest 2.4 kernel.
640          2. Create patches for 2.2 and 2.4 kernels.
641
642      3.3E (1/9/01):
643          1. Now that 2.4 is released remove ifdef code for kernel versions
644             less than 2.2. The driver is now only supported in kernels 2.2,
645             2.4, and greater.
646          2. Add code to release and acquire the io_request_lock in
647             the driver entrypoint functions: advansys_detect and
648             advansys_queuecommand. In kernel 2.4 the SCSI mid-level driver
649             still holds the io_request_lock on entry to SCSI low-level drivers.
650             This was supposed to be removed before 2.4 was released but never
651             happened. When the mid-level SCSI driver is changed all references
652             to the io_request_lock should be removed from the driver.
653          3. Simplify error handling by removing advansys_abort(),
654             AscAbortSRB(), AscResetDevice(). SCSI bus reset requests are
655             now handled by resetting the SCSI bus and fully re-initializing
656             the chip. This simple method of error recovery has proven to work
657             most reliably after attempts at different methods. Also now only
658             support the "new" error handling method and remove the obsolete
659             error handling interface.
660          4. Fix debug build errors.
661
662      3.3F (1/24/01):
663          1. Merge with ConnectCom version from Andy Kellner which
664             updates Adv Library to 5.14.
665          2. Make PowerPC (Big Endian) work for narrow cards and
666             fix problems writing EEPROM for wide cards.
667          3. Remove interrupts_enabled assertion function.
668
669      3.3G (2/16/01):
670          1. Return an error from narrow boards if passed a 16 byte
671             CDB. The wide board can already handle 16 byte CDBs.
672
673      3.3GJ (4/15/02):
674          1. hacks for lk 2.5 series (D. Gilbert)
675
676      3.3GJD (10/14/02):
677          1. change select_queue_depths to slave_configure
678          2. make cmd_per_lun be sane again
679
680   I. Known Problems/Fix List (XXX)
681
682      1. Need to add memory mapping workaround. Test the memory mapping.
683         If it doesn't work revert to I/O port access. Can a test be done
684         safely?
685      2. Handle an interrupt not working. Keep an interrupt counter in
686         the interrupt handler. In the timeout function if the interrupt
687         has not occurred then print a message and run in polled mode.
688      3. Allow bus type scanning order to be changed.
689      4. Need to add support for target mode commands, cf. CAM XPT.
690
691   J. Credits (Chronological Order)
692
693      Bob Frey <bfrey@turbolinux.com.cn> wrote the AdvanSys SCSI driver
694      and maintained it up to 3.3F. He continues to answer questions
695      and help maintain the driver.
696
697      Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and
698      basis for the Linux v1.3.X changes which were included in the
699      1.2 release.
700
701      Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug
702      in advansys_biosparam() which was fixed in the 1.3 release.
703
704      Erik Ratcliffe <erik@caldera.com> has done testing of the
705      AdvanSys driver in the Caldera releases.
706
707      Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to
708      AscWaitTixISRDone() which he found necessary to make the
709      driver work with a SCSI-1 disk.
710
711      Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide
712      support in the 3.1A driver.
713
714      Doug Gilbert <dgilbert@interlog.com> has made changes and
715      suggestions to improve the driver and done a lot of testing.
716
717      Ken Mort <ken@mort.net> reported a DEBUG compile bug fixed
718      in 3.2K.
719
720      Tom Rini <trini@kernel.crashing.org> provided the CONFIG_ISA
721      patch and helped with PowerPC wide and narrow board support.
722
723      Philip Blundell <philip.blundell@pobox.com> provided an
724      advansys_interrupts_enabled patch.
725
726      Dave Jones <dave@denial.force9.co.uk> reported the compiler
727      warnings generated when CONFIG_PROC_FS was not defined in
728      the 3.2M driver.
729
730      Jerry Quinn <jlquinn@us.ibm.com> fixed PowerPC support (endian
731      problems) for wide cards.
732
733      Bryan Henderson <bryanh@giraffe-data.com> helped debug narrow
734      card error handling.
735
736      Manuel Veloso <veloso@pobox.com> worked hard on PowerPC narrow
737      board support and fixed a bug in AscGetEEPConfig().
738
739      Arnaldo Carvalho de Melo <acme@conectiva.com.br> made
740      save_flags/restore_flags changes.
741
742      Andy Kellner <AKellner@connectcom.net> continues the Advansys SCSI
743      driver development for ConnectCom (Version > 3.3F).
744
745   K. ConnectCom (AdvanSys) Contact Information
746
747      Mail:                   ConnectCom Solutions, Inc.
748                              1150 Ringwood Court
749                              San Jose, CA 95131
750      Operator/Sales:         1-408-383-9400
751      FAX:                    1-408-383-9612
752      Tech Support:           1-408-467-2930
753      Tech Support E-Mail:    linux@connectcom.net
754      FTP Site:               ftp.connectcom.net (login: anonymous)
755      Web Site:               http://www.connectcom.net
756
757 */
758
759
760 /*
761  * --- Linux Version
762  */
763
764 #ifndef LINUX_VERSION_CODE
765 #include <linux/version.h>
766 #endif /* LINUX_VERSION_CODE */
767
768 /* Convert Linux Version, Patch-level, Sub-level to LINUX_VERSION_CODE. */
769 #define ASC_LINUX_VERSION(V, P, S)    (((V) * 65536) + ((P) * 256) + (S))
770 #define ASC_LINUX_KERNEL22 (LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,4,0))
771 #define ASC_LINUX_KERNEL24 (LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,4,0))
772
773 /* Driver supported only in version 2.2 and version >= 2.4. */
774 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,2,0) || \
775     (LINUX_VERSION_CODE > ASC_LINUX_VERSION(2,3,0) && \
776      LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,4,0))
777 #error "AdvanSys driver supported only in 2.2 and 2.4 or greater kernels."
778 #endif
779
780 /*
781  * --- Linux Include Files
782  */
783
784 #include <linux/config.h>
785 #include <linux/module.h>
786
787 #if defined(CONFIG_X86) && !defined(CONFIG_ISA)
788 #define CONFIG_ISA
789 #endif /* CONFIG_X86 && !CONFIG_ISA */
790
791 #include <linux/string.h>
792 #include <linux/kernel.h>
793 #include <linux/types.h>
794 #include <linux/ioport.h>
795 #include <linux/interrupt.h>
796 #include <linux/delay.h>
797 #include <linux/slab.h>
798 #include <linux/mm.h>
799 #include <linux/proc_fs.h>
800 #include <linux/init.h>
801 #include <linux/blkdev.h>
802 #include <linux/stat.h>
803 #include <linux/spinlock.h>
804
805 #include <asm/io.h>
806 #include <asm/system.h>
807 #include <asm/dma.h>
808
809 #include "scsi.h"
810 #include "hosts.h"
811 #include "advansys.h"
812 #ifdef CONFIG_PCI
813 #include <linux/pci.h>
814 #endif /* CONFIG_PCI */
815
816
817 /*
818  * --- Driver Options
819  */
820
821 /* Enable driver assertions. */
822 #define ADVANSYS_ASSERT
823
824 /* Enable driver /proc statistics. */
825 #define ADVANSYS_STATS
826
827 /* Enable driver tracing. */
828 /* #define ADVANSYS_DEBUG */
829
830
831 /*
832  * --- Debugging Header
833  */
834
835 #ifdef ADVANSYS_DEBUG
836 #define STATIC
837 #else /* ADVANSYS_DEBUG */
838 #define STATIC static
839 #endif /* ADVANSYS_DEBUG */
840
841
842 /*
843  * --- Asc Library Constants and Macros
844  */
845
846 #define ASC_LIB_VERSION_MAJOR  1
847 #define ASC_LIB_VERSION_MINOR  24
848 #define ASC_LIB_SERIAL_NUMBER  123
849
850 /*
851  * Portable Data Types
852  *
853  * Any instance where a 32-bit long or pointer type is assumed
854  * for precision or HW defined structures, the following define
855  * types must be used. In Linux the char, short, and int types
856  * are all consistent at 8, 16, and 32 bits respectively. Pointers
857  * and long types are 64 bits on Alpha and UltraSPARC.
858  */
859 #define ASC_PADDR __u32         /* Physical/Bus address data type. */
860 #define ASC_VADDR __u32         /* Virtual address data type. */
861 #define ASC_DCNT  __u32         /* Unsigned Data count type. */
862 #define ASC_SDCNT __s32         /* Signed Data count type. */
863
864 /*
865  * These macros are used to convert a virtual address to a
866  * 32-bit value. This currently can be used on Linux Alpha
867  * which uses 64-bit virtual address but a 32-bit bus address.
868  * This is likely to break in the future, but doing this now
869  * will give us time to change the HW and FW to handle 64-bit
870  * addresses.
871  */
872 #define ASC_VADDR_TO_U32   virt_to_bus
873 #define ASC_U32_TO_VADDR   bus_to_virt
874
875 typedef unsigned char uchar;
876
877 #ifndef NULL
878 #define NULL     (0)
879 #endif
880 #ifndef TRUE
881 #define TRUE     (1)
882 #endif
883 #ifndef FALSE
884 #define FALSE    (0)
885 #endif
886
887 #define EOF      (-1)
888 #define ERR      (-1)
889 #define UW_ERR   (uint)(0xFFFF)
890 #define isodd_word(val)   ((((uint)val) & (uint)0x0001) != 0)
891 #define AscPCIConfigVendorIDRegister      0x0000
892 #define AscPCIConfigDeviceIDRegister      0x0002
893 #define AscPCIConfigCommandRegister       0x0004
894 #define AscPCIConfigStatusRegister        0x0006
895 #define AscPCIConfigRevisionIDRegister    0x0008
896 #define AscPCIConfigCacheSize             0x000C
897 #define AscPCIConfigLatencyTimer          0x000D
898 #define AscPCIIOBaseRegister              0x0010
899 #define AscPCICmdRegBits_IOMemBusMaster   0x0007
900 #define ASC_PCI_ID2BUS(id)    ((id) & 0xFF)
901 #define ASC_PCI_ID2DEV(id)    (((id) >> 11) & 0x1F)
902 #define ASC_PCI_ID2FUNC(id)   (((id) >> 8) & 0x7)
903 #define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
904 #define ASC_PCI_VENDORID                  0x10CD
905 #define ASC_PCI_DEVICEID_1200A            0x1100
906 #define ASC_PCI_DEVICEID_1200B            0x1200
907 #define ASC_PCI_DEVICEID_ULTRA            0x1300
908 #define ASC_PCI_REVISION_3150             0x02
909 #define ASC_PCI_REVISION_3050             0x03
910
911 #define  ASC_DVCLIB_CALL_DONE     (1)
912 #define  ASC_DVCLIB_CALL_FAILED   (0)
913 #define  ASC_DVCLIB_CALL_ERROR    (-1)
914
915 /*
916  * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
917  * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
918  * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
919  * SRB structure.
920  */
921 #define CC_VERY_LONG_SG_LIST 0
922 #define ASC_SRB2SCSIQ(srb_ptr)  (srb_ptr)
923
924 #define PortAddr                 unsigned short    /* port address size  */
925 #define inp(port)                inb(port)
926 #define outp(port, byte)         outb((byte), (port))
927
928 #define inpw(port)               inw(port)
929 #define outpw(port, word)        outw((word), (port))
930
931 #define ASC_MAX_SG_QUEUE    7
932 #define ASC_MAX_SG_LIST     255
933
934 #define ASC_CS_TYPE  unsigned short
935
936 #define ASC_IS_ISA          (0x0001)
937 #define ASC_IS_ISAPNP       (0x0081)
938 #define ASC_IS_EISA         (0x0002)
939 #define ASC_IS_PCI          (0x0004)
940 #define ASC_IS_PCI_ULTRA    (0x0104)
941 #define ASC_IS_PCMCIA       (0x0008)
942 #define ASC_IS_MCA          (0x0020)
943 #define ASC_IS_VL           (0x0040)
944 #define ASC_ISA_PNP_PORT_ADDR  (0x279)
945 #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
946 #define ASC_IS_WIDESCSI_16  (0x0100)
947 #define ASC_IS_WIDESCSI_32  (0x0200)
948 #define ASC_IS_BIG_ENDIAN   (0x8000)
949 #define ASC_CHIP_MIN_VER_VL      (0x01)
950 #define ASC_CHIP_MAX_VER_VL      (0x07)
951 #define ASC_CHIP_MIN_VER_PCI     (0x09)
952 #define ASC_CHIP_MAX_VER_PCI     (0x0F)
953 #define ASC_CHIP_VER_PCI_BIT     (0x08)
954 #define ASC_CHIP_MIN_VER_ISA     (0x11)
955 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
956 #define ASC_CHIP_MAX_VER_ISA     (0x27)
957 #define ASC_CHIP_VER_ISA_BIT     (0x30)
958 #define ASC_CHIP_VER_ISAPNP_BIT  (0x20)
959 #define ASC_CHIP_VER_ASYN_BUG    (0x21)
960 #define ASC_CHIP_VER_PCI             0x08
961 #define ASC_CHIP_VER_PCI_ULTRA_3150  (ASC_CHIP_VER_PCI | 0x02)
962 #define ASC_CHIP_VER_PCI_ULTRA_3050  (ASC_CHIP_VER_PCI | 0x03)
963 #define ASC_CHIP_MIN_VER_EISA (0x41)
964 #define ASC_CHIP_MAX_VER_EISA (0x47)
965 #define ASC_CHIP_VER_EISA_BIT (0x40)
966 #define ASC_CHIP_LATEST_VER_EISA   ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
967 #define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER   0x21
968 #define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER   0x0A
969 #define ASC_MAX_VL_DMA_ADDR     (0x07FFFFFFL)
970 #define ASC_MAX_VL_DMA_COUNT    (0x07FFFFFFL)
971 #define ASC_MAX_PCI_DMA_ADDR    (0xFFFFFFFFL)
972 #define ASC_MAX_PCI_DMA_COUNT   (0xFFFFFFFFL)
973 #define ASC_MAX_ISA_DMA_ADDR    (0x00FFFFFFL)
974 #define ASC_MAX_ISA_DMA_COUNT   (0x00FFFFFFL)
975 #define ASC_MAX_EISA_DMA_ADDR   (0x07FFFFFFL)
976 #define ASC_MAX_EISA_DMA_COUNT  (0x07FFFFFFL)
977
978 #define ASC_SCSI_ID_BITS  3
979 #define ASC_SCSI_TIX_TYPE     uchar
980 #define ASC_ALL_DEVICE_BIT_SET  0xFF
981 #define ASC_SCSI_BIT_ID_TYPE  uchar
982 #define ASC_MAX_TID       7
983 #define ASC_MAX_LUN       7
984 #define ASC_SCSI_WIDTH_BIT_SET  0xFF
985 #define ASC_MAX_SENSE_LEN   32
986 #define ASC_MIN_SENSE_LEN   14
987 #define ASC_MAX_CDB_LEN     12
988 #define ASC_SCSI_RESET_HOLD_TIME_US  60
989 #define SCSICMD_TestUnitReady     0x00
990 #define SCSICMD_Rewind            0x01
991 #define SCSICMD_Rezero            0x01
992 #define SCSICMD_RequestSense      0x03
993 #define SCSICMD_Format            0x04
994 #define SCSICMD_FormatUnit        0x04
995 #define SCSICMD_Read6             0x08
996 #define SCSICMD_Write6            0x0A
997 #define SCSICMD_Seek6             0x0B
998 #define SCSICMD_Inquiry           0x12
999 #define SCSICMD_Verify6           0x13
1000 #define SCSICMD_ModeSelect6       0x15
1001 #define SCSICMD_ModeSense6        0x1A
1002 #define SCSICMD_StartStopUnit     0x1B
1003 #define SCSICMD_LoadUnloadTape    0x1B
1004 #define SCSICMD_ReadCapacity      0x25
1005 #define SCSICMD_Read10            0x28
1006 #define SCSICMD_Write10           0x2A
1007 #define SCSICMD_Seek10            0x2B
1008 #define SCSICMD_Erase10           0x2C
1009 #define SCSICMD_WriteAndVerify10  0x2E
1010 #define SCSICMD_Verify10          0x2F
1011 #define SCSICMD_WriteBuffer       0x3B
1012 #define SCSICMD_ReadBuffer        0x3C
1013 #define SCSICMD_ReadLong          0x3E
1014 #define SCSICMD_WriteLong         0x3F
1015 #define SCSICMD_ReadTOC           0x43
1016 #define SCSICMD_ReadHeader        0x44
1017 #define SCSICMD_ModeSelect10      0x55
1018 #define SCSICMD_ModeSense10       0x5A
1019
1020 /* Inquiry Data Peripheral Device Types */
1021 #define SCSI_TYPE_DASD     0x00
1022 #define SCSI_TYPE_SASD     0x01
1023 #define SCSI_TYPE_PRN      0x02
1024 #define SCSI_TYPE_PROC     0x03
1025 #define SCSI_TYPE_WORM     0x04
1026 #define SCSI_TYPE_CDROM    0x05
1027 #define SCSI_TYPE_SCANNER  0x06
1028 #define SCSI_TYPE_OPTMEM   0x07
1029 #define SCSI_TYPE_MED_CHG  0x08
1030 #define SCSI_TYPE_COMM     0x09
1031 #define SCSI_TYPE_UNKNOWN  0x1F
1032
1033 #define ADV_INQ_CLOCKING_ST_ONLY    0x0
1034 #define ADV_INQ_CLOCKING_DT_ONLY    0x1
1035 #define ADV_INQ_CLOCKING_ST_AND_DT  0x3
1036
1037 /*
1038  * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
1039  * and CmdDt (Command Support Data) field bit definitions.
1040  */
1041 #define ADV_INQ_RTN_VPD_AND_CMDDT           0x3
1042 #define ADV_INQ_RTN_CMDDT_FOR_OP_CODE       0x2
1043 #define ADV_INQ_RTN_VPD_FOR_PG_CODE         0x1
1044 #define ADV_INQ_RTN_STD_INQUIRY_DATA        0x0
1045
1046 #define ASC_SCSIDIR_NOCHK    0x00
1047 #define ASC_SCSIDIR_T2H      0x08
1048 #define ASC_SCSIDIR_H2T      0x10
1049 #define ASC_SCSIDIR_NODATA   0x18
1050 #define SCSI_SENKEY_NO_SENSE      0x00
1051 #define SCSI_SENKEY_UNDEFINED     0x01
1052 #define SCSI_SENKEY_NOT_READY     0x02
1053 #define SCSI_SENKEY_MEDIUM_ERR    0x03
1054 #define SCSI_SENKEY_HW_ERR        0x04
1055 #define SCSI_SENKEY_ILLEGAL       0x05
1056 #define SCSI_SENKEY_ATTENTION     0x06
1057 #define SCSI_SENKEY_PROTECTED     0x07
1058 #define SCSI_SENKEY_BLANK         0x08
1059 #define SCSI_SENKEY_V_UNIQUE      0x09
1060 #define SCSI_SENKEY_CPY_ABORT     0x0A
1061 #define SCSI_SENKEY_ABORT         0x0B
1062 #define SCSI_SENKEY_EQUAL         0x0C
1063 #define SCSI_SENKEY_VOL_OVERFLOW  0x0D
1064 #define SCSI_SENKEY_MISCOMP       0x0E
1065 #define SCSI_SENKEY_RESERVED      0x0F
1066 #define SCSI_ASC_NOMEDIA          0x3A
1067 #define ASC_SRB_HOST(x)  ((uchar)((uchar)(x) >> 4))
1068 #define ASC_SRB_TID(x)   ((uchar)((uchar)(x) & (uchar)0x0F))
1069 #define ASC_SRB_LUN(x)   ((uchar)((uint)(x) >> 13))
1070 #define PUT_CDB1(x)   ((uchar)((uint)(x) >> 8))
1071 #define SS_GOOD              0x00
1072 #define SS_CHK_CONDITION     0x02
1073 #define SS_CONDITION_MET     0x04
1074 #define SS_TARGET_BUSY       0x08
1075 #define SS_INTERMID          0x10
1076 #define SS_INTERMID_COND_MET 0x14
1077 #define SS_RSERV_CONFLICT    0x18
1078 #define SS_CMD_TERMINATED    0x22
1079 #define SS_QUEUE_FULL        0x28
1080 #define MS_CMD_DONE    0x00
1081 #define MS_EXTEND      0x01
1082 #define MS_SDTR_LEN    0x03
1083 #define MS_SDTR_CODE   0x01
1084 #define MS_WDTR_LEN    0x02
1085 #define MS_WDTR_CODE   0x03
1086 #define MS_MDP_LEN    0x05
1087 #define MS_MDP_CODE   0x00
1088 #define M1_SAVE_DATA_PTR        0x02
1089 #define M1_RESTORE_PTRS         0x03
1090 #define M1_DISCONNECT           0x04
1091 #define M1_INIT_DETECTED_ERR    0x05
1092 #define M1_ABORT                0x06
1093 #define M1_MSG_REJECT           0x07
1094 #define M1_NO_OP                0x08
1095 #define M1_MSG_PARITY_ERR       0x09
1096 #define M1_LINK_CMD_DONE        0x0A
1097 #define M1_LINK_CMD_DONE_WFLAG  0x0B
1098 #define M1_BUS_DVC_RESET        0x0C
1099 #define M1_ABORT_TAG            0x0D
1100 #define M1_CLR_QUEUE            0x0E
1101 #define M1_INIT_RECOVERY        0x0F
1102 #define M1_RELEASE_RECOVERY     0x10
1103 #define M1_KILL_IO_PROC         0x11
1104 #define M2_QTAG_MSG_SIMPLE      0x20
1105 #define M2_QTAG_MSG_HEAD        0x21
1106 #define M2_QTAG_MSG_ORDERED     0x22
1107 #define M2_IGNORE_WIDE_RESIDUE  0x23
1108
1109 /*
1110  * Inquiry data structure and bitfield macros
1111  *
1112  * Only quantities of more than 1 bit are shifted, since the others are
1113  * just tested for true or false. C bitfields aren't portable between big
1114  * and little-endian platforms so they are not used.
1115  */
1116
1117 #define ASC_INQ_DVC_TYPE(inq)       ((inq)->periph & 0x1f)
1118 #define ASC_INQ_QUALIFIER(inq)      (((inq)->periph & 0xe0) >> 5)
1119 #define ASC_INQ_DVC_TYPE_MOD(inq)   ((inq)->devtype & 0x7f)
1120 #define ASC_INQ_REMOVABLE(inq)      ((inq)->devtype & 0x80)
1121 #define ASC_INQ_ANSI_VER(inq)       ((inq)->ver & 0x07)
1122 #define ASC_INQ_ECMA_VER(inq)       (((inq)->ver & 0x38) >> 3)
1123 #define ASC_INQ_ISO_VER(inq)        (((inq)->ver & 0xc0) >> 6)
1124 #define ASC_INQ_RESPONSE_FMT(inq)   ((inq)->byte3 & 0x0f)
1125 #define ASC_INQ_TERM_IO(inq)        ((inq)->byte3 & 0x40)
1126 #define ASC_INQ_ASYNC_NOTIF(inq)    ((inq)->byte3 & 0x80)
1127 #define ASC_INQ_SOFT_RESET(inq)     ((inq)->flags & 0x01)
1128 #define ASC_INQ_CMD_QUEUE(inq)      ((inq)->flags & 0x02)
1129 #define ASC_INQ_LINK_CMD(inq)       ((inq)->flags & 0x08)
1130 #define ASC_INQ_SYNC(inq)           ((inq)->flags & 0x10)
1131 #define ASC_INQ_WIDE16(inq)         ((inq)->flags & 0x20)
1132 #define ASC_INQ_WIDE32(inq)         ((inq)->flags & 0x40)
1133 #define ASC_INQ_REL_ADDR(inq)       ((inq)->flags & 0x80)
1134 #define ASC_INQ_INFO_UNIT(inq)      ((inq)->info & 0x01)
1135 #define ASC_INQ_QUICK_ARB(inq)      ((inq)->info & 0x02)
1136 #define ASC_INQ_CLOCKING(inq)       (((inq)->info & 0x0c) >> 2)
1137
1138 typedef struct {
1139     uchar               periph;
1140     uchar               devtype;
1141     uchar               ver;
1142     uchar               byte3;
1143     uchar               add_len;
1144     uchar               res1;
1145     uchar               res2;
1146     uchar               flags;
1147     uchar               vendor_id[8];
1148     uchar               product_id[16];
1149     uchar               product_rev_level[4];
1150 } ASC_SCSI_INQUIRY;
1151
1152 #define ASC_SG_LIST_PER_Q   7
1153 #define QS_FREE        0x00
1154 #define QS_READY       0x01
1155 #define QS_DISC1       0x02
1156 #define QS_DISC2       0x04
1157 #define QS_BUSY        0x08
1158 #define QS_ABORTED     0x40
1159 #define QS_DONE        0x80
1160 #define QC_NO_CALLBACK   0x01
1161 #define QC_SG_SWAP_QUEUE 0x02
1162 #define QC_SG_HEAD       0x04
1163 #define QC_DATA_IN       0x08
1164 #define QC_DATA_OUT      0x10
1165 #define QC_URGENT        0x20
1166 #define QC_MSG_OUT       0x40
1167 #define QC_REQ_SENSE     0x80
1168 #define QCSG_SG_XFER_LIST  0x02
1169 #define QCSG_SG_XFER_MORE  0x04
1170 #define QCSG_SG_XFER_END   0x08
1171 #define QD_IN_PROGRESS       0x00
1172 #define QD_NO_ERROR          0x01
1173 #define QD_ABORTED_BY_HOST   0x02
1174 #define QD_WITH_ERROR        0x04
1175 #define QD_INVALID_REQUEST   0x80
1176 #define QD_INVALID_HOST_NUM  0x81
1177 #define QD_INVALID_DEVICE    0x82
1178 #define QD_ERR_INTERNAL      0xFF
1179 #define QHSTA_NO_ERROR               0x00
1180 #define QHSTA_M_SEL_TIMEOUT          0x11
1181 #define QHSTA_M_DATA_OVER_RUN        0x12
1182 #define QHSTA_M_DATA_UNDER_RUN       0x12
1183 #define QHSTA_M_UNEXPECTED_BUS_FREE  0x13
1184 #define QHSTA_M_BAD_BUS_PHASE_SEQ    0x14
1185 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1186 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET  0x22
1187 #define QHSTA_D_HOST_ABORT_FAILED       0x23
1188 #define QHSTA_D_EXE_SCSI_Q_FAILED       0x24
1189 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1190 #define QHSTA_D_ASPI_NO_BUF_POOL        0x26
1191 #define QHSTA_M_WTM_TIMEOUT         0x41
1192 #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
1193 #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
1194 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1195 #define QHSTA_M_TARGET_STATUS_BUSY  0x45
1196 #define QHSTA_M_BAD_TAG_CODE        0x46
1197 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY  0x47
1198 #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1199 #define QHSTA_D_LRAM_CMP_ERROR        0x81
1200 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1201 #define ASC_FLAG_SCSIQ_REQ        0x01
1202 #define ASC_FLAG_BIOS_SCSIQ_REQ   0x02
1203 #define ASC_FLAG_BIOS_ASYNC_IO    0x04
1204 #define ASC_FLAG_SRB_LINEAR_ADDR  0x08
1205 #define ASC_FLAG_WIN16            0x10
1206 #define ASC_FLAG_WIN32            0x20
1207 #define ASC_FLAG_ISA_OVER_16MB    0x40
1208 #define ASC_FLAG_DOS_VM_CALLBACK  0x80
1209 #define ASC_TAG_FLAG_EXTRA_BYTES               0x10
1210 #define ASC_TAG_FLAG_DISABLE_DISCONNECT        0x04
1211 #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX  0x08
1212 #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1213 #define ASC_SCSIQ_CPY_BEG              4
1214 #define ASC_SCSIQ_SGHD_CPY_BEG         2
1215 #define ASC_SCSIQ_B_FWD                0
1216 #define ASC_SCSIQ_B_BWD                1
1217 #define ASC_SCSIQ_B_STATUS             2
1218 #define ASC_SCSIQ_B_QNO                3
1219 #define ASC_SCSIQ_B_CNTL               4
1220 #define ASC_SCSIQ_B_SG_QUEUE_CNT       5
1221 #define ASC_SCSIQ_D_DATA_ADDR          8
1222 #define ASC_SCSIQ_D_DATA_CNT          12
1223 #define ASC_SCSIQ_B_SENSE_LEN         20
1224 #define ASC_SCSIQ_DONE_INFO_BEG       22
1225 #define ASC_SCSIQ_D_SRBPTR            22
1226 #define ASC_SCSIQ_B_TARGET_IX         26
1227 #define ASC_SCSIQ_B_CDB_LEN           28
1228 #define ASC_SCSIQ_B_TAG_CODE          29
1229 #define ASC_SCSIQ_W_VM_ID             30
1230 #define ASC_SCSIQ_DONE_STATUS         32
1231 #define ASC_SCSIQ_HOST_STATUS         33
1232 #define ASC_SCSIQ_SCSI_STATUS         34
1233 #define ASC_SCSIQ_CDB_BEG             36
1234 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1235 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT  60
1236 #define ASC_SCSIQ_B_FIRST_SG_WK_QP    48
1237 #define ASC_SCSIQ_B_SG_WK_QP          49
1238 #define ASC_SCSIQ_B_SG_WK_IX          50
1239 #define ASC_SCSIQ_W_ALT_DC1           52
1240 #define ASC_SCSIQ_B_LIST_CNT          6
1241 #define ASC_SCSIQ_B_CUR_LIST_CNT      7
1242 #define ASC_SGQ_B_SG_CNTL             4
1243 #define ASC_SGQ_B_SG_HEAD_QP          5
1244 #define ASC_SGQ_B_SG_LIST_CNT         6
1245 #define ASC_SGQ_B_SG_CUR_LIST_CNT     7
1246 #define ASC_SGQ_LIST_BEG              8
1247 #define ASC_DEF_SCSI1_QNG    4
1248 #define ASC_MAX_SCSI1_QNG    4
1249 #define ASC_DEF_SCSI2_QNG    16
1250 #define ASC_MAX_SCSI2_QNG    32
1251 #define ASC_TAG_CODE_MASK    0x23
1252 #define ASC_STOP_REQ_RISC_STOP      0x01
1253 #define ASC_STOP_ACK_RISC_STOP      0x03
1254 #define ASC_STOP_CLEAN_UP_BUSY_Q    0x10
1255 #define ASC_STOP_CLEAN_UP_DISC_Q    0x20
1256 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1257 #define ASC_TIDLUN_TO_IX(tid, lun)  (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1258 #define ASC_TID_TO_TARGET_ID(tid)   (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1259 #define ASC_TIX_TO_TARGET_ID(tix)   (0x01 << ((tix) & ASC_MAX_TID))
1260 #define ASC_TIX_TO_TID(tix)         ((tix) & ASC_MAX_TID)
1261 #define ASC_TID_TO_TIX(tid)         ((tid) & ASC_MAX_TID)
1262 #define ASC_TIX_TO_LUN(tix)         (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1263 #define ASC_QNO_TO_QADDR(q_no)      ((ASC_QADR_BEG)+((int)(q_no) << 6))
1264
1265 typedef struct asc_scsiq_1 {
1266     uchar               status;
1267     uchar               q_no;
1268     uchar               cntl;
1269     uchar               sg_queue_cnt;
1270     uchar               target_id;
1271     uchar               target_lun;
1272     ASC_PADDR           data_addr;
1273     ASC_DCNT            data_cnt;
1274     ASC_PADDR           sense_addr;
1275     uchar               sense_len;
1276     uchar               extra_bytes;
1277 } ASC_SCSIQ_1;
1278
1279 typedef struct asc_scsiq_2 {
1280     ASC_VADDR           srb_ptr;
1281     uchar               target_ix;
1282     uchar               flag;
1283     uchar               cdb_len;
1284     uchar               tag_code;
1285     ushort              vm_id;
1286 } ASC_SCSIQ_2;
1287
1288 typedef struct asc_scsiq_3 {
1289     uchar               done_stat;
1290     uchar               host_stat;
1291     uchar               scsi_stat;
1292     uchar               scsi_msg;
1293 } ASC_SCSIQ_3;
1294
1295 typedef struct asc_scsiq_4 {
1296     uchar               cdb[ASC_MAX_CDB_LEN];
1297     uchar               y_first_sg_list_qp;
1298     uchar               y_working_sg_qp;
1299     uchar               y_working_sg_ix;
1300     uchar               y_res;
1301     ushort              x_req_count;
1302     ushort              x_reconnect_rtn;
1303     ASC_PADDR           x_saved_data_addr;
1304     ASC_DCNT            x_saved_data_cnt;
1305 } ASC_SCSIQ_4;
1306
1307 typedef struct asc_q_done_info {
1308     ASC_SCSIQ_2         d2;
1309     ASC_SCSIQ_3         d3;
1310     uchar               q_status;
1311     uchar               q_no;
1312     uchar               cntl;
1313     uchar               sense_len;
1314     uchar               extra_bytes;
1315     uchar               res;
1316     ASC_DCNT            remain_bytes;
1317 } ASC_QDONE_INFO;
1318
1319 typedef struct asc_sg_list {
1320     ASC_PADDR           addr;
1321     ASC_DCNT            bytes;
1322 } ASC_SG_LIST;
1323
1324 typedef struct asc_sg_head {
1325     ushort              entry_cnt;
1326     ushort              queue_cnt;
1327     ushort              entry_to_copy;
1328     ushort              res;
1329     ASC_SG_LIST         sg_list[ASC_MAX_SG_LIST];
1330 } ASC_SG_HEAD;
1331
1332 #define ASC_MIN_SG_LIST   2
1333
1334 typedef struct asc_min_sg_head {
1335     ushort              entry_cnt;
1336     ushort              queue_cnt;
1337     ushort              entry_to_copy;
1338     ushort              res;
1339     ASC_SG_LIST         sg_list[ASC_MIN_SG_LIST];
1340 } ASC_MIN_SG_HEAD;
1341
1342 #define QCX_SORT        (0x0001)
1343 #define QCX_COALEASE    (0x0002)
1344
1345 typedef struct asc_scsi_q {
1346     ASC_SCSIQ_1         q1;
1347     ASC_SCSIQ_2         q2;
1348     uchar               *cdbptr;
1349     ASC_SG_HEAD         *sg_head;
1350     ushort              remain_sg_entry_cnt;
1351     ushort              next_sg_index;
1352 } ASC_SCSI_Q;
1353
1354 typedef struct asc_scsi_req_q {
1355     ASC_SCSIQ_1         r1;
1356     ASC_SCSIQ_2         r2;
1357     uchar               *cdbptr;
1358     ASC_SG_HEAD         *sg_head;
1359     uchar               *sense_ptr;
1360     ASC_SCSIQ_3         r3;
1361     uchar               cdb[ASC_MAX_CDB_LEN];
1362     uchar               sense[ASC_MIN_SENSE_LEN];
1363 } ASC_SCSI_REQ_Q;
1364
1365 typedef struct asc_scsi_bios_req_q {
1366     ASC_SCSIQ_1         r1;
1367     ASC_SCSIQ_2         r2;
1368     uchar               *cdbptr;
1369     ASC_SG_HEAD         *sg_head;
1370     uchar               *sense_ptr;
1371     ASC_SCSIQ_3         r3;
1372     uchar               cdb[ASC_MAX_CDB_LEN];
1373     uchar               sense[ASC_MIN_SENSE_LEN];
1374 } ASC_SCSI_BIOS_REQ_Q;
1375
1376 typedef struct asc_risc_q {
1377     uchar               fwd;
1378     uchar               bwd;
1379     ASC_SCSIQ_1         i1;
1380     ASC_SCSIQ_2         i2;
1381     ASC_SCSIQ_3         i3;
1382     ASC_SCSIQ_4         i4;
1383 } ASC_RISC_Q;
1384
1385 typedef struct asc_sg_list_q {
1386     uchar               seq_no;
1387     uchar               q_no;
1388     uchar               cntl;
1389     uchar               sg_head_qp;
1390     uchar               sg_list_cnt;
1391     uchar               sg_cur_list_cnt;
1392 } ASC_SG_LIST_Q;
1393
1394 typedef struct asc_risc_sg_list_q {
1395     uchar               fwd;
1396     uchar               bwd;
1397     ASC_SG_LIST_Q       sg;
1398     ASC_SG_LIST         sg_list[7];
1399 } ASC_RISC_SG_LIST_Q;
1400
1401 #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP  0x1000000UL
1402 #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP  1024
1403 #define ASCQ_ERR_NO_ERROR             0
1404 #define ASCQ_ERR_IO_NOT_FOUND         1
1405 #define ASCQ_ERR_LOCAL_MEM            2
1406 #define ASCQ_ERR_CHKSUM               3
1407 #define ASCQ_ERR_START_CHIP           4
1408 #define ASCQ_ERR_INT_TARGET_ID        5
1409 #define ASCQ_ERR_INT_LOCAL_MEM        6
1410 #define ASCQ_ERR_HALT_RISC            7
1411 #define ASCQ_ERR_GET_ASPI_ENTRY       8
1412 #define ASCQ_ERR_CLOSE_ASPI           9
1413 #define ASCQ_ERR_HOST_INQUIRY         0x0A
1414 #define ASCQ_ERR_SAVED_SRB_BAD        0x0B
1415 #define ASCQ_ERR_QCNTL_SG_LIST        0x0C
1416 #define ASCQ_ERR_Q_STATUS             0x0D
1417 #define ASCQ_ERR_WR_SCSIQ             0x0E
1418 #define ASCQ_ERR_PC_ADDR              0x0F
1419 #define ASCQ_ERR_SYN_OFFSET           0x10
1420 #define ASCQ_ERR_SYN_XFER_TIME        0x11
1421 #define ASCQ_ERR_LOCK_DMA             0x12
1422 #define ASCQ_ERR_UNLOCK_DMA           0x13
1423 #define ASCQ_ERR_VDS_CHK_INSTALL      0x14
1424 #define ASCQ_ERR_MICRO_CODE_HALT      0x15
1425 #define ASCQ_ERR_SET_LRAM_ADDR        0x16
1426 #define ASCQ_ERR_CUR_QNG              0x17
1427 #define ASCQ_ERR_SG_Q_LINKS           0x18
1428 #define ASCQ_ERR_SCSIQ_PTR            0x19
1429 #define ASCQ_ERR_ISR_RE_ENTRY         0x1A
1430 #define ASCQ_ERR_CRITICAL_RE_ENTRY    0x1B
1431 #define ASCQ_ERR_ISR_ON_CRITICAL      0x1C
1432 #define ASCQ_ERR_SG_LIST_ODD_ADDRESS  0x1D
1433 #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1434 #define ASCQ_ERR_SCSIQ_NULL_PTR       0x1F
1435 #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR   0x20
1436 #define ASCQ_ERR_GET_NUM_OF_FREE_Q    0x21
1437 #define ASCQ_ERR_SEND_SCSI_Q          0x22
1438 #define ASCQ_ERR_HOST_REQ_RISC_HALT   0x23
1439 #define ASCQ_ERR_RESET_SDTR           0x24
1440
1441 /*
1442  * Warning code values are set in ASC_DVC_VAR  'warn_code'.
1443  */
1444 #define ASC_WARN_NO_ERROR             0x0000
1445 #define ASC_WARN_IO_PORT_ROTATE       0x0001
1446 #define ASC_WARN_EEPROM_CHKSUM        0x0002
1447 #define ASC_WARN_IRQ_MODIFIED         0x0004
1448 #define ASC_WARN_AUTO_CONFIG          0x0008
1449 #define ASC_WARN_CMD_QNG_CONFLICT     0x0010
1450 #define ASC_WARN_EEPROM_RECOVER       0x0020
1451 #define ASC_WARN_CFG_MSW_RECOVER      0x0040
1452 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1453
1454 /*
1455  * Error code values are set in ASC_DVC_VAR  'err_code'.
1456  */
1457 #define ASC_IERR_WRITE_EEPROM         0x0001
1458 #define ASC_IERR_MCODE_CHKSUM         0x0002
1459 #define ASC_IERR_SET_PC_ADDR          0x0004
1460 #define ASC_IERR_START_STOP_CHIP      0x0008
1461 #define ASC_IERR_IRQ_NO               0x0010
1462 #define ASC_IERR_SET_IRQ_NO           0x0020
1463 #define ASC_IERR_CHIP_VERSION         0x0040
1464 #define ASC_IERR_SET_SCSI_ID          0x0080
1465 #define ASC_IERR_GET_PHY_ADDR         0x0100
1466 #define ASC_IERR_BAD_SIGNATURE        0x0200
1467 #define ASC_IERR_NO_BUS_TYPE          0x0400
1468 #define ASC_IERR_SCAM                 0x0800
1469 #define ASC_IERR_SET_SDTR             0x1000
1470 #define ASC_IERR_RW_LRAM              0x8000
1471
1472 #define ASC_DEF_IRQ_NO  10
1473 #define ASC_MAX_IRQ_NO  15
1474 #define ASC_MIN_IRQ_NO  10
1475 #define ASC_MIN_REMAIN_Q        (0x02)
1476 #define ASC_DEF_MAX_TOTAL_QNG   (0xF0)
1477 #define ASC_MIN_TAG_Q_PER_DVC   (0x04)
1478 #define ASC_DEF_TAG_Q_PER_DVC   (0x04)
1479 #define ASC_MIN_FREE_Q        ASC_MIN_REMAIN_Q
1480 #define ASC_MIN_TOTAL_QNG     ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1481 #define ASC_MAX_TOTAL_QNG 240
1482 #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1483 #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG   8
1484 #define ASC_MAX_PCI_INRAM_TOTAL_QNG  20
1485 #define ASC_MAX_INRAM_TAG_QNG   16
1486 #define ASC_IOADR_TABLE_MAX_IX  11
1487 #define ASC_IOADR_GAP   0x10
1488 #define ASC_SEARCH_IOP_GAP 0x10
1489 #define ASC_MIN_IOP_ADDR   (PortAddr)0x0100
1490 #define ASC_MAX_IOP_ADDR   (PortAddr)0x3F0
1491 #define ASC_IOADR_1     (PortAddr)0x0110
1492 #define ASC_IOADR_2     (PortAddr)0x0130
1493 #define ASC_IOADR_3     (PortAddr)0x0150
1494 #define ASC_IOADR_4     (PortAddr)0x0190
1495 #define ASC_IOADR_5     (PortAddr)0x0210
1496 #define ASC_IOADR_6     (PortAddr)0x0230
1497 #define ASC_IOADR_7     (PortAddr)0x0250
1498 #define ASC_IOADR_8     (PortAddr)0x0330
1499 #define ASC_IOADR_DEF   ASC_IOADR_8
1500 #define ASC_LIB_SCSIQ_WK_SP        256
1501 #define ASC_MAX_SYN_XFER_NO        16
1502 #define ASC_SYN_MAX_OFFSET         0x0F
1503 #define ASC_DEF_SDTR_OFFSET        0x0F
1504 #define ASC_DEF_SDTR_INDEX         0x00
1505 #define ASC_SDTR_ULTRA_PCI_10MB_INDEX  0x02
1506 #define SYN_XFER_NS_0  25
1507 #define SYN_XFER_NS_1  30
1508 #define SYN_XFER_NS_2  35
1509 #define SYN_XFER_NS_3  40
1510 #define SYN_XFER_NS_4  50
1511 #define SYN_XFER_NS_5  60
1512 #define SYN_XFER_NS_6  70
1513 #define SYN_XFER_NS_7  85
1514 #define SYN_ULTRA_XFER_NS_0    12
1515 #define SYN_ULTRA_XFER_NS_1    19
1516 #define SYN_ULTRA_XFER_NS_2    25
1517 #define SYN_ULTRA_XFER_NS_3    32
1518 #define SYN_ULTRA_XFER_NS_4    38
1519 #define SYN_ULTRA_XFER_NS_5    44
1520 #define SYN_ULTRA_XFER_NS_6    50
1521 #define SYN_ULTRA_XFER_NS_7    57
1522 #define SYN_ULTRA_XFER_NS_8    63
1523 #define SYN_ULTRA_XFER_NS_9    69
1524 #define SYN_ULTRA_XFER_NS_10   75
1525 #define SYN_ULTRA_XFER_NS_11   82
1526 #define SYN_ULTRA_XFER_NS_12   88
1527 #define SYN_ULTRA_XFER_NS_13   94
1528 #define SYN_ULTRA_XFER_NS_14  100
1529 #define SYN_ULTRA_XFER_NS_15  107
1530
1531 typedef struct ext_msg {
1532     uchar               msg_type;
1533     uchar               msg_len;
1534     uchar               msg_req;
1535     union {
1536         struct {
1537             uchar               sdtr_xfer_period;
1538             uchar               sdtr_req_ack_offset;
1539         } sdtr;
1540         struct {
1541             uchar               wdtr_width;
1542         } wdtr;
1543         struct {
1544             uchar               mdp_b3;
1545             uchar               mdp_b2;
1546             uchar               mdp_b1;
1547             uchar               mdp_b0;
1548         } mdp;
1549     } u_ext_msg;
1550     uchar               res;
1551 } EXT_MSG;
1552
1553 #define xfer_period     u_ext_msg.sdtr.sdtr_xfer_period
1554 #define req_ack_offset  u_ext_msg.sdtr.sdtr_req_ack_offset
1555 #define wdtr_width      u_ext_msg.wdtr.wdtr_width
1556 #define mdp_b3          u_ext_msg.mdp_b3
1557 #define mdp_b2          u_ext_msg.mdp_b2
1558 #define mdp_b1          u_ext_msg.mdp_b1
1559 #define mdp_b0          u_ext_msg.mdp_b0
1560
1561 typedef struct asc_dvc_cfg {
1562     ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1563     ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1564     ASC_SCSI_BIT_ID_TYPE disc_enable;
1565     ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1566     uchar               chip_scsi_id;
1567     uchar               isa_dma_speed;
1568     uchar               isa_dma_channel;
1569     uchar               chip_version;
1570     ushort              lib_serial_no;
1571     ushort              lib_version;
1572     ushort              mcode_date;
1573     ushort              mcode_version;
1574     uchar               max_tag_qng[ASC_MAX_TID + 1];
1575     uchar               *overrun_buf;
1576     uchar               sdtr_period_offset[ASC_MAX_TID + 1];
1577     ushort              pci_slot_info;
1578     uchar               adapter_info[6];
1579     struct pci_dev      *pci_dev;
1580 } ASC_DVC_CFG;
1581
1582 #define ASC_DEF_DVC_CNTL       0xFFFF
1583 #define ASC_DEF_CHIP_SCSI_ID   7
1584 #define ASC_DEF_ISA_DMA_SPEED  4
1585 #define ASC_INIT_STATE_NULL          0x0000
1586 #define ASC_INIT_STATE_BEG_GET_CFG   0x0001
1587 #define ASC_INIT_STATE_END_GET_CFG   0x0002
1588 #define ASC_INIT_STATE_BEG_SET_CFG   0x0004
1589 #define ASC_INIT_STATE_END_SET_CFG   0x0008
1590 #define ASC_INIT_STATE_BEG_LOAD_MC   0x0010
1591 #define ASC_INIT_STATE_END_LOAD_MC   0x0020
1592 #define ASC_INIT_STATE_BEG_INQUIRY   0x0040
1593 #define ASC_INIT_STATE_END_INQUIRY   0x0080
1594 #define ASC_INIT_RESET_SCSI_DONE     0x0100
1595 #define ASC_INIT_STATE_WITHOUT_EEP   0x8000
1596 #define ASC_PCI_DEVICE_ID_REV_A      0x1100
1597 #define ASC_PCI_DEVICE_ID_REV_B      0x1200
1598 #define ASC_BUG_FIX_IF_NOT_DWB       0x0001
1599 #define ASC_BUG_FIX_ASYN_USE_SYN     0x0002
1600 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1601 #define ASC_MIN_TAGGED_CMD  7
1602 #define ASC_MAX_SCSI_RESET_WAIT      30
1603
1604 struct asc_dvc_var;     /* Forward Declaration. */
1605
1606 typedef void (* ASC_ISR_CALLBACK)(struct asc_dvc_var *, ASC_QDONE_INFO *);
1607 typedef int (* ASC_EXE_CALLBACK)(struct asc_dvc_var *, ASC_SCSI_Q *);
1608
1609 typedef struct asc_dvc_var {
1610     PortAddr            iop_base;
1611     ushort              err_code;
1612     ushort              dvc_cntl;
1613     ushort              bug_fix_cntl;
1614     ushort              bus_type;
1615     ASC_ISR_CALLBACK    isr_callback;
1616     ASC_EXE_CALLBACK    exe_callback;
1617     ASC_SCSI_BIT_ID_TYPE init_sdtr;
1618     ASC_SCSI_BIT_ID_TYPE sdtr_done;
1619     ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1620     ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1621     ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1622     ASC_SCSI_BIT_ID_TYPE start_motor;
1623     uchar               scsi_reset_wait;
1624     uchar               chip_no;
1625     char                is_in_int;
1626     uchar               max_total_qng;
1627     uchar               cur_total_qng;
1628     uchar               in_critical_cnt;
1629     uchar               irq_no;
1630     uchar               last_q_shortage;
1631     ushort              init_state;
1632     uchar               cur_dvc_qng[ASC_MAX_TID + 1];
1633     uchar               max_dvc_qng[ASC_MAX_TID + 1];
1634     ASC_SCSI_Q  *scsiq_busy_head[ASC_MAX_TID + 1];
1635     ASC_SCSI_Q  *scsiq_busy_tail[ASC_MAX_TID + 1];
1636     uchar               sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1637     ASC_DVC_CFG *cfg;
1638     ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1639     char                redo_scam;
1640     ushort              res2;
1641     uchar               dos_int13_table[ASC_MAX_TID + 1];
1642     ASC_DCNT            max_dma_count;
1643     ASC_SCSI_BIT_ID_TYPE no_scam;
1644     ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1645     uchar               max_sdtr_index;
1646     uchar               host_init_sdtr_index;
1647     struct asc_board    *drv_ptr;
1648     ASC_DCNT            uc_break;
1649 } ASC_DVC_VAR;
1650
1651 typedef struct asc_dvc_inq_info {
1652     uchar               type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1653 } ASC_DVC_INQ_INFO;
1654
1655 typedef struct asc_cap_info {
1656     ASC_DCNT            lba;
1657     ASC_DCNT            blk_size;
1658 } ASC_CAP_INFO;
1659
1660 typedef struct asc_cap_info_array {
1661     ASC_CAP_INFO        cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1662 } ASC_CAP_INFO_ARRAY;
1663
1664 #define ASC_MCNTL_NO_SEL_TIMEOUT  (ushort)0x0001
1665 #define ASC_MCNTL_NULL_TARGET     (ushort)0x0002
1666 #define ASC_CNTL_INITIATOR         (ushort)0x0001
1667 #define ASC_CNTL_BIOS_GT_1GB       (ushort)0x0002
1668 #define ASC_CNTL_BIOS_GT_2_DISK    (ushort)0x0004
1669 #define ASC_CNTL_BIOS_REMOVABLE    (ushort)0x0008
1670 #define ASC_CNTL_NO_SCAM           (ushort)0x0010
1671 #define ASC_CNTL_INT_MULTI_Q       (ushort)0x0080
1672 #define ASC_CNTL_NO_LUN_SUPPORT    (ushort)0x0040
1673 #define ASC_CNTL_NO_VERIFY_COPY    (ushort)0x0100
1674 #define ASC_CNTL_RESET_SCSI        (ushort)0x0200
1675 #define ASC_CNTL_INIT_INQUIRY      (ushort)0x0400
1676 #define ASC_CNTL_INIT_VERBOSE      (ushort)0x0800
1677 #define ASC_CNTL_SCSI_PARITY       (ushort)0x1000
1678 #define ASC_CNTL_BURST_MODE        (ushort)0x2000
1679 #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1680 #define ASC_EEP_DVC_CFG_BEG_VL    2
1681 #define ASC_EEP_MAX_DVC_ADDR_VL   15
1682 #define ASC_EEP_DVC_CFG_BEG      32
1683 #define ASC_EEP_MAX_DVC_ADDR     45
1684 #define ASC_EEP_DEFINED_WORDS    10
1685 #define ASC_EEP_MAX_ADDR         63
1686 #define ASC_EEP_RES_WORDS         0
1687 #define ASC_EEP_MAX_RETRY        20
1688 #define ASC_MAX_INIT_BUSY_RETRY   8
1689 #define ASC_EEP_ISA_PNP_WSIZE    16
1690
1691 /*
1692  * These macros keep the chip SCSI id and ISA DMA speed
1693  * bitfields in board order. C bitfields aren't portable
1694  * between big and little-endian platforms so they are
1695  * not used.
1696  */
1697
1698 #define ASC_EEP_GET_CHIP_ID(cfg)    ((cfg)->id_speed & 0x0f)
1699 #define ASC_EEP_GET_DMA_SPD(cfg)    (((cfg)->id_speed & 0xf0) >> 4)
1700 #define ASC_EEP_SET_CHIP_ID(cfg, sid) \
1701    ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
1702 #define ASC_EEP_SET_DMA_SPD(cfg, spd) \
1703    ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
1704
1705 typedef struct asceep_config {
1706     ushort              cfg_lsw;
1707     ushort              cfg_msw;
1708     uchar               init_sdtr;
1709     uchar               disc_enable;
1710     uchar               use_cmd_qng;
1711     uchar               start_motor;
1712     uchar               max_total_qng;
1713     uchar               max_tag_qng;
1714     uchar               bios_scan;
1715     uchar               power_up_wait;
1716     uchar               no_scam;
1717     uchar               id_speed; /* low order 4 bits is chip scsi id */
1718                                   /* high order 4 bits is isa dma speed */
1719     uchar               dos_int13_table[ASC_MAX_TID + 1];
1720     uchar               adapter_info[6];
1721     ushort              cntl;
1722     ushort              chksum;
1723 } ASCEEP_CONFIG;
1724
1725 #define ASC_PCI_CFG_LSW_SCSI_PARITY  0x0800
1726 #define ASC_PCI_CFG_LSW_BURST_MODE   0x0080
1727 #define ASC_PCI_CFG_LSW_INTR_ABLE    0x0020
1728
1729 #define ASC_EEP_CMD_READ          0x80
1730 #define ASC_EEP_CMD_WRITE         0x40
1731 #define ASC_EEP_CMD_WRITE_ABLE    0x30
1732 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
1733 #define ASC_OVERRUN_BSIZE  0x00000048UL
1734 #define ASC_CTRL_BREAK_ONCE        0x0001
1735 #define ASC_CTRL_BREAK_STAY_IDLE   0x0002
1736 #define ASCV_MSGOUT_BEG         0x0000
1737 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1738 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1739 #define ASCV_BREAK_SAVED_CODE   (ushort)0x0006
1740 #define ASCV_MSGIN_BEG          (ASCV_MSGOUT_BEG+8)
1741 #define ASCV_MSGIN_SDTR_PERIOD  (ASCV_MSGIN_BEG+3)
1742 #define ASCV_MSGIN_SDTR_OFFSET  (ASCV_MSGIN_BEG+4)
1743 #define ASCV_SDTR_DATA_BEG      (ASCV_MSGIN_BEG+8)
1744 #define ASCV_SDTR_DONE_BEG      (ASCV_SDTR_DATA_BEG+8)
1745 #define ASCV_MAX_DVC_QNG_BEG    (ushort)0x0020
1746 #define ASCV_BREAK_ADDR           (ushort)0x0028
1747 #define ASCV_BREAK_NOTIFY_COUNT   (ushort)0x002A
1748 #define ASCV_BREAK_CONTROL        (ushort)0x002C
1749 #define ASCV_BREAK_HIT_COUNT      (ushort)0x002E
1750
1751 #define ASCV_ASCDVC_ERR_CODE_W  (ushort)0x0030
1752 #define ASCV_MCODE_CHKSUM_W   (ushort)0x0032
1753 #define ASCV_MCODE_SIZE_W     (ushort)0x0034
1754 #define ASCV_STOP_CODE_B      (ushort)0x0036
1755 #define ASCV_DVC_ERR_CODE_B   (ushort)0x0037
1756 #define ASCV_OVERRUN_PADDR_D  (ushort)0x0038
1757 #define ASCV_OVERRUN_BSIZE_D  (ushort)0x003C
1758 #define ASCV_HALTCODE_W       (ushort)0x0040
1759 #define ASCV_CHKSUM_W         (ushort)0x0042
1760 #define ASCV_MC_DATE_W        (ushort)0x0044
1761 #define ASCV_MC_VER_W         (ushort)0x0046
1762 #define ASCV_NEXTRDY_B        (ushort)0x0048
1763 #define ASCV_DONENEXT_B       (ushort)0x0049
1764 #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1765 #define ASCV_SCSIBUSY_B       (ushort)0x004B
1766 #define ASCV_Q_DONE_IN_PROGRESS_B  (ushort)0x004C
1767 #define ASCV_CURCDB_B         (ushort)0x004D
1768 #define ASCV_RCLUN_B          (ushort)0x004E
1769 #define ASCV_BUSY_QHEAD_B     (ushort)0x004F
1770 #define ASCV_DISC1_QHEAD_B    (ushort)0x0050
1771 #define ASCV_DISC_ENABLE_B    (ushort)0x0052
1772 #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1773 #define ASCV_HOSTSCSI_ID_B    (ushort)0x0055
1774 #define ASCV_MCODE_CNTL_B     (ushort)0x0056
1775 #define ASCV_NULL_TARGET_B    (ushort)0x0057
1776 #define ASCV_FREE_Q_HEAD_W    (ushort)0x0058
1777 #define ASCV_DONE_Q_TAIL_W    (ushort)0x005A
1778 #define ASCV_FREE_Q_HEAD_B    (ushort)(ASCV_FREE_Q_HEAD_W+1)
1779 #define ASCV_DONE_Q_TAIL_B    (ushort)(ASCV_DONE_Q_TAIL_W+1)
1780 #define ASCV_HOST_FLAG_B      (ushort)0x005D
1781 #define ASCV_TOTAL_READY_Q_B  (ushort)0x0064
1782 #define ASCV_VER_SERIAL_B     (ushort)0x0065
1783 #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1784 #define ASCV_WTM_FLAG_B       (ushort)0x0068
1785 #define ASCV_RISC_FLAG_B      (ushort)0x006A
1786 #define ASCV_REQ_SG_LIST_QP   (ushort)0x006B
1787 #define ASC_HOST_FLAG_IN_ISR        0x01
1788 #define ASC_HOST_FLAG_ACK_INT       0x02
1789 #define ASC_RISC_FLAG_GEN_INT      0x01
1790 #define ASC_RISC_FLAG_REQ_SG_LIST  0x02
1791 #define IOP_CTRL         (0x0F)
1792 #define IOP_STATUS       (0x0E)
1793 #define IOP_INT_ACK      IOP_STATUS
1794 #define IOP_REG_IFC      (0x0D)
1795 #define IOP_SYN_OFFSET    (0x0B)
1796 #define IOP_EXTRA_CONTROL (0x0D)
1797 #define IOP_REG_PC        (0x0C)
1798 #define IOP_RAM_ADDR      (0x0A)
1799 #define IOP_RAM_DATA      (0x08)
1800 #define IOP_EEP_DATA      (0x06)
1801 #define IOP_EEP_CMD       (0x07)
1802 #define IOP_VERSION       (0x03)
1803 #define IOP_CONFIG_HIGH   (0x04)
1804 #define IOP_CONFIG_LOW    (0x02)
1805 #define IOP_SIG_BYTE      (0x01)
1806 #define IOP_SIG_WORD      (0x00)
1807 #define IOP_REG_DC1      (0x0E)
1808 #define IOP_REG_DC0      (0x0C)
1809 #define IOP_REG_SB       (0x0B)
1810 #define IOP_REG_DA1      (0x0A)
1811 #define IOP_REG_DA0      (0x08)
1812 #define IOP_REG_SC       (0x09)
1813 #define IOP_DMA_SPEED    (0x07)
1814 #define IOP_REG_FLAG     (0x07)
1815 #define IOP_FIFO_H       (0x06)
1816 #define IOP_FIFO_L       (0x04)
1817 #define IOP_REG_ID       (0x05)
1818 #define IOP_REG_QP       (0x03)
1819 #define IOP_REG_IH       (0x02)
1820 #define IOP_REG_IX       (0x01)
1821 #define IOP_REG_AX       (0x00)
1822 #define IFC_REG_LOCK      (0x00)
1823 #define IFC_REG_UNLOCK    (0x09)
1824 #define IFC_WR_EN_FILTER  (0x10)
1825 #define IFC_RD_NO_EEPROM  (0x10)
1826 #define IFC_SLEW_RATE     (0x20)
1827 #define IFC_ACT_NEG       (0x40)
1828 #define IFC_INP_FILTER    (0x80)
1829 #define IFC_INIT_DEFAULT  (IFC_ACT_NEG | IFC_REG_UNLOCK)
1830 #define SC_SEL   (uchar)(0x80)
1831 #define SC_BSY   (uchar)(0x40)
1832 #define SC_ACK   (uchar)(0x20)
1833 #define SC_REQ   (uchar)(0x10)
1834 #define SC_ATN   (uchar)(0x08)
1835 #define SC_IO    (uchar)(0x04)
1836 #define SC_CD    (uchar)(0x02)
1837 #define SC_MSG   (uchar)(0x01)
1838 #define SEC_SCSI_CTL         (uchar)(0x80)
1839 #define SEC_ACTIVE_NEGATE    (uchar)(0x40)
1840 #define SEC_SLEW_RATE        (uchar)(0x20)
1841 #define SEC_ENABLE_FILTER    (uchar)(0x10)
1842 #define ASC_HALT_EXTMSG_IN     (ushort)0x8000
1843 #define ASC_HALT_CHK_CONDITION (ushort)0x8100
1844 #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1845 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX  (ushort)0x8300
1846 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX   (ushort)0x8400
1847 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1848 #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1849 #define ASC_MAX_QNO        0xF8
1850 #define ASC_DATA_SEC_BEG   (ushort)0x0080
1851 #define ASC_DATA_SEC_END   (ushort)0x0080
1852 #define ASC_CODE_SEC_BEG   (ushort)0x0080
1853 #define ASC_CODE_SEC_END   (ushort)0x0080
1854 #define ASC_QADR_BEG       (0x4000)
1855 #define ASC_QADR_USED      (ushort)(ASC_MAX_QNO * 64)
1856 #define ASC_QADR_END       (ushort)0x7FFF
1857 #define ASC_QLAST_ADR      (ushort)0x7FC0
1858 #define ASC_QBLK_SIZE      0x40
1859 #define ASC_BIOS_DATA_QBEG 0xF8
1860 #define ASC_MIN_ACTIVE_QNO 0x01
1861 #define ASC_QLINK_END      0xFF
1862 #define ASC_EEPROM_WORDS   0x10
1863 #define ASC_MAX_MGS_LEN    0x10
1864 #define ASC_BIOS_ADDR_DEF  0xDC00
1865 #define ASC_BIOS_SIZE      0x3800
1866 #define ASC_BIOS_RAM_OFF   0x3800
1867 #define ASC_BIOS_RAM_SIZE  0x800
1868 #define ASC_BIOS_MIN_ADDR  0xC000
1869 #define ASC_BIOS_MAX_ADDR  0xEC00
1870 #define ASC_BIOS_BANK_SIZE 0x0400
1871 #define ASC_MCODE_START_ADDR  0x0080
1872 #define ASC_CFG0_HOST_INT_ON    0x0020
1873 #define ASC_CFG0_BIOS_ON        0x0040
1874 #define ASC_CFG0_VERA_BURST_ON  0x0080
1875 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
1876 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
1877 #define ASC_CFG1_LRAM_8BITS_ON  0x0800
1878 #define ASC_CFG_MSW_CLR_MASK    0x3080
1879 #define CSW_TEST1             (ASC_CS_TYPE)0x8000
1880 #define CSW_AUTO_CONFIG       (ASC_CS_TYPE)0x4000
1881 #define CSW_RESERVED1         (ASC_CS_TYPE)0x2000
1882 #define CSW_IRQ_WRITTEN       (ASC_CS_TYPE)0x1000
1883 #define CSW_33MHZ_SELECTED    (ASC_CS_TYPE)0x0800
1884 #define CSW_TEST2             (ASC_CS_TYPE)0x0400
1885 #define CSW_TEST3             (ASC_CS_TYPE)0x0200
1886 #define CSW_RESERVED2         (ASC_CS_TYPE)0x0100
1887 #define CSW_DMA_DONE          (ASC_CS_TYPE)0x0080
1888 #define CSW_FIFO_RDY          (ASC_CS_TYPE)0x0040
1889 #define CSW_EEP_READ_DONE     (ASC_CS_TYPE)0x0020
1890 #define CSW_HALTED            (ASC_CS_TYPE)0x0010
1891 #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1892 #define CSW_PARITY_ERR        (ASC_CS_TYPE)0x0004
1893 #define CSW_SCSI_RESET_LATCH  (ASC_CS_TYPE)0x0002
1894 #define CSW_INT_PENDING       (ASC_CS_TYPE)0x0001
1895 #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1896 #define CIW_INT_ACK      (ASC_CS_TYPE)0x0100
1897 #define CIW_TEST1        (ASC_CS_TYPE)0x0200
1898 #define CIW_TEST2        (ASC_CS_TYPE)0x0400
1899 #define CIW_SEL_33MHZ    (ASC_CS_TYPE)0x0800
1900 #define CIW_IRQ_ACT      (ASC_CS_TYPE)0x1000
1901 #define CC_CHIP_RESET   (uchar)0x80
1902 #define CC_SCSI_RESET   (uchar)0x40
1903 #define CC_HALT         (uchar)0x20
1904 #define CC_SINGLE_STEP  (uchar)0x10
1905 #define CC_DMA_ABLE     (uchar)0x08
1906 #define CC_TEST         (uchar)0x04
1907 #define CC_BANK_ONE     (uchar)0x02
1908 #define CC_DIAG         (uchar)0x01
1909 #define ASC_1000_ID0W      0x04C1
1910 #define ASC_1000_ID0W_FIX  0x00C1
1911 #define ASC_1000_ID1B      0x25
1912 #define ASC_EISA_BIG_IOP_GAP   (0x1C30-0x0C50)
1913 #define ASC_EISA_SMALL_IOP_GAP (0x0020)
1914 #define ASC_EISA_MIN_IOP_ADDR  (0x0C30)
1915 #define ASC_EISA_MAX_IOP_ADDR  (0xFC50)
1916 #define ASC_EISA_REV_IOP_MASK  (0x0C83)
1917 #define ASC_EISA_PID_IOP_MASK  (0x0C80)
1918 #define ASC_EISA_CFG_IOP_MASK  (0x0C86)
1919 #define ASC_GET_EISA_SLOT(iop)  (PortAddr)((iop) & 0xF000)
1920 #define ASC_EISA_ID_740    0x01745004UL
1921 #define ASC_EISA_ID_750    0x01755004UL
1922 #define INS_HALTINT        (ushort)0x6281
1923 #define INS_HALT           (ushort)0x6280
1924 #define INS_SINT           (ushort)0x6200
1925 #define INS_RFLAG_WTM      (ushort)0x7380
1926 #define ASC_MC_SAVE_CODE_WSIZE  0x500
1927 #define ASC_MC_SAVE_DATA_WSIZE  0x40
1928
1929 typedef struct asc_mc_saved {
1930     ushort              data[ASC_MC_SAVE_DATA_WSIZE];
1931     ushort              code[ASC_MC_SAVE_CODE_WSIZE];
1932 } ASC_MC_SAVED;
1933
1934 #define AscGetQDoneInProgress(port)         AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1935 #define AscPutQDoneInProgress(port, val)    AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1936 #define AscGetVarFreeQHead(port)            AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1937 #define AscGetVarDoneQTail(port)            AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1938 #define AscPutVarFreeQHead(port, val)       AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1939 #define AscPutVarDoneQTail(port, val)       AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1940 #define AscGetRiscVarFreeQHead(port)        AscReadLramByte((port), ASCV_NEXTRDY_B)
1941 #define AscGetRiscVarDoneQTail(port)        AscReadLramByte((port), ASCV_DONENEXT_B)
1942 #define AscPutRiscVarFreeQHead(port, val)   AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1943 #define AscPutRiscVarDoneQTail(port, val)   AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1944 #define AscPutMCodeSDTRDoneAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1945 #define AscGetMCodeSDTRDoneAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1946 #define AscPutMCodeInitSDTRAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1947 #define AscGetMCodeInitSDTRAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1948 #define AscSynIndexToPeriod(index)        (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1949 #define AscGetChipSignatureByte(port)     (uchar)inp((port)+IOP_SIG_BYTE)
1950 #define AscGetChipSignatureWord(port)     (ushort)inpw((port)+IOP_SIG_WORD)
1951 #define AscGetChipVerNo(port)             (uchar)inp((port)+IOP_VERSION)
1952 #define AscGetChipCfgLsw(port)            (ushort)inpw((port)+IOP_CONFIG_LOW)
1953 #define AscGetChipCfgMsw(port)            (ushort)inpw((port)+IOP_CONFIG_HIGH)
1954 #define AscSetChipCfgLsw(port, data)      outpw((port)+IOP_CONFIG_LOW, data)
1955 #define AscSetChipCfgMsw(port, data)      outpw((port)+IOP_CONFIG_HIGH, data)
1956 #define AscGetChipEEPCmd(port)            (uchar)inp((port)+IOP_EEP_CMD)
1957 #define AscSetChipEEPCmd(port, data)      outp((port)+IOP_EEP_CMD, data)
1958 #define AscGetChipEEPData(port)           (ushort)inpw((port)+IOP_EEP_DATA)
1959 #define AscSetChipEEPData(port, data)     outpw((port)+IOP_EEP_DATA, data)
1960 #define AscGetChipLramAddr(port)          (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1961 #define AscSetChipLramAddr(port, addr)    outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1962 #define AscGetChipLramData(port)          (ushort)inpw((port)+IOP_RAM_DATA)
1963 #define AscSetChipLramData(port, data)    outpw((port)+IOP_RAM_DATA, data)
1964 #define AscGetChipIFC(port)               (uchar)inp((port)+IOP_REG_IFC)
1965 #define AscSetChipIFC(port, data)          outp((port)+IOP_REG_IFC, data)
1966 #define AscGetChipStatus(port)            (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1967 #define AscSetChipStatus(port, cs_val)    outpw((port)+IOP_STATUS, cs_val)
1968 #define AscGetChipControl(port)           (uchar)inp((port)+IOP_CTRL)
1969 #define AscSetChipControl(port, cc_val)   outp((port)+IOP_CTRL, cc_val)
1970 #define AscGetChipSyn(port)               (uchar)inp((port)+IOP_SYN_OFFSET)
1971 #define AscSetChipSyn(port, data)         outp((port)+IOP_SYN_OFFSET, data)
1972 #define AscSetPCAddr(port, data)          outpw((port)+IOP_REG_PC, data)
1973 #define AscGetPCAddr(port)                (ushort)inpw((port)+IOP_REG_PC)
1974 #define AscIsIntPending(port)             (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1975 #define AscGetChipScsiID(port)            ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1976 #define AscGetExtraControl(port)          (uchar)inp((port)+IOP_EXTRA_CONTROL)
1977 #define AscSetExtraControl(port, data)    outp((port)+IOP_EXTRA_CONTROL, data)
1978 #define AscReadChipAX(port)               (ushort)inpw((port)+IOP_REG_AX)
1979 #define AscWriteChipAX(port, data)        outpw((port)+IOP_REG_AX, data)
1980 #define AscReadChipIX(port)               (uchar)inp((port)+IOP_REG_IX)
1981 #define AscWriteChipIX(port, data)        outp((port)+IOP_REG_IX, data)
1982 #define AscReadChipIH(port)               (ushort)inpw((port)+IOP_REG_IH)
1983 #define AscWriteChipIH(port, data)        outpw((port)+IOP_REG_IH, data)
1984 #define AscReadChipQP(port)               (uchar)inp((port)+IOP_REG_QP)
1985 #define AscWriteChipQP(port, data)        outp((port)+IOP_REG_QP, data)
1986 #define AscReadChipFIFO_L(port)           (ushort)inpw((port)+IOP_REG_FIFO_L)
1987 #define AscWriteChipFIFO_L(port, data)    outpw((port)+IOP_REG_FIFO_L, data)
1988 #define AscReadChipFIFO_H(port)           (ushort)inpw((port)+IOP_REG_FIFO_H)
1989 #define AscWriteChipFIFO_H(port, data)    outpw((port)+IOP_REG_FIFO_H, data)
1990 #define AscReadChipDmaSpeed(port)         (uchar)inp((port)+IOP_DMA_SPEED)
1991 #define AscWriteChipDmaSpeed(port, data)  outp((port)+IOP_DMA_SPEED, data)
1992 #define AscReadChipDA0(port)              (ushort)inpw((port)+IOP_REG_DA0)
1993 #define AscWriteChipDA0(port)             outpw((port)+IOP_REG_DA0, data)
1994 #define AscReadChipDA1(port)              (ushort)inpw((port)+IOP_REG_DA1)
1995 #define AscWriteChipDA1(port)             outpw((port)+IOP_REG_DA1, data)
1996 #define AscReadChipDC0(port)              (ushort)inpw((port)+IOP_REG_DC0)
1997 #define AscWriteChipDC0(port)             outpw((port)+IOP_REG_DC0, data)
1998 #define AscReadChipDC1(port)              (ushort)inpw((port)+IOP_REG_DC1)
1999 #define AscWriteChipDC1(port)             outpw((port)+IOP_REG_DC1, data)
2000 #define AscReadChipDvcID(port)            (uchar)inp((port)+IOP_REG_ID)
2001 #define AscWriteChipDvcID(port, data)     outp((port)+IOP_REG_ID, data)
2002
2003 STATIC int       AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
2004 STATIC int       AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
2005 STATIC void      AscWaitEEPRead(void);
2006 STATIC void      AscWaitEEPWrite(void);
2007 STATIC ushort    AscReadEEPWord(PortAddr, uchar);
2008 STATIC ushort    AscWriteEEPWord(PortAddr, uchar, ushort);
2009 STATIC ushort    AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
2010 STATIC int       AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
2011 STATIC int       AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
2012 STATIC int       AscStartChip(PortAddr);
2013 STATIC int       AscStopChip(PortAddr);
2014 STATIC void      AscSetChipIH(PortAddr, ushort);
2015 STATIC int       AscIsChipHalted(PortAddr);
2016 STATIC void      AscAckInterrupt(PortAddr);
2017 STATIC void      AscDisableInterrupt(PortAddr);
2018 STATIC void      AscEnableInterrupt(PortAddr);
2019 STATIC void      AscSetBank(PortAddr, uchar);
2020 STATIC int       AscResetChipAndScsiBus(ASC_DVC_VAR *);
2021 #ifdef CONFIG_ISA
2022 STATIC ushort    AscGetIsaDmaChannel(PortAddr);
2023 STATIC ushort    AscSetIsaDmaChannel(PortAddr, ushort);
2024 STATIC uchar     AscSetIsaDmaSpeed(PortAddr, uchar);
2025 STATIC uchar     AscGetIsaDmaSpeed(PortAddr);
2026 #endif /* CONFIG_ISA */
2027 STATIC uchar     AscReadLramByte(PortAddr, ushort);
2028 STATIC ushort    AscReadLramWord(PortAddr, ushort);
2029 #if CC_VERY_LONG_SG_LIST
2030 STATIC ASC_DCNT  AscReadLramDWord(PortAddr, ushort);
2031 #endif /* CC_VERY_LONG_SG_LIST */
2032 STATIC void      AscWriteLramWord(PortAddr, ushort, ushort);
2033 STATIC void      AscWriteLramByte(PortAddr, ushort, uchar);
2034 STATIC ASC_DCNT  AscMemSumLramWord(PortAddr, ushort, int);
2035 STATIC void      AscMemWordSetLram(PortAddr, ushort, ushort, int);
2036 STATIC void      AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
2037 STATIC void      AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
2038 STATIC void      AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
2039 STATIC ushort    AscInitAscDvcVar(ASC_DVC_VAR *);
2040 STATIC ushort    AscInitFromEEP(ASC_DVC_VAR *);
2041 STATIC ushort    AscInitFromAscDvcVar(ASC_DVC_VAR *);
2042 STATIC ushort    AscInitMicroCodeVar(ASC_DVC_VAR *);
2043 STATIC int       AscTestExternalLram(ASC_DVC_VAR *);
2044 STATIC uchar     AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
2045 STATIC uchar     AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
2046 STATIC void      AscSetChipSDTR(PortAddr, uchar, uchar);
2047 STATIC uchar     AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
2048 STATIC uchar     AscAllocFreeQueue(PortAddr, uchar);
2049 STATIC uchar     AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
2050 STATIC int       AscHostReqRiscHalt(PortAddr);
2051 STATIC int       AscStopQueueExe(PortAddr);
2052 STATIC int       AscSendScsiQueue(ASC_DVC_VAR *,
2053                     ASC_SCSI_Q * scsiq,
2054                     uchar n_q_required);
2055 STATIC int       AscPutReadyQueue(ASC_DVC_VAR *,
2056                     ASC_SCSI_Q *, uchar);
2057 STATIC int       AscPutReadySgListQueue(ASC_DVC_VAR *,
2058                     ASC_SCSI_Q *, uchar);
2059 STATIC int       AscSetChipSynRegAtID(PortAddr, uchar, uchar);
2060 STATIC int       AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
2061 STATIC ushort    AscInitLram(ASC_DVC_VAR *);
2062 STATIC ushort    AscInitQLinkVar(ASC_DVC_VAR *);
2063 STATIC int       AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
2064 STATIC int       AscIsrChipHalted(ASC_DVC_VAR *);
2065 STATIC uchar     _AscCopyLramScsiDoneQ(PortAddr, ushort,
2066                     ASC_QDONE_INFO *, ASC_DCNT);
2067 STATIC int       AscIsrQDone(ASC_DVC_VAR *);
2068 STATIC int       AscCompareString(uchar *, uchar *, int);
2069 #ifdef CONFIG_ISA
2070 STATIC ushort    AscGetEisaChipCfg(PortAddr);
2071 STATIC ASC_DCNT  AscGetEisaProductID(PortAddr);
2072 STATIC PortAddr  AscSearchIOPortAddrEISA(PortAddr);
2073 STATIC PortAddr  AscSearchIOPortAddr11(PortAddr);
2074 STATIC PortAddr  AscSearchIOPortAddr(PortAddr, ushort);
2075 STATIC void      AscSetISAPNPWaitForKey(void);
2076 #endif /* CONFIG_ISA */
2077 STATIC uchar     AscGetChipScsiCtrl(PortAddr);
2078 STATIC uchar     AscSetChipScsiID(PortAddr, uchar);
2079 STATIC uchar     AscGetChipVersion(PortAddr, ushort);
2080 STATIC ushort    AscGetChipBusType(PortAddr);
2081 STATIC ASC_DCNT  AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
2082 STATIC int       AscFindSignature(PortAddr);
2083 STATIC void      AscToggleIRQAct(PortAddr);
2084 STATIC uchar     AscGetChipIRQ(PortAddr, ushort);
2085 STATIC uchar     AscSetChipIRQ(PortAddr, uchar, ushort);
2086 STATIC ushort    AscGetChipBiosAddress(PortAddr, ushort);
2087 STATIC inline ulong DvcEnterCritical(void);
2088 STATIC inline void DvcLeaveCritical(ulong);
2089 #ifdef CONFIG_PCI
2090 STATIC uchar     DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort);
2091 STATIC void      DvcWritePCIConfigByte(ASC_DVC_VAR *,
2092                     ushort, uchar);
2093 #endif /* CONFIG_PCI */
2094 STATIC ushort      AscGetChipBiosAddress(PortAddr, ushort);
2095 STATIC void      DvcSleepMilliSecond(ASC_DCNT);
2096 STATIC void      DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
2097 STATIC void      DvcPutScsiQ(PortAddr, ushort, uchar *, int);
2098 STATIC void      DvcGetQinfo(PortAddr, ushort, uchar *, int);
2099 STATIC ushort    AscInitGetConfig(ASC_DVC_VAR *);
2100 STATIC ushort    AscInitSetConfig(ASC_DVC_VAR *);
2101 STATIC ushort    AscInitAsc1000Driver(ASC_DVC_VAR *);
2102 STATIC void      AscAsyncFix(ASC_DVC_VAR *, uchar,
2103                     ASC_SCSI_INQUIRY *);
2104 STATIC int       AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
2105 STATIC void      AscInquiryHandling(ASC_DVC_VAR *,
2106                     uchar, ASC_SCSI_INQUIRY *);
2107 STATIC int       AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
2108 STATIC int       AscISR(ASC_DVC_VAR *);
2109 STATIC uint      AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar,
2110                     uchar);
2111 STATIC int       AscSgListToQueue(int);
2112 #ifdef CONFIG_ISA
2113 STATIC void      AscEnableIsaDma(uchar);
2114 #endif /* CONFIG_ISA */
2115 STATIC ASC_DCNT  AscGetMaxDmaCount(ushort);
2116
2117
2118 /*
2119  * --- Adv Library Constants and Macros
2120  */
2121
2122 #define ADV_LIB_VERSION_MAJOR  5
2123 #define ADV_LIB_VERSION_MINOR  14
2124
2125 /* d_os_dep.h */
2126 #define ADV_OS_LINUX
2127
2128 /*
2129  * Define Adv Library required special types.
2130  */
2131
2132 /*
2133  * Portable Data Types
2134  *
2135  * Any instance where a 32-bit long or pointer type is assumed
2136  * for precision or HW defined structures, the following define
2137  * types must be used. In Linux the char, short, and int types
2138  * are all consistent at 8, 16, and 32 bits respectively. Pointers
2139  * and long types are 64 bits on Alpha and UltraSPARC.
2140  */
2141 #define ADV_PADDR __u32         /* Physical address data type. */
2142 #define ADV_VADDR __u32         /* Virtual address data type. */
2143 #define ADV_DCNT  __u32         /* Unsigned Data count type. */
2144 #define ADV_SDCNT __s32         /* Signed Data count type. */
2145
2146 /*
2147  * These macros are used to convert a virtual address to a
2148  * 32-bit value. This currently can be used on Linux Alpha
2149  * which uses 64-bit virtual address but a 32-bit bus address.
2150  * This is likely to break in the future, but doing this now
2151  * will give us time to change the HW and FW to handle 64-bit
2152  * addresses.
2153  */
2154 #define ADV_VADDR_TO_U32   virt_to_bus
2155 #define ADV_U32_TO_VADDR   bus_to_virt
2156
2157 #define AdvPortAddr  ulong              /* Virtual memory address size */
2158
2159 /*
2160  * Define Adv Library required memory access macros.
2161  */
2162 #define ADV_MEM_READB(addr) readb(addr)
2163 #define ADV_MEM_READW(addr) readw(addr)
2164 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
2165 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
2166 #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
2167
2168 #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
2169
2170 /*
2171  * For wide  boards a CDB length maximum of 16 bytes
2172  * is supported.
2173  */
2174 #define ADV_MAX_CDB_LEN     16
2175
2176 /*
2177  * Define total number of simultaneous maximum element scatter-gather
2178  * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
2179  * maximum number of outstanding commands per wide host adapter. Each
2180  * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
2181  * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
2182  * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
2183  * structures or 255 scatter-gather elements.
2184  *
2185  */
2186 #define ADV_TOT_SG_BLOCK        ASC_DEF_MAX_HOST_QNG
2187
2188 /*
2189  * Define Adv Library required maximum number of scatter-gather
2190  * elements per request.
2191  */
2192 #define ADV_MAX_SG_LIST         255
2193
2194 /* Number of SG blocks needed. */
2195 #define ADV_NUM_SG_BLOCK \
2196     ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
2197
2198 /* Total contiguous memory needed for SG blocks. */
2199 #define ADV_SG_TOTAL_MEM_SIZE \
2200     (sizeof(ADV_SG_BLOCK) *  ADV_NUM_SG_BLOCK)
2201
2202 #define ADV_PAGE_SIZE PAGE_SIZE
2203
2204 #define ADV_NUM_PAGE_CROSSING \
2205     ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2206
2207 /* a_condor.h */
2208 #define ADV_PCI_VENDOR_ID               0x10CD
2209 #define ADV_PCI_DEVICE_ID_REV_A         0x2300
2210 #define ADV_PCI_DEVID_38C0800_REV1      0x2500
2211 #define ADV_PCI_DEVID_38C1600_REV1      0x2700
2212
2213 #define ADV_EEP_DVC_CFG_BEGIN           (0x00)
2214 #define ADV_EEP_DVC_CFG_END             (0x15)
2215 #define ADV_EEP_DVC_CTL_BEGIN           (0x16)  /* location of OEM name */
2216 #define ADV_EEP_MAX_WORD_ADDR           (0x1E)
2217
2218 #define ADV_EEP_DELAY_MS                100
2219
2220 #define ADV_EEPROM_BIG_ENDIAN          0x8000   /* EEPROM Bit 15 */
2221 #define ADV_EEPROM_BIOS_ENABLE         0x4000   /* EEPROM Bit 14 */
2222 /*
2223  * For the ASC3550 Bit 13 is Termination Polarity control bit.
2224  * For later ICs Bit 13 controls whether the CIS (Card Information
2225  * Service Section) is loaded from EEPROM.
2226  */
2227 #define ADV_EEPROM_TERM_POL            0x2000   /* EEPROM Bit 13 */
2228 #define ADV_EEPROM_CIS_LD              0x2000   /* EEPROM Bit 13 */
2229 /*
2230  * ASC38C1600 Bit 11
2231  *
2232  * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
2233  * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
2234  * Function 0 will specify INT B.
2235  *
2236  * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
2237  * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
2238  * Function 1 will specify INT A.
2239  */
2240 #define ADV_EEPROM_INTAB               0x0800   /* EEPROM Bit 11 */
2241
2242 typedef struct adveep_3550_config
2243 {
2244                                 /* Word Offset, Description */
2245
2246   ushort cfg_lsw;               /* 00 power up initialization */
2247                                 /*  bit 13 set - Term Polarity Control */
2248                                 /*  bit 14 set - BIOS Enable */
2249                                 /*  bit 15 set - Big Endian Mode */
2250   ushort cfg_msw;               /* 01 unused      */
2251   ushort disc_enable;           /* 02 disconnect enable */
2252   ushort wdtr_able;             /* 03 Wide DTR able */
2253   ushort sdtr_able;             /* 04 Synchronous DTR able */
2254   ushort start_motor;           /* 05 send start up motor */
2255   ushort tagqng_able;           /* 06 tag queuing able */
2256   ushort bios_scan;             /* 07 BIOS device control */
2257   ushort scam_tolerant;         /* 08 no scam */
2258
2259   uchar  adapter_scsi_id;       /* 09 Host Adapter ID */
2260   uchar  bios_boot_delay;       /*    power up wait */
2261
2262   uchar  scsi_reset_delay;      /* 10 reset delay */
2263   uchar  bios_id_lun;           /*    first boot device scsi id & lun */
2264                                 /*    high nibble is lun */
2265                                 /*    low nibble is scsi id */
2266
2267   uchar  termination;           /* 11 0 - automatic */
2268                                 /*    1 - low off / high off */
2269                                 /*    2 - low off / high on */
2270                                 /*    3 - low on  / high on */
2271                                 /*    There is no low on  / high off */
2272
2273   uchar  reserved1;             /*    reserved byte (not used) */
2274
2275   ushort bios_ctrl;             /* 12 BIOS control bits */
2276                                 /*  bit 0  BIOS don't act as initiator. */
2277                                 /*  bit 1  BIOS > 1 GB support */
2278                                 /*  bit 2  BIOS > 2 Disk Support */
2279                                 /*  bit 3  BIOS don't support removables */
2280                                 /*  bit 4  BIOS support bootable CD */
2281                                 /*  bit 5  BIOS scan enabled */
2282                                 /*  bit 6  BIOS support multiple LUNs */
2283                                 /*  bit 7  BIOS display of message */
2284                                 /*  bit 8  SCAM disabled */
2285                                 /*  bit 9  Reset SCSI bus during init. */
2286                                 /*  bit 10 */
2287                                 /*  bit 11 No verbose initialization. */
2288                                 /*  bit 12 SCSI parity enabled */
2289                                 /*  bit 13 */
2290                                 /*  bit 14 */
2291                                 /*  bit 15 */
2292   ushort  ultra_able;           /* 13 ULTRA speed able */
2293   ushort  reserved2;            /* 14 reserved */
2294   uchar   max_host_qng;         /* 15 maximum host queuing */
2295   uchar   max_dvc_qng;          /*    maximum per device queuing */
2296   ushort  dvc_cntl;             /* 16 control bit for driver */
2297   ushort  bug_fix;              /* 17 control bit for bug fix */
2298   ushort  serial_number_word1;  /* 18 Board serial number word 1 */
2299   ushort  serial_number_word2;  /* 19 Board serial number word 2 */
2300   ushort  serial_number_word3;  /* 20 Board serial number word 3 */
2301   ushort  check_sum;            /* 21 EEP check sum */
2302   uchar   oem_name[16];         /* 22 OEM name */
2303   ushort  dvc_err_code;         /* 30 last device driver error code */
2304   ushort  adv_err_code;         /* 31 last uc and Adv Lib error code */
2305   ushort  adv_err_addr;         /* 32 last uc error address */
2306   ushort  saved_dvc_err_code;   /* 33 saved last dev. driver error code   */
2307   ushort  saved_adv_err_code;   /* 34 saved last uc and Adv Lib error code */
2308   ushort  saved_adv_err_addr;   /* 35 saved last uc error address         */
2309   ushort  num_of_err;           /* 36 number of error */
2310 } ADVEEP_3550_CONFIG;
2311
2312 typedef struct adveep_38C0800_config
2313 {
2314                                 /* Word Offset, Description */
2315
2316   ushort cfg_lsw;               /* 00 power up initialization */
2317                                 /*  bit 13 set - Load CIS */
2318                                 /*  bit 14 set - BIOS Enable */
2319                                 /*  bit 15 set - Big Endian Mode */
2320   ushort cfg_msw;               /* 01 unused      */
2321   ushort disc_enable;           /* 02 disconnect enable */
2322   ushort wdtr_able;             /* 03 Wide DTR able */
2323   ushort sdtr_speed1;           /* 04 SDTR Speed TID 0-3 */
2324   ushort start_motor;           /* 05 send start up motor */
2325   ushort tagqng_able;           /* 06 tag queuing able */
2326   ushort bios_scan;             /* 07 BIOS device control */
2327   ushort scam_tolerant;         /* 08 no scam */
2328
2329   uchar  adapter_scsi_id;       /* 09 Host Adapter ID */
2330   uchar  bios_boot_delay;       /*    power up wait */
2331
2332   uchar  scsi_reset_delay;      /* 10 reset delay */
2333   uchar  bios_id_lun;           /*    first boot device scsi id & lun */
2334                                 /*    high nibble is lun */
2335                                 /*    low nibble is scsi id */
2336
2337   uchar  termination_se;        /* 11 0 - automatic */
2338                                 /*    1 - low off / high off */
2339                                 /*    2 - low off / high on */
2340                                 /*    3 - low on  / high on */
2341                                 /*    There is no low on  / high off */
2342
2343   uchar  termination_lvd;       /* 11 0 - automatic */
2344                                 /*    1 - low off / high off */
2345                                 /*    2 - low off / high on */
2346                                 /*    3 - low on  / high on */
2347                                 /*    There is no low on  / high off */
2348
2349   ushort bios_ctrl;             /* 12 BIOS control bits */
2350                                 /*  bit 0  BIOS don't act as initiator. */
2351                                 /*  bit 1  BIOS > 1 GB support */
2352                                 /*  bit 2  BIOS > 2 Disk Support */
2353                                 /*  bit 3  BIOS don't support removables */
2354                                 /*  bit 4  BIOS support bootable CD */
2355                                 /*  bit 5  BIOS scan enabled */
2356                                 /*  bit 6  BIOS support multiple LUNs */
2357                                 /*  bit 7  BIOS display of message */
2358                                 /*  bit 8  SCAM disabled */
2359                                 /*  bit 9  Reset SCSI bus during init. */
2360                                 /*  bit 10 */
2361                                 /*  bit 11 No verbose initialization. */
2362                                 /*  bit 12 SCSI parity enabled */
2363                                 /*  bit 13 */
2364                                 /*  bit 14 */
2365                                 /*  bit 15 */
2366   ushort  sdtr_speed2;          /* 13 SDTR speed TID 4-7 */
2367   ushort  sdtr_speed3;          /* 14 SDTR speed TID 8-11 */
2368   uchar   max_host_qng;         /* 15 maximum host queueing */
2369   uchar   max_dvc_qng;          /*    maximum per device queuing */
2370   ushort  dvc_cntl;             /* 16 control bit for driver */
2371   ushort  sdtr_speed4;          /* 17 SDTR speed 4 TID 12-15 */
2372   ushort  serial_number_word1;  /* 18 Board serial number word 1 */
2373   ushort  serial_number_word2;  /* 19 Board serial number word 2 */
2374   ushort  serial_number_word3;  /* 20 Board serial number word 3 */
2375   ushort  check_sum;            /* 21 EEP check sum */
2376   uchar   oem_name[16];         /* 22 OEM name */
2377   ushort  dvc_err_code;         /* 30 last device driver error code */
2378   ushort  adv_err_code;         /* 31 last uc and Adv Lib error code */
2379   ushort  adv_err_addr;         /* 32 last uc error address */
2380   ushort  saved_dvc_err_code;   /* 33 saved last dev. driver error code   */
2381   ushort  saved_adv_err_code;   /* 34 saved last uc and Adv Lib error code */
2382   ushort  saved_adv_err_addr;   /* 35 saved last uc error address         */
2383   ushort  reserved36;           /* 36 reserved */
2384   ushort  reserved37;           /* 37 reserved */
2385   ushort  reserved38;           /* 38 reserved */
2386   ushort  reserved39;           /* 39 reserved */
2387   ushort  reserved40;           /* 40 reserved */
2388   ushort  reserved41;           /* 41 reserved */
2389   ushort  reserved42;           /* 42 reserved */
2390   ushort  reserved43;           /* 43 reserved */
2391   ushort  reserved44;           /* 44 reserved */
2392   ushort  reserved45;           /* 45 reserved */
2393   ushort  reserved46;           /* 46 reserved */
2394   ushort  reserved47;           /* 47 reserved */
2395   ushort  reserved48;           /* 48 reserved */
2396   ushort  reserved49;           /* 49 reserved */
2397   ushort  reserved50;           /* 50 reserved */
2398   ushort  reserved51;           /* 51 reserved */
2399   ushort  reserved52;           /* 52 reserved */
2400   ushort  reserved53;           /* 53 reserved */
2401   ushort  reserved54;           /* 54 reserved */
2402   ushort  reserved55;           /* 55 reserved */
2403   ushort  cisptr_lsw;           /* 56 CIS PTR LSW */
2404   ushort  cisprt_msw;           /* 57 CIS PTR MSW */
2405   ushort  subsysvid;            /* 58 SubSystem Vendor ID */
2406   ushort  subsysid;             /* 59 SubSystem ID */
2407   ushort  reserved60;           /* 60 reserved */
2408   ushort  reserved61;           /* 61 reserved */
2409   ushort  reserved62;           /* 62 reserved */
2410   ushort  reserved63;           /* 63 reserved */
2411 } ADVEEP_38C0800_CONFIG;
2412
2413 typedef struct adveep_38C1600_config
2414 {
2415                                 /* Word Offset, Description */
2416
2417   ushort cfg_lsw;               /* 00 power up initialization */
2418                                 /*  bit 11 set - Func. 0 INTB, Func. 1 INTA */
2419                                 /*       clear - Func. 0 INTA, Func. 1 INTB */
2420                                 /*  bit 13 set - Load CIS */
2421                                 /*  bit 14 set - BIOS Enable */
2422                                 /*  bit 15 set - Big Endian Mode */
2423   ushort cfg_msw;               /* 01 unused */
2424   ushort disc_enable;           /* 02 disconnect enable */
2425   ushort wdtr_able;             /* 03 Wide DTR able */
2426   ushort sdtr_speed1;           /* 04 SDTR Speed TID 0-3 */
2427   ushort start_motor;           /* 05 send start up motor */
2428   ushort tagqng_able;           /* 06 tag queuing able */
2429   ushort bios_scan;             /* 07 BIOS device control */
2430   ushort scam_tolerant;         /* 08 no scam */
2431
2432   uchar  adapter_scsi_id;       /* 09 Host Adapter ID */
2433   uchar  bios_boot_delay;       /*    power up wait */
2434
2435   uchar  scsi_reset_delay;      /* 10 reset delay */
2436   uchar  bios_id_lun;           /*    first boot device scsi id & lun */
2437                                 /*    high nibble is lun */
2438                                 /*    low nibble is scsi id */
2439
2440   uchar  termination_se;        /* 11 0 - automatic */
2441                                 /*    1 - low off / high off */
2442                                 /*    2 - low off / high on */
2443                                 /*    3 - low on  / high on */
2444                                 /*    There is no low on  / high off */
2445
2446   uchar  termination_lvd;       /* 11 0 - automatic */
2447                                 /*    1 - low off / high off */
2448                                 /*    2 - low off / high on */
2449                                 /*    3 - low on  / high on */
2450                                 /*    There is no low on  / high off */
2451
2452   ushort bios_ctrl;             /* 12 BIOS control bits */
2453                                 /*  bit 0  BIOS don't act as initiator. */
2454                                 /*  bit 1  BIOS > 1 GB support */
2455                                 /*  bit 2  BIOS > 2 Disk Support */
2456                                 /*  bit 3  BIOS don't support removables */
2457                                 /*  bit 4  BIOS support bootable CD */
2458                                 /*  bit 5  BIOS scan enabled */
2459                                 /*  bit 6  BIOS support multiple LUNs */
2460                                 /*  bit 7  BIOS display of message */
2461                                 /*  bit 8  SCAM disabled */
2462                                 /*  bit 9  Reset SCSI bus during init. */
2463                                 /*  bit 10 Basic Integrity Checking disabled */
2464                                 /*  bit 11 No verbose initialization. */
2465                                 /*  bit 12 SCSI parity enabled */
2466                                 /*  bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
2467                                 /*  bit 14 */
2468                                 /*  bit 15 */
2469   ushort  sdtr_speed2;          /* 13 SDTR speed TID 4-7 */
2470   ushort  sdtr_speed3;          /* 14 SDTR speed TID 8-11 */
2471   uchar   max_host_qng;         /* 15 maximum host queueing */
2472   uchar   max_dvc_qng;          /*    maximum per device queuing */
2473   ushort  dvc_cntl;             /* 16 control bit for driver */
2474   ushort  sdtr_speed4;          /* 17 SDTR speed 4 TID 12-15 */
2475   ushort  serial_number_word1;  /* 18 Board serial number word 1 */
2476   ushort  serial_number_word2;  /* 19 Board serial number word 2 */
2477   ushort  serial_number_word3;  /* 20 Board serial number word 3 */
2478   ushort  check_sum;            /* 21 EEP check sum */
2479   uchar   oem_name[16];         /* 22 OEM name */
2480   ushort  dvc_err_code;         /* 30 last device driver error code */
2481   ushort  adv_err_code;         /* 31 last uc and Adv Lib error code */
2482   ushort  adv_err_addr;         /* 32 last uc error address */
2483   ushort  saved_dvc_err_code;   /* 33 saved last dev. driver error code   */
2484   ushort  saved_adv_err_code;   /* 34 saved last uc and Adv Lib error code */
2485   ushort  saved_adv_err_addr;   /* 35 saved last uc error address         */
2486   ushort  reserved36;           /* 36 reserved */
2487   ushort  reserved37;           /* 37 reserved */
2488   ushort  reserved38;           /* 38 reserved */
2489   ushort  reserved39;           /* 39 reserved */
2490   ushort  reserved40;           /* 40 reserved */
2491   ushort  reserved41;           /* 41 reserved */
2492   ushort  reserved42;           /* 42 reserved */
2493   ushort  reserved43;           /* 43 reserved */
2494   ushort  reserved44;           /* 44 reserved */
2495   ushort  reserved45;           /* 45 reserved */
2496   ushort  reserved46;           /* 46 reserved */
2497   ushort  reserved47;           /* 47 reserved */
2498   ushort  reserved48;           /* 48 reserved */
2499   ushort  reserved49;           /* 49 reserved */
2500   ushort  reserved50;           /* 50 reserved */
2501   ushort  reserved51;           /* 51 reserved */
2502   ushort  reserved52;           /* 52 reserved */
2503   ushort  reserved53;           /* 53 reserved */
2504   ushort  reserved54;           /* 54 reserved */
2505   ushort  reserved55;           /* 55 reserved */
2506   ushort  cisptr_lsw;           /* 56 CIS PTR LSW */
2507   ushort  cisprt_msw;           /* 57 CIS PTR MSW */
2508   ushort  subsysvid;            /* 58 SubSystem Vendor ID */
2509   ushort  subsysid;             /* 59 SubSystem ID */
2510   ushort  reserved60;           /* 60 reserved */
2511   ushort  reserved61;           /* 61 reserved */
2512   ushort  reserved62;           /* 62 reserved */
2513   ushort  reserved63;           /* 63 reserved */
2514 } ADVEEP_38C1600_CONFIG;
2515
2516 /*
2517  * EEPROM Commands
2518  */
2519 #define ASC_EEP_CMD_DONE             0x0200
2520 #define ASC_EEP_CMD_DONE_ERR         0x0001
2521
2522 /* cfg_word */
2523 #define EEP_CFG_WORD_BIG_ENDIAN      0x8000
2524
2525 /* bios_ctrl */
2526 #define BIOS_CTRL_BIOS               0x0001
2527 #define BIOS_CTRL_EXTENDED_XLAT      0x0002
2528 #define BIOS_CTRL_GT_2_DISK          0x0004
2529 #define BIOS_CTRL_BIOS_REMOVABLE     0x0008
2530 #define BIOS_CTRL_BOOTABLE_CD        0x0010
2531 #define BIOS_CTRL_MULTIPLE_LUN       0x0040
2532 #define BIOS_CTRL_DISPLAY_MSG        0x0080
2533 #define BIOS_CTRL_NO_SCAM            0x0100
2534 #define BIOS_CTRL_RESET_SCSI_BUS     0x0200
2535 #define BIOS_CTRL_INIT_VERBOSE       0x0800
2536 #define BIOS_CTRL_SCSI_PARITY        0x1000
2537 #define BIOS_CTRL_AIPP_DIS           0x2000
2538
2539 #define ADV_3550_MEMSIZE   0x2000       /* 8 KB Internal Memory */
2540 #define ADV_3550_IOLEN     0x40         /* I/O Port Range in bytes */
2541
2542 #define ADV_38C0800_MEMSIZE  0x4000     /* 16 KB Internal Memory */
2543 #define ADV_38C0800_IOLEN    0x100      /* I/O Port Range in bytes */
2544
2545 /*
2546  * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
2547  * a special 16K Adv Library and Microcode version. After the issue is
2548  * resolved, should restore 32K support.
2549  *
2550  * #define ADV_38C1600_MEMSIZE  0x8000L   * 32 KB Internal Memory *
2551  */
2552 #define ADV_38C1600_MEMSIZE  0x4000   /* 16 KB Internal Memory */
2553 #define ADV_38C1600_IOLEN    0x100     /* I/O Port Range 256 bytes */
2554 #define ADV_38C1600_MEMLEN   0x1000    /* Memory Range 4KB bytes */
2555
2556 /*
2557  * Byte I/O register address from base of 'iop_base'.
2558  */
2559 #define IOPB_INTR_STATUS_REG    0x00
2560 #define IOPB_CHIP_ID_1          0x01
2561 #define IOPB_INTR_ENABLES       0x02
2562 #define IOPB_CHIP_TYPE_REV      0x03
2563 #define IOPB_RES_ADDR_4         0x04
2564 #define IOPB_RES_ADDR_5         0x05
2565 #define IOPB_RAM_DATA           0x06
2566 #define IOPB_RES_ADDR_7         0x07
2567 #define IOPB_FLAG_REG           0x08
2568 #define IOPB_RES_ADDR_9         0x09
2569 #define IOPB_RISC_CSR           0x0A
2570 #define IOPB_RES_ADDR_B         0x0B
2571 #define IOPB_RES_ADDR_C         0x0C
2572 #define IOPB_RES_ADDR_D         0x0D
2573 #define IOPB_SOFT_OVER_WR       0x0E
2574 #define IOPB_RES_ADDR_F         0x0F
2575 #define IOPB_MEM_CFG            0x10
2576 #define IOPB_RES_ADDR_11        0x11
2577 #define IOPB_GPIO_DATA          0x12
2578 #define IOPB_RES_ADDR_13        0x13
2579 #define IOPB_FLASH_PAGE         0x14
2580 #define IOPB_RES_ADDR_15        0x15
2581 #define IOPB_GPIO_CNTL          0x16
2582 #define IOPB_RES_ADDR_17        0x17
2583 #define IOPB_FLASH_DATA         0x18
2584 #define IOPB_RES_ADDR_19        0x19
2585 #define IOPB_RES_ADDR_1A        0x1A
2586 #define IOPB_RES_ADDR_1B        0x1B
2587 #define IOPB_RES_ADDR_1C        0x1C
2588 #define IOPB_RES_ADDR_1D        0x1D
2589 #define IOPB_RES_ADDR_1E        0x1E
2590 #define IOPB_RES_ADDR_1F        0x1F
2591 #define IOPB_DMA_CFG0           0x20
2592 #define IOPB_DMA_CFG1           0x21
2593 #define IOPB_TICKLE             0x22
2594 #define IOPB_DMA_REG_WR         0x23
2595 #define IOPB_SDMA_STATUS        0x24
2596 #define IOPB_SCSI_BYTE_CNT      0x25
2597 #define IOPB_HOST_BYTE_CNT      0x26
2598 #define IOPB_BYTE_LEFT_TO_XFER  0x27
2599 #define IOPB_BYTE_TO_XFER_0     0x28
2600 #define IOPB_BYTE_TO_XFER_1     0x29
2601 #define IOPB_BYTE_TO_XFER_2     0x2A
2602 #define IOPB_BYTE_TO_XFER_3     0x2B
2603 #define IOPB_ACC_GRP            0x2C
2604 #define IOPB_RES_ADDR_2D        0x2D
2605 #define IOPB_DEV_ID             0x2E
2606 #define IOPB_RES_ADDR_2F        0x2F
2607 #define IOPB_SCSI_DATA          0x30
2608 #define IOPB_RES_ADDR_31        0x31
2609 #define IOPB_RES_ADDR_32        0x32
2610 #define IOPB_SCSI_DATA_HSHK     0x33
2611 #define IOPB_SCSI_CTRL          0x34
2612 #define IOPB_RES_ADDR_35        0x35
2613 #define IOPB_RES_ADDR_36        0x36
2614 #define IOPB_RES_ADDR_37        0x37
2615 #define IOPB_RAM_BIST           0x38
2616 #define IOPB_PLL_TEST           0x39
2617 #define IOPB_PCI_INT_CFG        0x3A
2618 #define IOPB_RES_ADDR_3B        0x3B
2619 #define IOPB_RFIFO_CNT          0x3C
2620 #define IOPB_RES_ADDR_3D        0x3D
2621 #define IOPB_RES_ADDR_3E        0x3E
2622 #define IOPB_RES_ADDR_3F        0x3F
2623
2624 /*
2625  * Word I/O register address from base of 'iop_base'.
2626  */
2627 #define IOPW_CHIP_ID_0          0x00  /* CID0  */
2628 #define IOPW_CTRL_REG           0x02  /* CC    */
2629 #define IOPW_RAM_ADDR           0x04  /* LA    */
2630 #define IOPW_RAM_DATA           0x06  /* LD    */
2631 #define IOPW_RES_ADDR_08        0x08
2632 #define IOPW_RISC_CSR           0x0A  /* CSR   */
2633 #define IOPW_SCSI_CFG0          0x0C  /* CFG0  */
2634 #define IOPW_SCSI_CFG1          0x0E  /* CFG1  */
2635 #define IOPW_RES_ADDR_10        0x10
2636 #define IOPW_SEL_MASK           0x12  /* SM    */
2637 #define IOPW_RES_ADDR_14        0x14
2638 #define IOPW_FLASH_ADDR         0x16  /* FA    */
2639 #define IOPW_RES_ADDR_18        0x18
2640 #define IOPW_EE_CMD             0x1A  /* EC    */
2641 #define IOPW_EE_DATA            0x1C  /* ED    */
2642 #define IOPW_SFIFO_CNT          0x1E  /* SFC   */
2643 #define IOPW_RES_ADDR_20        0x20
2644 #define IOPW_Q_BASE             0x22  /* QB    */
2645 #define IOPW_QP                 0x24  /* QP    */
2646 #define IOPW_IX                 0x26  /* IX    */
2647 #define IOPW_SP                 0x28  /* SP    */
2648 #define IOPW_PC                 0x2A  /* PC    */
2649 #define IOPW_RES_ADDR_2C        0x2C
2650 #define IOPW_RES_ADDR_2E        0x2E
2651 #define IOPW_SCSI_DATA          0x30  /* SD    */
2652 #define IOPW_SCSI_DATA_HSHK     0x32  /* SDH   */
2653 #define IOPW_SCSI_CTRL          0x34  /* SC    */
2654 #define IOPW_HSHK_CFG           0x36  /* HCFG  */
2655 #define IOPW_SXFR_STATUS        0x36  /* SXS   */
2656 #define IOPW_SXFR_CNTL          0x38  /* SXL   */
2657 #define IOPW_SXFR_CNTH          0x3A  /* SXH   */
2658 #define IOPW_RES_ADDR_3C        0x3C
2659 #define IOPW_RFIFO_DATA         0x3E  /* RFD   */
2660
2661 /*
2662  * Doubleword I/O register address from base of 'iop_base'.
2663  */
2664 #define IOPDW_RES_ADDR_0         0x00
2665 #define IOPDW_RAM_DATA           0x04
2666 #define IOPDW_RES_ADDR_8         0x08
2667 #define IOPDW_RES_ADDR_C         0x0C
2668 #define IOPDW_RES_ADDR_10        0x10
2669 #define IOPDW_COMMA              0x14
2670 #define IOPDW_COMMB              0x18
2671 #define IOPDW_RES_ADDR_1C        0x1C
2672 #define IOPDW_SDMA_ADDR0         0x20
2673 #define IOPDW_SDMA_ADDR1         0x24
2674 #define IOPDW_SDMA_COUNT         0x28
2675 #define IOPDW_SDMA_ERROR         0x2C
2676 #define IOPDW_RDMA_ADDR0         0x30
2677 #define IOPDW_RDMA_ADDR1         0x34
2678 #define IOPDW_RDMA_COUNT         0x38
2679 #define IOPDW_RDMA_ERROR         0x3C
2680
2681 #define ADV_CHIP_ID_BYTE         0x25
2682 #define ADV_CHIP_ID_WORD         0x04C1
2683
2684 #define ADV_SC_SCSI_BUS_RESET    0x2000
2685
2686 #define ADV_INTR_ENABLE_HOST_INTR                   0x01
2687 #define ADV_INTR_ENABLE_SEL_INTR                    0x02
2688 #define ADV_INTR_ENABLE_DPR_INTR                    0x04
2689 #define ADV_INTR_ENABLE_RTA_INTR                    0x08
2690 #define ADV_INTR_ENABLE_RMA_INTR                    0x10
2691 #define ADV_INTR_ENABLE_RST_INTR                    0x20
2692 #define ADV_INTR_ENABLE_DPE_INTR                    0x40
2693 #define ADV_INTR_ENABLE_GLOBAL_INTR                 0x80
2694
2695 #define ADV_INTR_STATUS_INTRA            0x01
2696 #define ADV_INTR_STATUS_INTRB            0x02
2697 #define ADV_INTR_STATUS_INTRC            0x04
2698
2699 #define ADV_RISC_CSR_STOP           (0x0000)
2700 #define ADV_RISC_TEST_COND          (0x2000)
2701 #define ADV_RISC_CSR_RUN            (0x4000)
2702 #define ADV_RISC_CSR_SINGLE_STEP    (0x8000)
2703
2704 #define ADV_CTRL_REG_HOST_INTR      0x0100
2705 #define ADV_CTRL_REG_SEL_INTR       0x0200
2706 #define ADV_CTRL_REG_DPR_INTR       0x0400
2707 #define ADV_CTRL_REG_RTA_INTR       0x0800
2708 #define ADV_CTRL_REG_RMA_INTR       0x1000
2709 #define ADV_CTRL_REG_RES_BIT14      0x2000
2710 #define ADV_CTRL_REG_DPE_INTR       0x4000
2711 #define ADV_CTRL_REG_POWER_DONE     0x8000
2712 #define ADV_CTRL_REG_ANY_INTR       0xFF00
2713
2714 #define ADV_CTRL_REG_CMD_RESET             0x00C6
2715 #define ADV_CTRL_REG_CMD_WR_IO_REG         0x00C5
2716 #define ADV_CTRL_REG_CMD_RD_IO_REG         0x00C4
2717 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE  0x00C3
2718 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE  0x00C2
2719
2720 #define ADV_TICKLE_NOP                      0x00
2721 #define ADV_TICKLE_A                        0x01
2722 #define ADV_TICKLE_B                        0x02
2723 #define ADV_TICKLE_C                        0x03
2724
2725 #define ADV_SCSI_CTRL_RSTOUT        0x2000
2726
2727 #define AdvIsIntPending(port) \
2728     (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2729
2730 /*
2731  * SCSI_CFG0 Register bit definitions
2732  */
2733 #define TIMER_MODEAB    0xC000  /* Watchdog, Second, and Select. Timer Ctrl. */
2734 #define PARITY_EN       0x2000  /* Enable SCSI Parity Error detection */
2735 #define EVEN_PARITY     0x1000  /* Select Even Parity */
2736 #define WD_LONG         0x0800  /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2737 #define QUEUE_128       0x0400  /* Queue Size, 1: 128 byte, 0: 64 byte */
2738 #define PRIM_MODE       0x0100  /* Primitive SCSI mode */
2739 #define SCAM_EN         0x0080  /* Enable SCAM selection */
2740 #define SEL_TMO_LONG    0x0040  /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2741 #define CFRM_ID         0x0020  /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2742 #define OUR_ID_EN       0x0010  /* Enable OUR_ID bits */
2743 #define OUR_ID          0x000F  /* SCSI ID */
2744
2745 /*
2746  * SCSI_CFG1 Register bit definitions
2747  */
2748 #define BIG_ENDIAN      0x8000  /* Enable Big Endian Mode MIO:15, EEP:15 */
2749 #define TERM_POL        0x2000  /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2750 #define SLEW_RATE       0x1000  /* SCSI output buffer slew rate */
2751 #define FILTER_SEL      0x0C00  /* Filter Period Selection */
2752 #define  FLTR_DISABLE    0x0000  /* Input Filtering Disabled */
2753 #define  FLTR_11_TO_20NS 0x0800  /* Input Filtering 11ns to 20ns */
2754 #define  FLTR_21_TO_39NS 0x0C00  /* Input Filtering 21ns to 39ns */
2755 #define ACTIVE_DBL      0x0200  /* Disable Active Negation */
2756 #define DIFF_MODE       0x0100  /* SCSI differential Mode (Read-Only) */
2757 #define DIFF_SENSE      0x0080  /* 1: No SE cables, 0: SE cable (Read-Only) */
2758 #define TERM_CTL_SEL    0x0040  /* Enable TERM_CTL_H and TERM_CTL_L */
2759 #define TERM_CTL        0x0030  /* External SCSI Termination Bits */
2760 #define  TERM_CTL_H      0x0020  /* Enable External SCSI Upper Termination */
2761 #define  TERM_CTL_L      0x0010  /* Enable External SCSI Lower Termination */
2762 #define CABLE_DETECT    0x000F  /* External SCSI Cable Connection Status */
2763
2764 /*
2765  * Addendum for ASC-38C0800 Chip
2766  *
2767  * The ASC-38C1600 Chip uses the same definitions except that the
2768  * bus mode override bits [12:10] have been moved to byte register
2769  * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
2770  * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
2771  * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
2772  * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
2773  * and [1:0]. Bits [14], [7:6], [3:2] are unused.
2774  */
2775 #define DIS_TERM_DRV    0x4000  /* 1: Read c_det[3:0], 0: cannot read */
2776 #define HVD_LVD_SE      0x1C00  /* Device Detect Bits */
2777 #define  HVD             0x1000  /* HVD Device Detect */
2778 #define  LVD             0x0800  /* LVD Device Detect */
2779 #define  SE              0x0400  /* SE Device Detect */
2780 #define TERM_LVD        0x00C0  /* LVD Termination Bits */
2781 #define  TERM_LVD_HI     0x0080  /* Enable LVD Upper Termination */
2782 #define  TERM_LVD_LO     0x0040  /* Enable LVD Lower Termination */
2783 #define TERM_SE         0x0030  /* SE Termination Bits */
2784 #define  TERM_SE_HI      0x0020  /* Enable SE Upper Termination */
2785 #define  TERM_SE_LO      0x0010  /* Enable SE Lower Termination */
2786 #define C_DET_LVD       0x000C  /* LVD Cable Detect Bits */
2787 #define  C_DET3          0x0008  /* Cable Detect for LVD External Wide */
2788 #define  C_DET2          0x0004  /* Cable Detect for LVD Internal Wide */
2789 #define C_DET_SE        0x0003  /* SE Cable Detect Bits */
2790 #define  C_DET1          0x0002  /* Cable Detect for SE Internal Wide */
2791 #define  C_DET0          0x0001  /* Cable Detect for SE Internal Narrow */
2792
2793
2794 #define CABLE_ILLEGAL_A 0x7
2795     /* x 0 0 0  | on  on | Illegal (all 3 connectors are used) */
2796
2797 #define CABLE_ILLEGAL_B 0xB
2798     /* 0 x 0 0  | on  on | Illegal (all 3 connectors are used) */
2799
2800 /*
2801  * MEM_CFG Register bit definitions
2802  */
2803 #define BIOS_EN         0x40    /* BIOS Enable MIO:14,EEP:14 */
2804 #define FAST_EE_CLK     0x20    /* Diagnostic Bit */
2805 #define RAM_SZ          0x1C    /* Specify size of RAM to RISC */
2806 #define  RAM_SZ_2KB      0x00    /* 2 KB */
2807 #define  RAM_SZ_4KB      0x04    /* 4 KB */
2808 #define  RAM_SZ_8KB      0x08    /* 8 KB */
2809 #define  RAM_SZ_16KB     0x0C    /* 16 KB */
2810 #define  RAM_SZ_32KB     0x10    /* 32 KB */
2811 #define  RAM_SZ_64KB     0x14    /* 64 KB */
2812
2813 /*
2814  * DMA_CFG0 Register bit definitions
2815  *
2816  * This register is only accessible to the host.
2817  */
2818 #define BC_THRESH_ENB   0x80    /* PCI DMA Start Conditions */
2819 #define FIFO_THRESH     0x70    /* PCI DMA FIFO Threshold */
2820 #define  FIFO_THRESH_16B  0x00   /* 16 bytes */
2821 #define  FIFO_THRESH_32B  0x20   /* 32 bytes */
2822 #define  FIFO_THRESH_48B  0x30   /* 48 bytes */
2823 #define  FIFO_THRESH_64B  0x40   /* 64 bytes */
2824 #define  FIFO_THRESH_80B  0x50   /* 80 bytes (default) */
2825 #define  FIFO_THRESH_96B  0x60   /* 96 bytes */
2826 #define  FIFO_THRESH_112B 0x70   /* 112 bytes */
2827 #define START_CTL       0x0C    /* DMA start conditions */
2828 #define  START_CTL_TH    0x00    /* Wait threshold level (default) */
2829 #define  START_CTL_ID    0x04    /* Wait SDMA/SBUS idle */
2830 #define  START_CTL_THID  0x08    /* Wait threshold and SDMA/SBUS idle */
2831 #define  START_CTL_EMFU  0x0C    /* Wait SDMA FIFO empty/full */
2832 #define READ_CMD        0x03    /* Memory Read Method */
2833 #define  READ_CMD_MR     0x00    /* Memory Read */
2834 #define  READ_CMD_MRL    0x02    /* Memory Read Long */
2835 #define  READ_CMD_MRM    0x03    /* Memory Read Multiple (default) */
2836
2837 /*
2838  * ASC-38C0800 RAM BIST Register bit definitions
2839  */
2840 #define RAM_TEST_MODE         0x80
2841 #define PRE_TEST_MODE         0x40
2842 #define NORMAL_MODE           0x00
2843 #define RAM_TEST_DONE         0x10
2844 #define RAM_TEST_STATUS       0x0F
2845 #define  RAM_TEST_HOST_ERROR   0x08
2846 #define  RAM_TEST_INTRAM_ERROR 0x04
2847 #define  RAM_TEST_RISC_ERROR   0x02
2848 #define  RAM_TEST_SCSI_ERROR   0x01
2849 #define  RAM_TEST_SUCCESS      0x00
2850 #define PRE_TEST_VALUE        0x05
2851 #define NORMAL_VALUE          0x00
2852
2853 /*
2854  * ASC38C1600 Definitions
2855  *
2856  * IOPB_PCI_INT_CFG Bit Field Definitions
2857  */
2858
2859 #define INTAB_LD        0x80    /* Value loaded from EEPROM Bit 11. */
2860
2861 /*
2862  * Bit 1 can be set to change the interrupt for the Function to operate in
2863  * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
2864  * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
2865  * mode, otherwise the operating mode is undefined.
2866  */
2867 #define TOTEMPOLE       0x02
2868
2869 /*
2870  * Bit 0 can be used to change the Int Pin for the Function. The value is
2871  * 0 by default for both Functions with Function 0 using INT A and Function
2872  * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
2873  * INT A is used.
2874  *
2875  * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
2876  * value specified in the PCI Configuration Space.
2877  */
2878 #define INTAB           0x01
2879
2880 /* a_advlib.h */
2881
2882 /*
2883  * Adv Library Status Definitions
2884  */
2885 #define ADV_TRUE        1
2886 #define ADV_FALSE       0
2887 #define ADV_NOERROR     1
2888 #define ADV_SUCCESS     1
2889 #define ADV_BUSY        0
2890 #define ADV_ERROR       (-1)
2891
2892
2893 /*
2894  * ADV_DVC_VAR 'warn_code' values
2895  */
2896 #define ASC_WARN_BUSRESET_ERROR         0x0001 /* SCSI Bus Reset error */
2897 #define ASC_WARN_EEPROM_CHKSUM          0x0002 /* EEP check sum error */
2898 #define ASC_WARN_EEPROM_TERMINATION     0x0004 /* EEP termination bad field */
2899 #define ASC_WARN_SET_PCI_CONFIG_SPACE   0x0080 /* PCI config space set error */
2900 #define ASC_WARN_ERROR                  0xFFFF /* ADV_ERROR return */
2901
2902 #define ADV_MAX_TID                     15 /* max. target identifier */
2903 #define ADV_MAX_LUN                     7  /* max. logical unit number */
2904
2905 /*
2906  * Error code values are set in ADV_DVC_VAR 'err_code'.
2907  */
2908 #define ASC_IERR_WRITE_EEPROM       0x0001 /* write EEPROM error */
2909 #define ASC_IERR_MCODE_CHKSUM       0x0002 /* micro code check sum error */
2910 #define ASC_IERR_NO_CARRIER         0x0004 /* No more carrier memory. */
2911 #define ASC_IERR_START_STOP_CHIP    0x0008 /* start/stop chip failed */
2912 #define ASC_IERR_CHIP_VERSION       0x0040 /* wrong chip version */
2913 #define ASC_IERR_SET_SCSI_ID        0x0080 /* set SCSI ID failed */
2914 #define ASC_IERR_HVD_DEVICE         0x0100 /* HVD attached to LVD connector. */
2915 #define ASC_IERR_BAD_SIGNATURE      0x0200 /* signature not found */
2916 #define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
2917 #define ASC_IERR_SINGLE_END_DEVICE  0x0800 /* Single-end used w/differential */
2918 #define ASC_IERR_REVERSED_CABLE     0x1000 /* Narrow flat cable reversed */
2919 #define ASC_IERR_BIST_PRE_TEST      0x2000 /* BIST pre-test error */
2920 #define ASC_IERR_BIST_RAM_TEST      0x4000 /* BIST RAM test error */
2921 #define ASC_IERR_BAD_CHIPTYPE       0x8000 /* Invalid 'chip_type' setting. */
2922
2923 /*
2924  * Fixed locations of microcode operating variables.
2925  */
2926 #define ASC_MC_CODE_BEGIN_ADDR          0x0028 /* microcode start address */
2927 #define ASC_MC_CODE_END_ADDR            0x002A /* microcode end address */
2928 #define ASC_MC_CODE_CHK_SUM             0x002C /* microcode code checksum */
2929 #define ASC_MC_VERSION_DATE             0x0038 /* microcode version */
2930 #define ASC_MC_VERSION_NUM              0x003A /* microcode number */
2931 #define ASC_MC_BIOSMEM                  0x0040 /* BIOS RISC Memory Start */
2932 #define ASC_MC_BIOSLEN                  0x0050 /* BIOS RISC Memory Length */
2933 #define ASC_MC_BIOS_SIGNATURE           0x0058 /* BIOS Signature 0x55AA */
2934 #define ASC_MC_BIOS_VERSION             0x005A /* BIOS Version (2 bytes) */
2935 #define ASC_MC_SDTR_SPEED1              0x0090 /* SDTR Speed for TID 0-3 */
2936 #define ASC_MC_SDTR_SPEED2              0x0092 /* SDTR Speed for TID 4-7 */
2937 #define ASC_MC_SDTR_SPEED3              0x0094 /* SDTR Speed for TID 8-11 */
2938 #define ASC_MC_SDTR_SPEED4              0x0096 /* SDTR Speed for TID 12-15 */
2939 #define ASC_MC_CHIP_TYPE                0x009A
2940 #define ASC_MC_INTRB_CODE               0x009B
2941 #define ASC_MC_WDTR_ABLE                0x009C
2942 #define ASC_MC_SDTR_ABLE                0x009E
2943 #define ASC_MC_TAGQNG_ABLE              0x00A0
2944 #define ASC_MC_DISC_ENABLE              0x00A2
2945 #define ASC_MC_IDLE_CMD_STATUS          0x00A4
2946 #define ASC_MC_IDLE_CMD                 0x00A6
2947 #define ASC_MC_IDLE_CMD_PARAMETER       0x00A8
2948 #define ASC_MC_DEFAULT_SCSI_CFG0        0x00AC
2949 #define ASC_MC_DEFAULT_SCSI_CFG1        0x00AE
2950 #define ASC_MC_DEFAULT_MEM_CFG          0x00B0
2951 #define ASC_MC_DEFAULT_SEL_MASK         0x00B2
2952 #define ASC_MC_SDTR_DONE                0x00B6
2953 #define ASC_MC_NUMBER_OF_QUEUED_CMD     0x00C0
2954 #define ASC_MC_NUMBER_OF_MAX_CMD        0x00D0
2955 #define ASC_MC_DEVICE_HSHK_CFG_TABLE    0x0100
2956 #define ASC_MC_CONTROL_FLAG             0x0122 /* Microcode control flag. */
2957 #define ASC_MC_WDTR_DONE                0x0124
2958 #define ASC_MC_CAM_MODE_MASK            0x015E /* CAM mode TID bitmask. */
2959 #define ASC_MC_ICQ                      0x0160
2960 #define ASC_MC_IRQ                      0x0164
2961 #define ASC_MC_PPR_ABLE                 0x017A
2962
2963 /*
2964  * BIOS LRAM variable absolute offsets.
2965  */
2966 #define BIOS_CODESEG    0x54
2967 #define BIOS_CODELEN    0x56
2968 #define BIOS_SIGNATURE  0x58
2969 #define BIOS_VERSION    0x5A
2970
2971 /*
2972  * Microcode Control Flags
2973  *
2974  * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2975  * and handled by the microcode.
2976  */
2977 #define CONTROL_FLAG_IGNORE_PERR        0x0001 /* Ignore DMA Parity Errors */
2978 #define CONTROL_FLAG_ENABLE_AIPP        0x0002 /* Enabled AIPP checking. */
2979
2980 /*
2981  * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2982  */
2983 #define HSHK_CFG_WIDE_XFR       0x8000
2984 #define HSHK_CFG_RATE           0x0F00
2985 #define HSHK_CFG_OFFSET         0x001F
2986
2987 #define ASC_DEF_MAX_HOST_QNG    0xFD /* Max. number of host commands (253) */
2988 #define ASC_DEF_MIN_HOST_QNG    0x10 /* Min. number of host commands (16) */
2989 #define ASC_DEF_MAX_DVC_QNG     0x3F /* Max. number commands per device (63) */
2990 #define ASC_DEF_MIN_DVC_QNG     0x04 /* Min. number commands per device (4) */
2991
2992 #define ASC_QC_DATA_CHECK  0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2993 #define ASC_QC_DATA_OUT    0x02 /* Data out DMA transfer. */
2994 #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2995 #define ASC_QC_NO_OVERRUN  0x08 /* Don't report overrun. */
2996 #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2997
2998 #define ASC_QSC_NO_DISC     0x01 /* Don't allow disconnect for request. */
2999 #define ASC_QSC_NO_TAGMSG   0x02 /* Don't allow tag queuing for request. */
3000 #define ASC_QSC_NO_SYNC     0x04 /* Don't use Synch. transfer on request. */
3001 #define ASC_QSC_NO_WIDE     0x08 /* Don't use Wide transfer on request. */
3002 #define ASC_QSC_REDO_DTR    0x10 /* Renegotiate WDTR/SDTR before request. */
3003 /*
3004  * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
3005  * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
3006  */
3007 #define ASC_QSC_HEAD_TAG    0x40 /* Use Head Tag Message (0x21). */
3008 #define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
3009
3010 /*
3011  * All fields here are accessed by the board microcode and need to be
3012  * little-endian.
3013  */
3014 typedef struct adv_carr_t
3015 {
3016     ADV_VADDR   carr_va;       /* Carrier Virtual Address */
3017     ADV_PADDR   carr_pa;       /* Carrier Physical Address */
3018     ADV_VADDR   areq_vpa;      /* ASC_SCSI_REQ_Q Virtual or Physical Address */
3019     /*
3020      * next_vpa [31:4]            Carrier Virtual or Physical Next Pointer
3021      *
3022      * next_vpa [3:1]             Reserved Bits
3023      * next_vpa [0]               Done Flag set in Response Queue.
3024      */
3025     ADV_VADDR   next_vpa;
3026 } ADV_CARR_T;
3027
3028 /*
3029  * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
3030  */
3031 #define ASC_NEXT_VPA_MASK       0xFFFFFFF0
3032
3033 #define ASC_RQ_DONE             0x00000001
3034 #define ASC_RQ_GOOD             0x00000002
3035 #define ASC_CQ_STOPPER          0x00000000
3036
3037 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
3038
3039 #define ADV_CARRIER_NUM_PAGE_CROSSING \
3040     (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
3041         (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
3042
3043 #define ADV_CARRIER_BUFSIZE \
3044     ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
3045
3046 /*
3047  * ASC_SCSI_REQ_Q 'a_flag' definitions
3048  *
3049  * The Adv Library should limit use to the lower nibble (4 bits) of
3050  * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
3051  */
3052 #define ADV_POLL_REQUEST                0x01   /* poll for request completion */
3053 #define ADV_SCSIQ_DONE                  0x02   /* request done */
3054 #define ADV_DONT_RETRY                  0x08   /* don't do retry */
3055
3056 #define ADV_CHIP_ASC3550          0x01   /* Ultra-Wide IC */
3057 #define ADV_CHIP_ASC38C0800       0x02   /* Ultra2-Wide/LVD IC */
3058 #define ADV_CHIP_ASC38C1600       0x03   /* Ultra3-Wide/LVD2 IC */
3059
3060 /*
3061  * Adapter temporary configuration structure
3062  *
3063  * This structure can be discarded after initialization. Don't add
3064  * fields here needed after initialization.
3065  *
3066  * Field naming convention:
3067  *
3068  *  *_enable indicates the field enables or disables a feature. The
3069  *  value of the field is never reset.
3070  */
3071 typedef struct adv_dvc_cfg {
3072   ushort disc_enable;       /* enable disconnection */
3073   uchar  chip_version;      /* chip version */
3074   uchar  termination;       /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
3075   ushort lib_version;       /* Adv Library version number */
3076   ushort control_flag;      /* Microcode Control Flag */
3077   ushort mcode_date;        /* Microcode date */
3078   ushort mcode_version;     /* Microcode version */
3079   ushort pci_slot_info;     /* high byte device/function number */
3080                             /* bits 7-3 device num., bits 2-0 function num. */
3081                             /* low byte bus num. */
3082   ushort serial1;           /* EEPROM serial number word 1 */
3083   ushort serial2;           /* EEPROM serial number word 2 */
3084   ushort serial3;           /* EEPROM serial number word 3 */
3085   struct pci_dev *pci_dev;  /* pointer to the pci dev structure for this board */
3086 } ADV_DVC_CFG;
3087
3088 struct adv_dvc_var;
3089 struct adv_scsi_req_q;
3090
3091 typedef void (* ADV_ISR_CALLBACK)
3092     (struct adv_dvc_var *, struct adv_scsi_req_q *);
3093
3094 typedef void (* ADV_ASYNC_CALLBACK)
3095     (struct adv_dvc_var *, uchar);
3096
3097 /*
3098  * Adapter operation variable structure.
3099  *
3100  * One structure is required per host adapter.
3101  *
3102  * Field naming convention:
3103  *
3104  *  *_able indicates both whether a feature should be enabled or disabled
3105  *  and whether a device isi capable of the feature. At initialization
3106  *  this field may be set, but later if a device is found to be incapable
3107  *  of the feature, the field is cleared.
3108  */
3109 typedef struct adv_dvc_var {
3110   AdvPortAddr iop_base;   /* I/O port address */
3111   ushort err_code;        /* fatal error code */
3112   ushort bios_ctrl;       /* BIOS control word, EEPROM word 12 */
3113   ADV_ISR_CALLBACK isr_callback;
3114   ADV_ASYNC_CALLBACK async_callback;
3115   ushort wdtr_able;       /* try WDTR for a device */
3116   ushort sdtr_able;       /* try SDTR for a device */
3117   ushort ultra_able;      /* try SDTR Ultra speed for a device */
3118   ushort sdtr_speed1;     /* EEPROM SDTR Speed for TID 0-3   */
3119   ushort sdtr_speed2;     /* EEPROM SDTR Speed for TID 4-7   */
3120   ushort sdtr_speed3;     /* EEPROM SDTR Speed for TID 8-11  */
3121   ushort sdtr_speed4;     /* EEPROM SDTR Speed for TID 12-15 */
3122   ushort tagqng_able;     /* try tagged queuing with a device */
3123   ushort ppr_able;        /* PPR message capable per TID bitmask. */
3124   uchar  max_dvc_qng;     /* maximum number of tagged commands per device */
3125   ushort start_motor;     /* start motor command allowed */
3126   uchar  scsi_reset_wait; /* delay in seconds after scsi bus reset */
3127   uchar  chip_no;         /* should be assigned by caller */
3128   uchar  max_host_qng;    /* maximum number of Q'ed command allowed */
3129   uchar  irq_no;          /* IRQ number */
3130   ushort no_scam;         /* scam_tolerant of EEPROM */
3131   struct asc_board *drv_ptr; /* driver pointer to private structure */
3132   uchar  chip_scsi_id;    /* chip SCSI target ID */
3133   uchar  chip_type;
3134   uchar  bist_err_code;
3135   ADV_CARR_T *carrier_buf;
3136   ADV_CARR_T *carr_freelist; /* Carrier free list. */
3137   ADV_CARR_T *icq_sp;  /* Initiator command queue stopper pointer. */
3138   ADV_CARR_T *irq_sp;  /* Initiator response queue stopper pointer. */
3139   ushort carr_pending_cnt;    /* Count of pending carriers. */
3140  /*
3141   * Note: The following fields will not be used after initialization. The
3142   * driver may discard the buffer after initialization is done.
3143   */
3144   ADV_DVC_CFG *cfg; /* temporary configuration structure  */
3145 } ADV_DVC_VAR;
3146
3147 #define NO_OF_SG_PER_BLOCK              15
3148
3149 typedef struct asc_sg_block {
3150     uchar reserved1;
3151     uchar reserved2;
3152     uchar reserved3;
3153     uchar sg_cnt;                     /* Valid entries in block. */
3154     ADV_PADDR sg_ptr;                 /* Pointer to next sg block. */
3155     struct  {
3156         ADV_PADDR sg_addr;                  /* SG element address. */
3157         ADV_DCNT  sg_count;                 /* SG element count. */
3158     } sg_list[NO_OF_SG_PER_BLOCK];
3159 } ADV_SG_BLOCK;
3160
3161 /*
3162  * ADV_SCSI_REQ_Q - microcode request structure
3163  *
3164  * All fields in this structure up to byte 60 are used by the microcode.
3165  * The microcode makes assumptions about the size and ordering of fields
3166  * in this structure. Do not change the structure definition here without
3167  * coordinating the change with the microcode.
3168  *
3169  * All fields accessed by microcode must be maintained in little_endian
3170  * order.
3171  */
3172 typedef struct adv_scsi_req_q {
3173     uchar       cntl;           /* Ucode flags and state (ASC_MC_QC_*). */
3174     uchar       target_cmd;
3175     uchar       target_id;      /* Device target identifier. */
3176     uchar       target_lun;     /* Device target logical unit number. */
3177     ADV_PADDR   data_addr;      /* Data buffer physical address. */
3178     ADV_DCNT    data_cnt;       /* Data count. Ucode sets to residual. */
3179     ADV_PADDR   sense_addr;
3180     ADV_PADDR   carr_pa;
3181     uchar       mflag;
3182     uchar       sense_len;
3183     uchar       cdb_len;        /* SCSI CDB length. Must <= 16 bytes. */
3184     uchar       scsi_cntl;
3185     uchar       done_status;    /* Completion status. */
3186     uchar       scsi_status;    /* SCSI status byte. */
3187     uchar       host_status;    /* Ucode host status. */
3188     uchar       sg_working_ix;
3189     uchar       cdb[12];        /* SCSI CDB bytes 0-11. */
3190     ADV_PADDR   sg_real_addr;   /* SG list physical address. */
3191     ADV_PADDR   scsiq_rptr;
3192     uchar       cdb16[4];       /* SCSI CDB bytes 12-15. */
3193     ADV_VADDR   scsiq_ptr;
3194     ADV_VADDR   carr_va;
3195     /*
3196      * End of microcode structure - 60 bytes. The rest of the structure
3197      * is used by the Adv Library and ignored by the microcode.
3198      */
3199     ADV_VADDR   srb_ptr;
3200     ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
3201     char        *vdata_addr;   /* Data buffer virtual address. */
3202     uchar       a_flag;
3203     uchar       pad[2];        /* Pad out to a word boundary. */
3204 } ADV_SCSI_REQ_Q;
3205
3206 /*
3207  * Microcode idle loop commands
3208  */
3209 #define IDLE_CMD_COMPLETED           0
3210 #define IDLE_CMD_STOP_CHIP           0x0001
3211 #define IDLE_CMD_STOP_CHIP_SEND_INT  0x0002
3212 #define IDLE_CMD_SEND_INT            0x0004
3213 #define IDLE_CMD_ABORT               0x0008
3214 #define IDLE_CMD_DEVICE_RESET        0x0010
3215 #define IDLE_CMD_SCSI_RESET_START    0x0020 /* Assert SCSI Bus Reset */
3216 #define IDLE_CMD_SCSI_RESET_END      0x0040 /* Deassert SCSI Bus Reset */
3217 #define IDLE_CMD_SCSIREQ             0x0080
3218
3219 #define IDLE_CMD_STATUS_SUCCESS      0x0001
3220 #define IDLE_CMD_STATUS_FAILURE      0x0002
3221
3222 /*
3223  * AdvSendIdleCmd() flag definitions.
3224  */
3225 #define ADV_NOWAIT     0x01
3226
3227 /*
3228  * Wait loop time out values.
3229  */
3230 #define SCSI_WAIT_10_SEC             10UL    /* 10 seconds */
3231 #define SCSI_WAIT_100_MSEC           100UL   /* 100 milliseconds */
3232 #define SCSI_US_PER_MSEC             1000    /* microseconds per millisecond */
3233 #define SCSI_MS_PER_SEC              1000UL  /* milliseconds per second */
3234 #define SCSI_MAX_RETRY               10      /* retry count */
3235
3236 #define ADV_ASYNC_RDMA_FAILURE          0x01 /* Fatal RDMA failure. */
3237 #define ADV_ASYNC_SCSI_BUS_RESET_DET    0x02 /* Detected SCSI Bus Reset. */
3238 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
3239 #define ADV_RDMA_IN_CARR_AND_Q_INVALID  0x04 /* RDMAed-in data invalid. */
3240
3241
3242 #define ADV_HOST_SCSI_BUS_RESET      0x80 /* Host Initiated SCSI Bus Reset. */
3243
3244 /*
3245  * Device drivers must define the following functions.
3246  */
3247 STATIC inline ulong DvcEnterCritical(void);
3248 STATIC inline void  DvcLeaveCritical(ulong);
3249 STATIC void  DvcSleepMilliSecond(ADV_DCNT);
3250 STATIC uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
3251 STATIC void  DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
3252 STATIC ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
3253                 uchar *, ASC_SDCNT *, int);
3254 STATIC void  DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
3255
3256 /*
3257  * Adv Library functions available to drivers.
3258  */
3259 STATIC int     AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3260 STATIC int     AdvISR(ADV_DVC_VAR *);
3261 STATIC int     AdvInitGetConfig(ADV_DVC_VAR *);
3262 STATIC int     AdvInitAsc3550Driver(ADV_DVC_VAR *);
3263 STATIC int     AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
3264 STATIC int     AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
3265 STATIC int     AdvResetChipAndSB(ADV_DVC_VAR *);
3266 STATIC int     AdvResetSB(ADV_DVC_VAR *asc_dvc);
3267
3268 /*
3269  * Internal Adv Library functions.
3270  */
3271 STATIC int    AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
3272 STATIC void   AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3273 STATIC int    AdvInitFrom3550EEP(ADV_DVC_VAR *);
3274 STATIC int    AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
3275 STATIC int    AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
3276 STATIC ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3277 STATIC void   AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3278 STATIC ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3279 STATIC void   AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3280 STATIC ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3281 STATIC void   AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3282 STATIC void   AdvWaitEEPCmd(AdvPortAddr);
3283 STATIC ushort AdvReadEEPWord(AdvPortAddr, int);
3284
3285 /*
3286  * PCI Bus Definitions
3287  */
3288 #define AscPCICmdRegBits_BusMastering     0x0007
3289 #define AscPCICmdRegBits_ParErrRespCtrl   0x0040
3290
3291 /* Read byte from a register. */
3292 #define AdvReadByteRegister(iop_base, reg_off) \
3293      (ADV_MEM_READB((iop_base) + (reg_off)))
3294
3295 /* Write byte to a register. */
3296 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
3297      (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3298
3299 /* Read word (2 bytes) from a register. */
3300 #define AdvReadWordRegister(iop_base, reg_off) \
3301      (ADV_MEM_READW((iop_base) + (reg_off)))
3302
3303 /* Write word (2 bytes) to a register. */
3304 #define AdvWriteWordRegister(iop_base, reg_off, word) \
3305      (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
3306
3307 /* Write dword (4 bytes) to a register. */
3308 #define AdvWriteDWordRegister(iop_base, reg_off, dword) \
3309      (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
3310
3311 /* Read byte from LRAM. */
3312 #define AdvReadByteLram(iop_base, addr, byte) \
3313 do { \
3314     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3315     (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3316 } while (0)
3317
3318 /* Write byte to LRAM. */
3319 #define AdvWriteByteLram(iop_base, addr, byte) \
3320     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3321      ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3322
3323 /* Read word (2 bytes) from LRAM. */
3324 #define AdvReadWordLram(iop_base, addr, word) \
3325 do { \
3326     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3327     (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3328 } while (0)
3329
3330 /* Write word (2 bytes) to LRAM. */
3331 #define AdvWriteWordLram(iop_base, addr, word) \
3332     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3333      ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3334
3335 /* Write little-endian double word (4 bytes) to LRAM */
3336 /* Because of unspecified C language ordering don't use auto-increment. */
3337 #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
3338     ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3339       ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3340                      cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3341      (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3342       ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3343                      cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3344
3345 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
3346 #define AdvReadWordAutoIncLram(iop_base) \
3347      (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3348
3349 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
3350 #define AdvWriteWordAutoIncLram(iop_base, word) \
3351      (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3352
3353
3354 /*
3355  * Define macro to check for Condor signature.
3356  *
3357  * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3358  * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3359  */
3360 #define AdvFindSignature(iop_base) \
3361     (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3362     ADV_CHIP_ID_BYTE) && \
3363      (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3364     ADV_CHIP_ID_WORD)) ?  ADV_TRUE : ADV_FALSE)
3365
3366 /*
3367  * Define macro to Return the version number of the chip at 'iop_base'.
3368  *
3369  * The second parameter 'bus_type' is currently unused.
3370  */
3371 #define AdvGetChipVersion(iop_base, bus_type) \
3372     AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3373
3374 /*
3375  * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3376  * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3377  *
3378  * If the request has not yet been sent to the device it will simply be
3379  * aborted from RISC memory. If the request is disconnected it will be
3380  * aborted on reselection by sending an Abort Message to the target ID.
3381  *
3382  * Return value:
3383  *      ADV_TRUE(1) - Queue was successfully aborted.
3384  *      ADV_FALSE(0) - Queue was not found on the active queue list.
3385  */
3386 #define AdvAbortQueue(asc_dvc, scsiq) \
3387         AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3388                        (ADV_DCNT) (scsiq))
3389
3390 /*
3391  * Send a Bus Device Reset Message to the specified target ID.
3392  *
3393  * All outstanding commands will be purged if sending the
3394  * Bus Device Reset Message is successful.
3395  *
3396  * Return Value:
3397  *      ADV_TRUE(1) - All requests on the target are purged.
3398  *      ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3399  *                     are not purged.
3400  */
3401 #define AdvResetDevice(asc_dvc, target_id) \
3402         AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3403                     (ADV_DCNT) (target_id))
3404
3405 /*
3406  * SCSI Wide Type definition.
3407  */
3408 #define ADV_SCSI_BIT_ID_TYPE   ushort
3409
3410 /*
3411  * AdvInitScsiTarget() 'cntl_flag' options.
3412  */
3413 #define ADV_SCAN_LUN           0x01
3414 #define ADV_CAPINFO_NOLUN      0x02
3415
3416 /*
3417  * Convert target id to target id bit mask.
3418  */
3419 #define ADV_TID_TO_TIDMASK(tid)   (0x01 << ((tid) & ADV_MAX_TID))
3420
3421 /*
3422  * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3423  */
3424
3425 #define QD_NO_STATUS         0x00       /* Request not completed yet. */
3426 #define QD_NO_ERROR          0x01
3427 #define QD_ABORTED_BY_HOST   0x02
3428 #define QD_WITH_ERROR        0x04
3429
3430 #define QHSTA_NO_ERROR              0x00
3431 #define QHSTA_M_SEL_TIMEOUT         0x11
3432 #define QHSTA_M_DATA_OVER_RUN       0x12
3433 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3434 #define QHSTA_M_QUEUE_ABORTED       0x15
3435 #define QHSTA_M_SXFR_SDMA_ERR       0x16 /* SXFR_STATUS SCSI DMA Error */
3436 #define QHSTA_M_SXFR_SXFR_PERR      0x17 /* SXFR_STATUS SCSI Bus Parity Error */
3437 #define QHSTA_M_RDMA_PERR           0x18 /* RISC PCI DMA parity error */
3438 #define QHSTA_M_SXFR_OFF_UFLW       0x19 /* SXFR_STATUS Offset Underflow */
3439 #define QHSTA_M_SXFR_OFF_OFLW       0x20 /* SXFR_STATUS Offset Overflow */
3440 #define QHSTA_M_SXFR_WD_TMO         0x21 /* SXFR_STATUS Watchdog Timeout */
3441 #define QHSTA_M_SXFR_DESELECTED     0x22 /* SXFR_STATUS Deselected */
3442 /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
3443 #define QHSTA_M_SXFR_XFR_OFLW       0x12 /* SXFR_STATUS Transfer Overflow */
3444 #define QHSTA_M_SXFR_XFR_PH_ERR     0x24 /* SXFR_STATUS Transfer Phase Error */
3445 #define QHSTA_M_SXFR_UNKNOWN_ERROR  0x25 /* SXFR_STATUS Unknown Error */
3446 #define QHSTA_M_SCSI_BUS_RESET      0x30 /* Request aborted from SBR */
3447 #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
3448 #define QHSTA_M_BUS_DEVICE_RESET    0x32 /* Request aborted from BDR */
3449 #define QHSTA_M_DIRECTION_ERR       0x35 /* Data Phase mismatch */
3450 #define QHSTA_M_DIRECTION_ERR_HUNG  0x36 /* Data Phase mismatch and bus hang */
3451 #define QHSTA_M_WTM_TIMEOUT         0x41
3452 #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
3453 #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
3454 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
3455 #define QHSTA_M_INVALID_DEVICE      0x45 /* Bad target ID */
3456 #define QHSTA_M_FROZEN_TIDQ         0x46 /* TID Queue frozen. */
3457 #define QHSTA_M_SGBACKUP_ERROR      0x47 /* Scatter-Gather backup error */
3458
3459
3460 /*
3461  * Default EEPROM Configuration structure defined in a_init.c.
3462  */
3463 extern ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
3464 extern ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
3465 extern ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
3466
3467 /*
3468  * DvcGetPhyAddr() flag arguments
3469  */
3470 #define ADV_IS_SCSIQ_FLAG       0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
3471 #define ADV_ASCGETSGLIST_VADDR  0x02 /* 'addr' is AscGetSGList() virtual addr */
3472 #define ADV_IS_SENSE_FLAG       0x04 /* 'addr' is sense virtual pointer */
3473 #define ADV_IS_DATA_FLAG        0x08 /* 'addr' is data virtual pointer */
3474 #define ADV_IS_SGLIST_FLAG      0x10 /* 'addr' is sglist virtual pointer */
3475 #define ADV_IS_CARRIER_FLAG     0x20 /* 'addr' is ADV_CARR_T pointer */
3476
3477 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
3478 #define ADV_8BALIGN(addr)      (((ulong) (addr) + 0x7) & ~0x7)
3479 #define ADV_16BALIGN(addr)     (((ulong) (addr) + 0xF) & ~0xF)
3480 #define ADV_32BALIGN(addr)     (((ulong) (addr) + 0x1F) & ~0x1F)
3481
3482 /*
3483  * Total contiguous memory needed for driver SG blocks.
3484  *
3485  * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3486  * number of scatter-gather elements the driver supports in a
3487  * single request.
3488  */
3489
3490 #define ADV_SG_LIST_MAX_BYTE_SIZE \
3491          (sizeof(ADV_SG_BLOCK) * \
3492           ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3493
3494 /*
3495  * Inquiry data structure and bitfield macros
3496  *
3497  * Using bitfields to access the subchar data isn't portable across
3498  * endianness, so instead mask and shift. Only quantities of more
3499  * than 1 bit are shifted, since the others are just tested for true
3500  * or false.
3501  */
3502
3503 #define ADV_INQ_DVC_TYPE(inq)       ((inq)->periph & 0x1f)
3504 #define ADV_INQ_QUALIFIER(inq)      (((inq)->periph & 0xe0) >> 5)
3505 #define ADV_INQ_DVC_TYPE_MOD(inq)   ((inq)->devtype & 0x7f)
3506 #define ADV_INQ_REMOVABLE(inq)      ((inq)->devtype & 0x80)
3507 #define ADV_INQ_ANSI_VER(inq)       ((inq)->ver & 0x07)
3508 #define ADV_INQ_ECMA_VER(inq)       (((inq)->ver & 0x38) >> 3)
3509 #define ADV_INQ_ISO_VER(inq)        (((inq)->ver & 0xc0) >> 6)
3510 #define ADV_INQ_RESPONSE_FMT(inq)   ((inq)->byte3 & 0x0f)
3511 #define ADV_INQ_TERM_IO(inq)        ((inq)->byte3 & 0x40)
3512 #define ADV_INQ_ASYNC_NOTIF(inq)    ((inq)->byte3 & 0x80)
3513 #define ADV_INQ_SOFT_RESET(inq)     ((inq)->flags & 0x01)
3514 #define ADV_INQ_CMD_QUEUE(inq)      ((inq)->flags & 0x02)
3515 #define ADV_INQ_LINK_CMD(inq)       ((inq)->flags & 0x08)
3516 #define ADV_INQ_SYNC(inq)           ((inq)->flags & 0x10)
3517 #define ADV_INQ_WIDE16(inq)         ((inq)->flags & 0x20)
3518 #define ADV_INQ_WIDE32(inq)         ((inq)->flags & 0x40)
3519 #define ADV_INQ_REL_ADDR(inq)       ((inq)->flags & 0x80)
3520 #define ADV_INQ_INFO_UNIT(inq)      ((inq)->info & 0x01)
3521 #define ADV_INQ_QUICK_ARB(inq)      ((inq)->info & 0x02)
3522 #define ADV_INQ_CLOCKING(inq)       (((inq)->info & 0x0c) >> 2)
3523
3524 typedef struct {
3525   uchar periph;                 /* peripheral device type [0:4] */
3526                                 /* peripheral qualifier [5:7] */
3527   uchar devtype;                /* device type modifier (for SCSI I) [0:6] */
3528                                 /* RMB - removable medium bit [7] */
3529   uchar ver;                    /* ANSI approved version [0:2] */
3530                                 /* ECMA version [3:5] */
3531                                 /* ISO version [6:7] */
3532   uchar byte3;                  /* response data format [0:3] */
3533                                 /* 0 SCSI 1 */
3534                                 /* 1 CCS */
3535                                 /* 2 SCSI-2 */
3536                                 /* 3-F reserved */
3537                                 /* reserved [4:5] */
3538                                 /* terminate I/O process bit (see 5.6.22) [6] */
3539                                 /* asynch. event notification (processor) [7] */
3540   uchar add_len;                /* additional length */
3541   uchar res1;                   /* reserved */
3542   uchar res2;                   /* reserved */
3543   uchar flags;                  /* soft reset implemented [0] */
3544                                 /* command queuing [1] */
3545                                 /* reserved [2] */
3546                                 /* linked command for this logical unit [3] */
3547                                 /* synchronous data transfer [4] */
3548                                 /* wide bus 16 bit data transfer [5] */
3549                                 /* wide bus 32 bit data transfer [6] */
3550                                 /* relative addressing mode [7] */
3551   uchar vendor_id[8];           /* vendor identification */
3552   uchar product_id[16];         /* product identification */
3553   uchar product_rev_level[4];   /* product revision level */
3554   uchar vendor_specific[20];    /* vendor specific */
3555   uchar info;                   /* information unit supported [0] */
3556                                 /* quick arbitrate supported [1] */
3557                                 /* clocking field [2:3] */
3558                                 /* reserved [4:7] */
3559   uchar res3;                   /* reserved */
3560 } ADV_SCSI_INQUIRY; /* 58 bytes */
3561
3562
3563 /*
3564  * --- Driver Constants and Macros
3565  */
3566
3567 #define ASC_NUM_BOARD_SUPPORTED 16
3568 #define ASC_NUM_IOPORT_PROBE    4
3569 #define ASC_NUM_BUS             4
3570
3571 /* Reference Scsi_Host hostdata */
3572 #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3573
3574 /* asc_board_t flags */
3575 #define ASC_HOST_IN_RESET       0x01
3576 #define ASC_IS_WIDE_BOARD       0x04    /* AdvanSys Wide Board */
3577 #define ASC_SELECT_QUEUE_DEPTHS 0x08
3578
3579 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3580 #define ASC_WIDE_BOARD(boardp)   ((boardp)->flags & ASC_IS_WIDE_BOARD)
3581
3582 #define NO_ISA_DMA              0xff        /* No ISA DMA Channel Used */
3583
3584 /*
3585  * If the Linux kernel version supports freeing initialization code
3586  * and data after loading, define macros for this purpose. These macros
3587  * are not used when the driver is built as a module, cf. linux/init.h.
3588  */
3589 #if ASC_LINUX_KERNEL24
3590 #define ASC_INITFUNC(type, func)        type __init func
3591 #elif ASC_LINUX_KERNEL22
3592 #define ASC_INITFUNC(type, func)        __initfunc(type func)
3593 #endif
3594 #define ASC_INITDATA                    __initdata
3595 #define ASC_INIT                        __init
3596
3597 #define ASC_INFO_SIZE           128            /* advansys_info() line size */
3598
3599 #ifdef CONFIG_PROC_FS
3600 /* /proc/scsi/advansys/[0...] related definitions */
3601 #define ASC_PRTBUF_SIZE         2048
3602 #define ASC_PRTLINE_SIZE        160
3603
3604 #define ASC_PRT_NEXT() \
3605     if (cp) { \
3606         totlen += len; \
3607         leftlen -= len; \
3608         if (leftlen == 0) { \
3609             return totlen; \
3610         } \
3611         cp += len; \
3612     }
3613
3614 #define ASC_MIN(a, b) (((a) < (b)) ? (a) : (b))
3615 #endif /* CONFIG_PROC_FS */
3616
3617 /* Asc Library return codes */
3618 #define ASC_TRUE        1
3619 #define ASC_FALSE       0
3620 #define ASC_NOERROR     1
3621 #define ASC_BUSY        0
3622 #define ASC_ERROR       (-1)
3623
3624 /* Scsi_Cmnd function return codes */
3625 #define STATUS_BYTE(byte)   (byte)
3626 #define MSG_BYTE(byte)      ((byte) << 8)
3627 #define HOST_BYTE(byte)     ((byte) << 16)
3628 #define DRIVER_BYTE(byte)   ((byte) << 24)
3629
3630 /*
3631  * The following definitions and macros are OS independent interfaces to
3632  * the queue functions:
3633  *  REQ - SCSI request structure
3634  *  REQP - pointer to SCSI request structure
3635  *  REQPTID(reqp) - reqp's target id
3636  *  REQPNEXT(reqp) - reqp's next pointer
3637  *  REQPNEXTP(reqp) - pointer to reqp's next pointer
3638  *  REQPTIME(reqp) - reqp's time stamp value
3639  *  REQTIMESTAMP() - system time stamp value
3640  */
3641 typedef Scsi_Cmnd            REQ, *REQP;
3642 #define REQPNEXT(reqp)       ((REQP) ((reqp)->host_scribble))
3643 #define REQPNEXTP(reqp)      ((REQP *) &((reqp)->host_scribble))
3644 #define REQPTID(reqp)        ((reqp)->device->id)
3645 #define REQPTIME(reqp)       ((reqp)->SCp.this_residual)
3646 #define REQTIMESTAMP()       (jiffies)
3647
3648 #define REQTIMESTAT(function, ascq, reqp, tid) \
3649 { \
3650     /*
3651      * If the request time stamp is less than the system time stamp, then \
3652      * maybe the system time stamp wrapped. Set the request time to zero.\
3653      */ \
3654     if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3655         REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3656     } else { \
3657         /* Indicate an error occurred with the assertion. */ \
3658         ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3659         REQPTIME(reqp) = 0; \
3660     } \
3661     /* Handle first minimum time case without external initialization. */ \
3662     if (((ascq)->q_tot_cnt[tid] == 1) ||  \
3663         (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3664             (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3665             ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3666                 (function), (tid), (ascq)->q_min_tim[tid]); \
3667         } \
3668     if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3669         (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3670         ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3671             (function), tid, (ascq)->q_max_tim[tid]); \
3672     } \
3673     (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3674     /* Reset the time stamp field. */ \
3675     REQPTIME(reqp) = 0; \
3676 }
3677
3678 /* asc_enqueue() flags */
3679 #define ASC_FRONT       1
3680 #define ASC_BACK        2
3681
3682 /* asc_dequeue_list() argument */
3683 #define ASC_TID_ALL        (-1)
3684
3685 /* Return non-zero, if the queue is empty. */
3686 #define ASC_QUEUE_EMPTY(ascq)    ((ascq)->q_tidmask == 0)
3687
3688 /* PCI configuration declarations */
3689
3690 #define PCI_BASE_CLASS_PREDEFINED               0x00
3691 #define PCI_BASE_CLASS_MASS_STORAGE             0x01
3692 #define PCI_BASE_CLASS_NETWORK                  0x02
3693 #define PCI_BASE_CLASS_DISPLAY                  0x03
3694 #define PCI_BASE_CLASS_MULTIMEDIA               0x04
3695 #define PCI_BASE_CLASS_MEMORY_CONTROLLER        0x05
3696 #define PCI_BASE_CLASS_BRIDGE_DEVICE            0x06
3697
3698 /* MASS STORAGE */
3699 #define PCI_SUB_CLASS_SCSI_CONTROLLER           0x00
3700 #define PCI_SUB_CLASS_IDE_CONTROLLER            0x01
3701 #define PCI_SUB_CLASS_FLOPPY_DISK_CONTROLLER    0x02
3702 #define PCI_SUB_CLASS_IPI_BUS_CONTROLLER        0x03
3703 #define PCI_SUB_CLASS_OTHER_MASS_CONTROLLER     0x80
3704
3705 /* NETWORK CONTROLLER */
3706 #define PCI_SUB_CLASS_ETHERNET_CONTROLLER       0x00
3707 #define PCI_SUB_CLASS_TOKEN_RING_CONTROLLER     0x01
3708 #define PCI_SUB_CLASS_FDDI_CONTROLLER           0x02
3709 #define PCI_SUB_CLASS_OTHER_NETWORK_CONTROLLER  0x80
3710
3711 /* DISPLAY CONTROLLER */
3712 #define PCI_SUB_CLASS_VGA_CONTROLLER            0x00
3713 #define PCI_SUB_CLASS_XGA_CONTROLLER            0x01
3714 #define PCI_SUB_CLASS_OTHER_DISPLAY_CONTROLLER  0x80
3715
3716 /* MULTIMEDIA CONTROLLER */
3717 #define PCI_SUB_CLASS_VIDEO_DEVICE              0x00
3718 #define PCI_SUB_CLASS_AUDIO_DEVICE              0x01
3719 #define PCI_SUB_CLASS_OTHER_MULTIMEDIA_DEVICE   0x80
3720
3721 /* MEMORY CONTROLLER */
3722 #define PCI_SUB_CLASS_RAM_CONTROLLER            0x00
3723 #define PCI_SUB_CLASS_FLASH_CONTROLLER          0x01
3724 #define PCI_SUB_CLASS_OTHER_MEMORY_CONTROLLER   0x80
3725
3726 /* BRIDGE CONTROLLER */
3727 #define PCI_SUB_CLASS_HOST_BRIDGE_CONTROLLER    0x00
3728 #define PCI_SUB_CLASS_ISA_BRIDGE_CONTROLLER     0x01
3729 #define PCI_SUB_CLASS_EISA_BRIDGE_CONTROLLER    0x02
3730 #define PCI_SUB_CLASS_MC_BRIDGE_CONTROLLER      0x03
3731 #define PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER    0x04
3732 #define PCI_SUB_CLASS_PCMCIA_BRIDGE_CONTROLLER  0x05
3733 #define PCI_SUB_CLASS_OTHER_BRIDGE_CONTROLLER   0x80
3734
3735 #define PCI_MAX_SLOT            0x1F
3736 #define PCI_MAX_BUS             0xFF
3737 #define PCI_IOADDRESS_MASK      0xFFFE
3738 #define ASC_PCI_VENDORID        0x10CD
3739 #define ASC_PCI_DEVICE_ID_CNT   6       /* PCI Device ID count. */
3740 #define ASC_PCI_DEVICE_ID_1100  0x1100
3741 #define ASC_PCI_DEVICE_ID_1200  0x1200
3742 #define ASC_PCI_DEVICE_ID_1300  0x1300
3743 #define ASC_PCI_DEVICE_ID_2300  0x2300  /* ASC-3550 */
3744 #define ASC_PCI_DEVICE_ID_2500  0x2500  /* ASC-38C0800 */
3745 #define ASC_PCI_DEVICE_ID_2700  0x2700  /* ASC-38C1600 */
3746
3747 /* PCI IO Port Addresses to generate special cycle */
3748
3749 #define PCI_CONFIG_ADDRESS_MECH1          0x0CF8
3750 #define PCI_CONFIG_DATA_MECH1             0x0CFC
3751
3752 #define PCI_CONFIG_FORWARD_REGISTER       0x0CFA    /* 0=type 0; 1=type 1; */
3753
3754 #define PCI_CONFIG_BUS_NUMBER_MASK        0x00FF0000
3755 #define PCI_CONFIG_DEVICE_FUNCTION_MASK   0x0000FF00
3756 #define PCI_CONFIG_REGISTER_NUMBER_MASK   0x000000F8
3757
3758 #define PCI_DEVICE_FOUND                0x0000
3759 #define PCI_DEVICE_NOT_FOUND            0xffff
3760
3761 #define SUBCLASS_OFFSET         0x0A
3762 #define CLASSCODE_OFFSET        0x0B
3763 #define VENDORID_OFFSET         0x00
3764 #define DEVICEID_OFFSET         0x02
3765
3766 #ifndef ADVANSYS_STATS
3767 #define ASC_STATS(shp, counter)
3768 #define ASC_STATS_ADD(shp, counter, count)
3769 #else /* ADVANSYS_STATS */
3770 #define ASC_STATS(shp, counter) \
3771     (ASC_BOARDP(shp)->asc_stats.counter++)
3772
3773 #define ASC_STATS_ADD(shp, counter, count) \
3774     (ASC_BOARDP(shp)->asc_stats.counter += (count))
3775 #endif /* ADVANSYS_STATS */
3776
3777 #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3778
3779 /* If the result wraps when calculating tenths, return 0. */
3780 #define ASC_TENTHS(num, den) \
3781     (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3782     0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3783
3784 /*
3785  * Display a message to the console.
3786  */
3787 #define ASC_PRINT(s) \
3788     { \
3789         printk("advansys: "); \
3790         printk(s); \
3791     }
3792
3793 #define ASC_PRINT1(s, a1) \
3794     { \
3795         printk("advansys: "); \
3796         printk((s), (a1)); \
3797     }
3798
3799 #define ASC_PRINT2(s, a1, a2) \
3800     { \
3801         printk("advansys: "); \
3802         printk((s), (a1), (a2)); \
3803     }
3804
3805 #define ASC_PRINT3(s, a1, a2, a3) \
3806     { \
3807         printk("advansys: "); \
3808         printk((s), (a1), (a2), (a3)); \
3809     }
3810
3811 #define ASC_PRINT4(s, a1, a2, a3, a4) \
3812     { \
3813         printk("advansys: "); \
3814         printk((s), (a1), (a2), (a3), (a4)); \
3815     }
3816
3817
3818 #ifndef ADVANSYS_DEBUG
3819
3820 #define ASC_DBG(lvl, s)
3821 #define ASC_DBG1(lvl, s, a1)
3822 #define ASC_DBG2(lvl, s, a1, a2)
3823 #define ASC_DBG3(lvl, s, a1, a2, a3)
3824 #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3825 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3826 #define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3827 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3828 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3829 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3830 #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3831 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
3832 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
3833 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
3834 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3835
3836 #else /* ADVANSYS_DEBUG */
3837
3838 /*
3839  * Debugging Message Levels:
3840  * 0: Errors Only
3841  * 1: High-Level Tracing
3842  * 2-N: Verbose Tracing
3843  */
3844
3845 #define ASC_DBG(lvl, s) \
3846     { \
3847         if (asc_dbglvl >= (lvl)) { \
3848             printk(s); \
3849         } \
3850     }
3851
3852 #define ASC_DBG1(lvl, s, a1) \
3853     { \
3854         if (asc_dbglvl >= (lvl)) { \
3855             printk((s), (a1)); \
3856         } \
3857     }
3858
3859 #define ASC_DBG2(lvl, s, a1, a2) \
3860     { \
3861         if (asc_dbglvl >= (lvl)) { \
3862             printk((s), (a1), (a2)); \
3863         } \
3864     }
3865
3866 #define ASC_DBG3(lvl, s, a1, a2, a3) \
3867     { \
3868         if (asc_dbglvl >= (lvl)) { \
3869             printk((s), (a1), (a2), (a3)); \
3870         } \
3871     }
3872
3873 #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3874     { \
3875         if (asc_dbglvl >= (lvl)) { \
3876             printk((s), (a1), (a2), (a3), (a4)); \
3877         } \
3878     }
3879
3880 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3881     { \
3882         if (asc_dbglvl >= (lvl)) { \
3883             asc_prt_scsi_host(s); \
3884         } \
3885     }
3886
3887 #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3888     { \
3889         if (asc_dbglvl >= (lvl)) { \
3890             asc_prt_scsi_cmnd(s); \
3891         } \
3892     }
3893
3894 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3895     { \
3896         if (asc_dbglvl >= (lvl)) { \
3897             asc_prt_asc_scsi_q(scsiqp); \
3898         } \
3899     }
3900
3901 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3902     { \
3903         if (asc_dbglvl >= (lvl)) { \
3904             asc_prt_asc_qdone_info(qdone); \
3905         } \
3906     }
3907
3908 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3909     { \
3910         if (asc_dbglvl >= (lvl)) { \
3911             asc_prt_adv_scsi_req_q(scsiqp); \
3912         } \
3913     }
3914
3915 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3916     { \
3917         if (asc_dbglvl >= (lvl)) { \
3918             asc_prt_hex((name), (start), (length)); \
3919         } \
3920     }
3921
3922 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3923         ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3924
3925 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3926         ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3927
3928 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3929         ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3930 #endif /* ADVANSYS_DEBUG */
3931
3932 #ifndef ADVANSYS_ASSERT
3933 #define ASC_ASSERT(a)
3934 #else /* ADVANSYS_ASSERT */
3935
3936 #define ASC_ASSERT(a) \
3937     { \
3938         if (!(a)) { \
3939             printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3940                 __FILE__, __LINE__); \
3941         } \
3942     }
3943
3944 #endif /* ADVANSYS_ASSERT */
3945
3946
3947 /*
3948  * --- Driver Structures
3949  */
3950
3951 #ifdef ADVANSYS_STATS
3952
3953 /* Per board statistics structure */
3954 struct asc_stats {
3955     /* Driver Entrypoint Statistics */
3956     ADV_DCNT queuecommand;    /* # calls to advansys_queuecommand() */
3957     ADV_DCNT reset;           /* # calls to advansys_eh_bus_reset() */
3958     ADV_DCNT biosparam;       /* # calls to advansys_biosparam() */
3959     ADV_DCNT interrupt;       /* # advansys_interrupt() calls */
3960     ADV_DCNT callback;        /* # calls to asc/adv_isr_callback() */
3961     ADV_DCNT done;            /* # calls to request's scsi_done function */
3962     ADV_DCNT build_error;     /* # asc/adv_build_req() ASC_ERROR returns. */
3963     ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
3964     ADV_DCNT adv_build_nosg;  /* # adv_build_req() adv_sgblk_t alloc. fail. */
3965     /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3966     ADV_DCNT exe_noerror;     /* # ASC_NOERROR returns. */
3967     ADV_DCNT exe_busy;        /* # ASC_BUSY returns. */
3968     ADV_DCNT exe_error;       /* # ASC_ERROR returns. */
3969     ADV_DCNT exe_unknown;     /* # unknown returns. */
3970     /* Data Transfer Statistics */
3971     ADV_DCNT cont_cnt;        /* # non-scatter-gather I/O requests received */
3972     ADV_DCNT cont_xfer;       /* # contiguous transfer 512-bytes */
3973     ADV_DCNT sg_cnt;          /* # scatter-gather I/O requests received */
3974     ADV_DCNT sg_elem;         /* # scatter-gather elements */
3975     ADV_DCNT sg_xfer;         /* # scatter-gather transfer 512-bytes */
3976 };
3977 #endif /* ADVANSYS_STATS */
3978
3979 /*
3980  * Request queuing structure
3981  */
3982 typedef struct asc_queue {
3983     ADV_SCSI_BIT_ID_TYPE  q_tidmask;                /* queue mask */
3984     REQP                  q_first[ADV_MAX_TID+1];   /* first queued request */
3985     REQP                  q_last[ADV_MAX_TID+1];    /* last queued request */
3986 #ifdef ADVANSYS_STATS
3987     short                 q_cur_cnt[ADV_MAX_TID+1]; /* current queue count */
3988     short                 q_max_cnt[ADV_MAX_TID+1]; /* maximum queue count */
3989     ADV_DCNT              q_tot_cnt[ADV_MAX_TID+1]; /* total enqueue count */
3990     ADV_DCNT              q_tot_tim[ADV_MAX_TID+1]; /* total time queued */
3991     ushort                q_max_tim[ADV_MAX_TID+1]; /* maximum time queued */
3992     ushort                q_min_tim[ADV_MAX_TID+1]; /* minimum time queued */
3993 #endif /* ADVANSYS_STATS */
3994 } asc_queue_t;
3995
3996 /*
3997  * Adv Library Request Structures
3998  *
3999  * The following two structures are used to process Wide Board requests.
4000  *
4001  * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
4002  * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
4003  * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
4004  * Mid-Level SCSI request structure.
4005  *
4006  * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
4007  * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
4008  * up to 255 scatter-gather elements may be used per request or
4009  * ADV_SCSI_REQ_Q.
4010  *
4011  * Both structures must be 32 byte aligned.
4012  */
4013 typedef struct adv_sgblk {
4014     ADV_SG_BLOCK        sg_block;     /* Sgblock structure. */
4015     uchar               align[32];    /* Sgblock structure padding. */
4016     struct adv_sgblk    *next_sgblkp; /* Next scatter-gather structure. */
4017 } adv_sgblk_t;
4018
4019 typedef struct adv_req {
4020     ADV_SCSI_REQ_Q      scsi_req_q;   /* Adv Library request structure. */
4021     uchar               align[32];    /* Request structure padding. */
4022     Scsi_Cmnd           *cmndp;       /* Mid-Level SCSI command pointer. */
4023     adv_sgblk_t         *sgblkp;      /* Adv Library scatter-gather pointer. */
4024     struct adv_req      *next_reqp;   /* Next Request Structure. */
4025 } adv_req_t;
4026
4027 /*
4028  * Structure allocated for each board.
4029  *
4030  * This structure is allocated by scsi_register() at the end
4031  * of the 'Scsi_Host' structure starting at the 'hostdata'
4032  * field. It is guaranteed to be allocated from DMA-able memory.
4033  */
4034 typedef struct asc_board {
4035     int                  id;                    /* Board Id */
4036     uint                 flags;                 /* Board flags */
4037     union {
4038         ASC_DVC_VAR      asc_dvc_var;           /* Narrow board */
4039         ADV_DVC_VAR      adv_dvc_var;           /* Wide board */
4040     } dvc_var;
4041     union {
4042         ASC_DVC_CFG      asc_dvc_cfg;           /* Narrow board */
4043         ADV_DVC_CFG      adv_dvc_cfg;           /* Wide board */
4044     } dvc_cfg;
4045     ushort               asc_n_io_port;         /* Number I/O ports. */
4046     asc_queue_t          active;                /* Active command queue */
4047     asc_queue_t          waiting;               /* Waiting command queue */
4048     asc_queue_t          done;                  /* Done command queue */
4049     ADV_SCSI_BIT_ID_TYPE init_tidmask;          /* Target init./valid mask */
4050     Scsi_Device          *device[ADV_MAX_TID+1]; /* Mid-Level Scsi Device */
4051     ushort               reqcnt[ADV_MAX_TID+1]; /* Starvation request count */
4052     ADV_SCSI_BIT_ID_TYPE queue_full;            /* Queue full mask */
4053     ushort               queue_full_cnt[ADV_MAX_TID+1]; /* Queue full count */
4054     union {
4055         ASCEEP_CONFIG         asc_eep;          /* Narrow EEPROM config. */
4056         ADVEEP_3550_CONFIG    adv_3550_eep;     /* 3550 EEPROM config. */
4057         ADVEEP_38C0800_CONFIG adv_38C0800_eep;  /* 38C0800 EEPROM config. */
4058         ADVEEP_38C1600_CONFIG adv_38C1600_eep;  /* 38C1600 EEPROM config. */
4059     } eep_config;
4060     ulong                last_reset;            /* Saved last reset time */
4061     spinlock_t lock;                            /* Board spinlock */
4062 #ifdef CONFIG_PROC_FS
4063     /* /proc/scsi/advansys/[0...] */
4064     char                 *prtbuf;               /* /proc print buffer */
4065 #endif /* CONFIG_PROC_FS */
4066 #ifdef ADVANSYS_STATS
4067     struct asc_stats     asc_stats;             /* Board statistics */
4068 #endif /* ADVANSYS_STATS */
4069     /*
4070      * The following fields are used only for Narrow Boards.
4071      */
4072     /* The following three structures must be in DMA-able memory. */
4073     ASC_SCSI_REQ_Q       scsireqq;
4074     ASC_CAP_INFO         cap_info;
4075     ASC_SCSI_INQUIRY     inquiry;
4076     uchar                sdtr_data[ASC_MAX_TID+1]; /* SDTR information */
4077     /*
4078      * The following fields are used only for Wide Boards.
4079      */
4080     void                 *ioremap_addr;         /* I/O Memory remap address. */
4081     ushort               ioport;                /* I/O Port address. */
4082     ADV_CARR_T           *orig_carrp;           /* ADV_CARR_T memory block. */
4083     adv_req_t            *orig_reqp;            /* adv_req_t memory block. */
4084     adv_req_t            *adv_reqp;             /* Request structures. */
4085     adv_sgblk_t          *adv_sgblkp;           /* Scatter-gather structures. */
4086     ushort               bios_signature;        /* BIOS Signature. */
4087     ushort               bios_version;          /* BIOS Version. */
4088     ushort               bios_codeseg;          /* BIOS Code Segment. */
4089     ushort               bios_codelen;          /* BIOS Code Segment Length. */
4090 } asc_board_t;
4091
4092 /*
4093  * PCI configuration structures
4094  */
4095 typedef struct _PCI_DATA_
4096 {
4097     uchar    type;
4098     uchar    bus;
4099     uchar    slot;
4100     uchar    func;
4101     uchar    offset;
4102 } PCI_DATA;
4103
4104 typedef struct _PCI_DEVICE_
4105 {
4106     ushort   vendorID;
4107     ushort   deviceID;
4108     ushort   slotNumber;
4109     ushort   slotFound;
4110     uchar    busNumber;
4111     uchar    maxBusNumber;
4112     uchar    devFunc;
4113     ushort   startSlot;
4114     ushort   endSlot;
4115     uchar    bridge;
4116     uchar    type;
4117 } PCI_DEVICE;
4118
4119 typedef struct _PCI_CONFIG_SPACE_
4120 {
4121     ushort   vendorID;
4122     ushort   deviceID;
4123     ushort   command;
4124     ushort   status;
4125     uchar    revision;
4126     uchar    classCode[3];
4127     uchar    cacheSize;
4128     uchar    latencyTimer;
4129     uchar    headerType;
4130     uchar    bist;
4131     ADV_PADDR baseAddress[6];
4132     ushort   reserved[4];
4133     ADV_PADDR optionRomAddr;
4134     ushort   reserved2[4];
4135     uchar    irqLine;
4136     uchar    irqPin;
4137     uchar    minGnt;
4138     uchar    maxLatency;
4139 } PCI_CONFIG_SPACE;
4140
4141
4142 /*
4143  * --- Driver Data
4144  */
4145
4146 /* Note: All driver global data should be initialized. */
4147
4148 #if ASC_LINUX_KERNEL22
4149 #ifdef CONFIG_PROC_FS
4150 struct proc_dir_entry proc_scsi_advansys =
4151 {
4152     PROC_SCSI_ADVANSYS,              /* unsigned short low_ino */
4153     8,                               /* unsigned short namelen */
4154     "advansys",                      /* const char *name */
4155     S_IFDIR | S_IRUGO | S_IXUGO,     /* mode_t mode */
4156     2                                /* nlink_t nlink */
4157 };
4158 #endif /* CONFIG_PROC_FS */
4159 #endif /* ASC_LINUX_KERNEL22 */
4160
4161 /* Number of boards detected in system. */
4162 STATIC int asc_board_count = 0;
4163 STATIC struct Scsi_Host    *asc_host[ASC_NUM_BOARD_SUPPORTED] = { 0 };
4164
4165 /* Overrun buffer used by all narrow boards. */
4166 STATIC uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
4167
4168 /*
4169  * Global structures required to issue a command.
4170  */
4171 STATIC ASC_SCSI_Q asc_scsi_q = { { 0 } };
4172 STATIC ASC_SG_HEAD asc_sg_head = { 0 };
4173
4174 /* List of supported bus types. */
4175 STATIC ushort asc_bus[ASC_NUM_BUS] ASC_INITDATA = {
4176     ASC_IS_ISA,
4177     ASC_IS_VL,
4178     ASC_IS_EISA,
4179     ASC_IS_PCI,
4180 };
4181
4182 /*
4183  * Used with the LILO 'advansys' option to eliminate or
4184  * limit I/O port probing at boot time, cf. advansys_setup().
4185  */
4186 STATIC int asc_iopflag = ASC_FALSE;
4187 STATIC int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
4188
4189 #ifdef ADVANSYS_DEBUG
4190 STATIC char *
4191 asc_bus_name[ASC_NUM_BUS] = {
4192     "ASC_IS_ISA",
4193     "ASC_IS_VL",
4194     "ASC_IS_EISA",
4195     "ASC_IS_PCI",
4196 };
4197
4198 STATIC int          asc_dbglvl = 3;
4199 #endif /* ADVANSYS_DEBUG */
4200
4201 /* Declaration for Asc Library internal data referenced by driver. */
4202 STATIC PortAddr     _asc_def_iop_base[];
4203
4204
4205 /*
4206  * --- Driver Function Prototypes
4207  *
4208  * advansys.h contains function prototypes for functions global to Linux.
4209  */
4210
4211 STATIC irqreturn_t advansys_interrupt(int, void *, struct pt_regs *);
4212 STATIC int        advansys_slave_configure(Scsi_Device *);
4213 STATIC void       asc_scsi_done_list(Scsi_Cmnd *, int from_isr);
4214 STATIC int        asc_execute_scsi_cmnd(Scsi_Cmnd *);
4215 STATIC int        asc_build_req(asc_board_t *, Scsi_Cmnd *);
4216 STATIC int        adv_build_req(asc_board_t *, Scsi_Cmnd *, ADV_SCSI_REQ_Q **);
4217 STATIC int        adv_get_sglist(asc_board_t *, adv_req_t *, Scsi_Cmnd *);
4218 STATIC void       asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
4219 STATIC void       adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
4220 STATIC void       adv_async_callback(ADV_DVC_VAR *, uchar);
4221 STATIC void       asc_enqueue(asc_queue_t *, REQP, int);
4222 STATIC REQP       asc_dequeue(asc_queue_t *, int);
4223 STATIC REQP       asc_dequeue_list(asc_queue_t *, REQP *, int);
4224 STATIC int        asc_rmqueue(asc_queue_t *, REQP);
4225 STATIC void       asc_execute_queue(asc_queue_t *);
4226 #ifdef CONFIG_PROC_FS
4227 STATIC int        asc_proc_copy(off_t, off_t, char *, int , char *, int);
4228 STATIC int        asc_prt_board_devices(struct Scsi_Host *, char *, int);
4229 STATIC int        asc_prt_adv_bios(struct Scsi_Host *, char *, int);
4230 STATIC int        asc_get_eeprom_string(ushort *serialnum, uchar *cp);
4231 STATIC int        asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
4232 STATIC int        asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
4233 STATIC int        asc_prt_driver_conf(struct Scsi_Host *, char *, int);
4234 STATIC int        asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
4235 STATIC int        asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
4236 STATIC int        asc_prt_line(char *, int, char *fmt, ...);
4237 #endif /* CONFIG_PROC_FS */
4238
4239 /* Declaration for Asc Library internal functions referenced by driver. */
4240 STATIC int          AscFindSignature(PortAddr);
4241 STATIC ushort       AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
4242
4243 /* Statistics function prototypes. */
4244 #ifdef ADVANSYS_STATS
4245 #ifdef CONFIG_PROC_FS
4246 STATIC int          asc_prt_board_stats(struct Scsi_Host *, char *, int);
4247 STATIC int          asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
4248 #endif /* CONFIG_PROC_FS */
4249 #endif /* ADVANSYS_STATS */
4250
4251 /* Debug function prototypes. */
4252 #ifdef ADVANSYS_DEBUG
4253 STATIC void         asc_prt_scsi_host(struct Scsi_Host *);
4254 STATIC void         asc_prt_scsi_cmnd(Scsi_Cmnd *);
4255 STATIC void         asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
4256 STATIC void         asc_prt_asc_dvc_var(ASC_DVC_VAR *);
4257 STATIC void         asc_prt_asc_scsi_q(ASC_SCSI_Q *);
4258 STATIC void         asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
4259 STATIC void         asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
4260 STATIC void         asc_prt_adv_dvc_var(ADV_DVC_VAR *);
4261 STATIC void         asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
4262 STATIC void         asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
4263 STATIC void         asc_prt_hex(char *f, uchar *, int);
4264 #endif /* ADVANSYS_DEBUG */
4265
4266
4267 /*
4268  * --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
4269  */
4270
4271 #ifdef CONFIG_PROC_FS
4272 /*
4273  * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
4274  *
4275  * *buffer: I/O buffer
4276  * **start: if inout == FALSE pointer into buffer where user read should start
4277  * offset: current offset into a /proc/scsi/advansys/[0...] file
4278  * length: length of buffer
4279  * hostno: Scsi_Host host_no
4280  * inout: TRUE - user is writing; FALSE - user is reading
4281  *
4282  * Return the number of bytes read from or written to a
4283  * /proc/scsi/advansys/[0...] file.
4284  *
4285  * Note: This function uses the per board buffer 'prtbuf' which is
4286  * allocated when the board is initialized in advansys_detect(). The
4287  * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
4288  * used to write to the buffer. The way asc_proc_copy() is written
4289  * if 'prtbuf' is too small it will not be overwritten. Instead the
4290  * user just won't get all the available statistics.
4291  */
4292 int
4293 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
4294                 off_t offset, int length, int inout)
4295 {
4296     struct Scsi_Host    *shp;
4297     asc_board_t         *boardp;
4298     int                 i;
4299     char                *cp;
4300     int                 cplen;
4301     int                 cnt;
4302     int                 totcnt;
4303     int                 leftlen;
4304     char                *curbuf;
4305     off_t               advoffset;
4306 #ifdef ADVANSYS_STATS
4307     int                 tgt_id;
4308 #endif /* ADVANSYS_STATS */
4309
4310     ASC_DBG(1, "advansys_proc_info: begin\n");
4311
4312     /*
4313      * User write not supported.
4314      */
4315     if (inout == TRUE) {
4316         return(-ENOSYS);
4317     }
4318
4319     /*
4320      * User read of /proc/scsi/advansys/[0...] file.
4321      */
4322
4323     /* Find the specified board. */
4324     for (i = 0; i < asc_board_count; i++) {
4325         if (asc_host[i]->host_no == shost->host_no) {
4326             break;
4327         }
4328     }
4329     if (i == asc_board_count) {
4330         return(-ENOENT);
4331     }
4332
4333     shp = asc_host[i];
4334     boardp = ASC_BOARDP(shp);
4335
4336     /* Copy read data starting at the beginning of the buffer. */
4337     *start = buffer;
4338     curbuf = buffer;
4339     advoffset = 0;
4340     totcnt = 0;
4341     leftlen = length;
4342
4343     /*
4344      * Get board configuration information.
4345      *
4346      * advansys_info() returns the board string from its own static buffer.
4347      */
4348     cp = (char *) advansys_info(shp);
4349     strcat(cp, "\n");
4350     cplen = strlen(cp);
4351     /* Copy board information. */
4352     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4353     totcnt += cnt;
4354     leftlen -= cnt;
4355     if (leftlen == 0) {
4356         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4357         return totcnt;
4358     }
4359     advoffset += cplen;
4360     curbuf += cnt;
4361
4362     /*
4363      * Display Wide Board BIOS Information.
4364      */
4365     if (ASC_WIDE_BOARD(boardp)) {
4366         cp = boardp->prtbuf;
4367         cplen = asc_prt_adv_bios(shp, cp, ASC_PRTBUF_SIZE);
4368         ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4369         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4370         totcnt += cnt;
4371         leftlen -= cnt;
4372         if (leftlen == 0) {
4373             ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4374             return totcnt;
4375         }
4376         advoffset += cplen;
4377         curbuf += cnt;
4378     }
4379
4380     /*
4381      * Display driver information for each device attached to the board.
4382      */
4383     cp = boardp->prtbuf;
4384     cplen = asc_prt_board_devices(shp, cp, ASC_PRTBUF_SIZE);
4385     ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4386     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4387     totcnt += cnt;
4388     leftlen -= cnt;
4389     if (leftlen == 0) {
4390         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4391         return totcnt;
4392     }
4393     advoffset += cplen;
4394     curbuf += cnt;
4395
4396     /*
4397      * Display EEPROM configuration for the board.
4398      */
4399     cp = boardp->prtbuf;
4400     if (ASC_NARROW_BOARD(boardp)) {
4401         cplen = asc_prt_asc_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4402     } else {
4403         cplen = asc_prt_adv_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4404     }
4405     ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4406     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4407     totcnt += cnt;
4408     leftlen -= cnt;
4409     if (leftlen == 0) {
4410         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4411         return totcnt;
4412     }
4413     advoffset += cplen;
4414     curbuf += cnt;
4415
4416     /*
4417      * Display driver configuration and information for the board.
4418      */
4419     cp = boardp->prtbuf;
4420     cplen = asc_prt_driver_conf(shp, cp, ASC_PRTBUF_SIZE);
4421     ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4422     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4423     totcnt += cnt;
4424     leftlen -= cnt;
4425     if (leftlen == 0) {
4426         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4427         return totcnt;
4428     }
4429     advoffset += cplen;
4430     curbuf += cnt;
4431
4432 #ifdef ADVANSYS_STATS
4433     /*
4434      * Display driver statistics for the board.
4435      */
4436     cp = boardp->prtbuf;
4437     cplen = asc_prt_board_stats(shp, cp, ASC_PRTBUF_SIZE);
4438     ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4439     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4440     totcnt += cnt;
4441     leftlen -= cnt;
4442     if (leftlen == 0) {
4443         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4444         return totcnt;
4445     }
4446     advoffset += cplen;
4447     curbuf += cnt;
4448
4449     /*
4450      * Display driver statistics for each target.
4451      */
4452     for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
4453       cp = boardp->prtbuf;
4454       cplen = asc_prt_target_stats(shp, tgt_id, cp, ASC_PRTBUF_SIZE);
4455       ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4456       cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4457       totcnt += cnt;
4458       leftlen -= cnt;
4459       if (leftlen == 0) {
4460         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4461         return totcnt;
4462       }
4463       advoffset += cplen;
4464       curbuf += cnt;
4465     }
4466 #endif /* ADVANSYS_STATS */
4467
4468     /*
4469      * Display Asc Library dynamic configuration information
4470      * for the board.
4471      */
4472     cp = boardp->prtbuf;
4473     if (ASC_NARROW_BOARD(boardp)) {
4474         cplen = asc_prt_asc_board_info(shp, cp, ASC_PRTBUF_SIZE);
4475     } else {
4476         cplen = asc_prt_adv_board_info(shp, cp, ASC_PRTBUF_SIZE);
4477     }
4478     ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4479     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4480     totcnt += cnt;
4481     leftlen -= cnt;
4482     if (leftlen == 0) {
4483         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4484         return totcnt;
4485     }
4486     advoffset += cplen;
4487     curbuf += cnt;
4488
4489     ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4490
4491     return totcnt;
4492 }
4493 #endif /* CONFIG_PROC_FS */
4494
4495 /*
4496  * advansys_detect()
4497  *
4498  * Detect function for AdvanSys adapters.
4499  *
4500  * Argument is a pointer to the host driver's scsi_hosts entry.
4501  *
4502  * Return number of adapters found.
4503  *
4504  * Note: Because this function is called during system initialization
4505  * it must not call SCSI mid-level functions including scsi_malloc()
4506  * and scsi_free().
4507  */
4508 ASC_INITFUNC(
4509 int,
4510 advansys_detect(Scsi_Host_Template *tpnt)
4511 )
4512 {
4513     static int          detect_called = ASC_FALSE;
4514     int                 iop;
4515     int                 bus;
4516     struct Scsi_Host    *shp = NULL;
4517     asc_board_t         *boardp = NULL;
4518     ASC_DVC_VAR         *asc_dvc_varp = NULL;
4519     ADV_DVC_VAR         *adv_dvc_varp = NULL;
4520     adv_sgblk_t         *sgp = NULL;
4521     int                 ioport = 0;
4522     int                 share_irq = FALSE;
4523     int                 iolen = 0;
4524 #ifdef CONFIG_PCI
4525     int                 pci_init_search = 0;
4526     struct pci_dev      *pci_devicep[ASC_NUM_BOARD_SUPPORTED];
4527     int                 pci_card_cnt_max = 0;
4528     int                 pci_card_cnt = 0;
4529     struct pci_dev      *pci_devp = NULL;
4530     int                 pci_device_id_cnt = 0;
4531     unsigned int        pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
4532                                     ASC_PCI_DEVICE_ID_1100,
4533                                     ASC_PCI_DEVICE_ID_1200,
4534                                     ASC_PCI_DEVICE_ID_1300,
4535                                     ASC_PCI_DEVICE_ID_2300,
4536                                     ASC_PCI_DEVICE_ID_2500,
4537                                     ASC_PCI_DEVICE_ID_2700
4538                         };
4539     ADV_PADDR           pci_memory_address;
4540 #endif /* CONFIG_PCI */
4541     int                 warn_code, err_code;
4542     int                 ret;
4543
4544     if (detect_called == ASC_FALSE) {
4545         detect_called = ASC_TRUE;
4546     } else {
4547         printk("AdvanSys SCSI: advansys_detect() multiple calls ignored\n");
4548         return 0;
4549     }
4550
4551     ASC_DBG(1, "advansys_detect: begin\n");
4552
4553 #if ASC_LINUX_KERNEL24
4554     tpnt->proc_name = "advansys";
4555 #elif ASC_LINUX_KERNEL22
4556     tpnt->proc_dir = &proc_scsi_advansys;
4557 #endif
4558
4559     asc_board_count = 0;
4560
4561     /*
4562      * If I/O port probing has been modified, then verify and
4563      * clean-up the 'asc_ioport' list.
4564      */
4565     if (asc_iopflag == ASC_TRUE) {
4566         for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
4567             ASC_DBG2(1, "advansys_detect: asc_ioport[%d] 0x%x\n",
4568                 ioport, asc_ioport[ioport]);
4569             if (asc_ioport[ioport] != 0) {
4570                 for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX; iop++) {
4571                     if (_asc_def_iop_base[iop] == asc_ioport[ioport]) {
4572                         break;
4573                     }
4574                 }
4575                 if (iop == ASC_IOADR_TABLE_MAX_IX) {
4576                     printk(
4577 "AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
4578                         asc_ioport[ioport]);
4579                     asc_ioport[ioport] = 0;
4580                 }
4581             }
4582         }
4583         ioport = 0;
4584     }
4585
4586     for (bus = 0; bus < ASC_NUM_BUS; bus++) {
4587
4588         ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
4589             bus, asc_bus_name[bus]);
4590         iop = 0;
4591
4592         while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) {
4593
4594             ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
4595                 asc_board_count);
4596
4597             switch (asc_bus[bus]) {
4598             case ASC_IS_ISA:
4599             case ASC_IS_VL:
4600 #ifdef CONFIG_ISA
4601                 if (asc_iopflag == ASC_FALSE) {
4602                     iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4603                 } else {
4604                     /*
4605                      * ISA and VL I/O port scanning has either been
4606                      * eliminated or limited to selected ports on
4607                      * the LILO command line, /etc/lilo.conf, or
4608                      * by setting variables when the module was loaded.
4609                      */
4610                     ASC_DBG(1, "advansys_detect: I/O port scanning modified\n");
4611                 ioport_try_again:
4612                     iop = 0;
4613                     for (; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
4614                         if ((iop = asc_ioport[ioport]) != 0) {
4615                             break;
4616                         }
4617                     }
4618                     if (iop) {
4619                         ASC_DBG1(1,
4620                                 "advansys_detect: probing I/O port 0x%x...\n",
4621                             iop);
4622                         if (check_region(iop, ASC_IOADR_GAP) != 0) {
4623                             printk(
4624 "AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop);
4625                             /* Don't try this I/O port twice. */
4626                             asc_ioport[ioport] = 0;
4627                             goto ioport_try_again;
4628                         } else if (AscFindSignature(iop) == ASC_FALSE) {
4629                             printk(
4630 "AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop);
4631                             /* Don't try this I/O port twice. */
4632                             asc_ioport[ioport] = 0;
4633                             goto ioport_try_again;
4634                         } else {
4635                             /*
4636                              * If this isn't an ISA board, then it must be
4637                              * a VL board. If currently looking an ISA
4638                              * board is being looked for then try for
4639                              * another ISA board in 'asc_ioport'.
4640                              */
4641                             if (asc_bus[bus] == ASC_IS_ISA &&
4642                                 (AscGetChipVersion(iop, ASC_IS_ISA) &
4643                                  ASC_CHIP_VER_ISA_BIT) == 0) {
4644                                  /*
4645                                   * Don't clear 'asc_ioport[ioport]'. Try
4646                                   * this board again for VL. Increment
4647                                   * 'ioport' past this board.
4648                                   */
4649                                  ioport++;
4650                                  goto ioport_try_again;
4651                             }
4652                         }
4653                         /*
4654                          * This board appears good, don't try the I/O port
4655                          * again by clearing its value. Increment 'ioport'
4656                          * for the next iteration.
4657                          */
4658                         asc_ioport[ioport++] = 0;
4659                     }
4660                 }
4661 #endif /* CONFIG_ISA */
4662                 break;
4663
4664             case ASC_IS_EISA:
4665 #ifdef CONFIG_ISA
4666                 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4667 #endif /* CONFIG_ISA */
4668                 break;
4669
4670             case ASC_IS_PCI:
4671 #ifdef CONFIG_PCI
4672                 if (pci_init_search == 0) {
4673                     int i, j;
4674
4675                     pci_init_search = 1;
4676
4677                     /* Find all PCI cards. */
4678                     while (pci_device_id_cnt < ASC_PCI_DEVICE_ID_CNT) {
4679                         if ((pci_devp = pci_find_device(ASC_PCI_VENDORID,
4680                             pci_device_id[pci_device_id_cnt], pci_devp)) ==
4681                             NULL) {
4682                             pci_device_id_cnt++;
4683                         } else {
4684 #if ASC_LINUX_KERNEL24
4685                             if (pci_enable_device(pci_devp) == 0) {
4686                                 pci_devicep[pci_card_cnt_max++] = pci_devp;
4687                             }
4688 #elif ASC_LINUX_KERNEL22
4689                             pci_devicep[pci_card_cnt_max++] = pci_devp;
4690 #endif
4691                         }
4692                     }
4693
4694                     /*
4695                      * Sort PCI cards in ascending order by PCI Bus, Slot,
4696                      * and Device Number.
4697                      */
4698                     for (i = 0; i < pci_card_cnt_max - 1; i++)
4699                     {
4700                         for (j = i + 1; j < pci_card_cnt_max; j++) {
4701                             if ((pci_devicep[j]->bus->number <
4702                                  pci_devicep[i]->bus->number) ||
4703                                 ((pci_devicep[j]->bus->number ==
4704                                   pci_devicep[i]->bus->number) &&
4705                                   (pci_devicep[j]->devfn <
4706                                    pci_devicep[i]->devfn))) {
4707                                 pci_devp = pci_devicep[i];
4708                                 pci_devicep[i] = pci_devicep[j];
4709                                 pci_devicep[j] = pci_devp;
4710                             }
4711                         }
4712                     }
4713
4714                     pci_card_cnt = 0;
4715                 } else {
4716                     pci_card_cnt++;
4717                 }
4718
4719                 if (pci_card_cnt == pci_card_cnt_max) {
4720                     iop = 0;
4721                 } else {
4722                     pci_devp = pci_devicep[pci_card_cnt];
4723
4724                     ASC_DBG2(2,
4725                         "advansys_detect: devfn %d, bus number %d\n",
4726                         pci_devp->devfn, pci_devp->bus->number);
4727 #if ASC_LINUX_KERNEL24
4728                     iop = pci_resource_start(pci_devp, 0);
4729 #elif ASC_LINUX_KERNEL22
4730                     iop = pci_devp->base_address[0] & PCI_IOADDRESS_MASK;
4731 #endif
4732                     ASC_DBG2(1,
4733                         "advansys_detect: vendorID %X, deviceID %X\n",
4734                         pci_devp->vendor, pci_devp->device);
4735                     ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
4736                         iop, pci_devp->irq);
4737                 }
4738 #endif /* CONFIG_PCI */
4739                 break;
4740
4741             default:
4742                 ASC_PRINT1("advansys_detect: unknown bus type: %d\n",
4743                     asc_bus[bus]);
4744                 break;
4745             }
4746             ASC_DBG1(1, "advansys_detect: iop 0x%x\n", iop);
4747
4748             /*
4749              * Adapter not found, try next bus type.
4750              */
4751             if (iop == 0) {
4752                 break;
4753             }
4754
4755             /*
4756              * Adapter found.
4757              *
4758              * Register the adapter, get its configuration, and
4759              * initialize it.
4760              */
4761             ASC_DBG(2, "advansys_detect: scsi_register()\n");
4762             shp = scsi_register(tpnt, sizeof(asc_board_t));
4763
4764             if (shp == NULL) {
4765                 continue;
4766             }
4767
4768             scsi_set_device(shp, &pci_devp->dev);
4769
4770             /* Save a pointer to the Scsi_Host of each board found. */
4771             asc_host[asc_board_count++] = shp;
4772
4773             /* Initialize private per board data */
4774             boardp = ASC_BOARDP(shp);
4775             memset(boardp, 0, sizeof(asc_board_t));
4776             boardp->id = asc_board_count - 1;
4777
4778             /* Initialize spinlock. */
4779             boardp->lock = SPIN_LOCK_UNLOCKED;
4780
4781             /*
4782              * Handle both narrow and wide boards.
4783              *
4784              * If a Wide board was detected, set the board structure
4785              * wide board flag. Set-up the board structure based on
4786              * the board type.
4787              */
4788 #ifdef CONFIG_PCI
4789             if (asc_bus[bus] == ASC_IS_PCI &&
4790                 (pci_devp->device == ASC_PCI_DEVICE_ID_2300 ||
4791                  pci_devp->device == ASC_PCI_DEVICE_ID_2500 ||
4792                  pci_devp->device == ASC_PCI_DEVICE_ID_2700))
4793             {
4794                 boardp->flags |= ASC_IS_WIDE_BOARD;
4795             }
4796 #endif /* CONFIG_PCI */
4797
4798             if (ASC_NARROW_BOARD(boardp)) {
4799                 ASC_DBG(1, "advansys_detect: narrow board\n");
4800                 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4801                 asc_dvc_varp->bus_type = asc_bus[bus];
4802                 asc_dvc_varp->drv_ptr = boardp;
4803                 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
4804                 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
4805                 asc_dvc_varp->iop_base = iop;
4806                 asc_dvc_varp->isr_callback = asc_isr_callback;
4807             } else {
4808                 ASC_DBG(1, "advansys_detect: wide board\n");
4809                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4810                 adv_dvc_varp->drv_ptr = boardp;
4811                 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
4812                 adv_dvc_varp->isr_callback = adv_isr_callback;
4813                 adv_dvc_varp->async_callback = adv_async_callback;
4814 #ifdef CONFIG_PCI
4815                 if (pci_devp->device == ASC_PCI_DEVICE_ID_2300)
4816                 {
4817                     ASC_DBG(1, "advansys_detect: ASC-3550\n");
4818                     adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
4819                 } else if (pci_devp->device == ASC_PCI_DEVICE_ID_2500)
4820                 {
4821                     ASC_DBG(1, "advansys_detect: ASC-38C0800\n");
4822                     adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
4823                 } else
4824                 {
4825                     ASC_DBG(1, "advansys_detect: ASC-38C1600\n");
4826                     adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
4827                 }
4828 #endif /* CONFIG_PCI */
4829
4830                 /*
4831                  * Map the board's registers into virtual memory for
4832                  * PCI slave access. Only memory accesses are used to
4833                  * access the board's registers.
4834                  *
4835                  * Note: The PCI register base address is not always
4836                  * page aligned, but the address passed to ioremap()
4837                  * must be page aligned. It is guaranteed that the
4838                  * PCI register base address will not cross a page
4839                  * boundary.
4840                  */
4841                 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
4842                 {
4843                     iolen = ADV_3550_IOLEN;
4844                 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
4845                 {
4846                     iolen = ADV_38C0800_IOLEN;
4847                 } else
4848                 {
4849                     iolen = ADV_38C1600_IOLEN;
4850                 }
4851 #ifdef CONFIG_PCI
4852 #if ASC_LINUX_KERNEL24
4853                 pci_memory_address = pci_resource_start(pci_devp, 1);
4854 #elif ASC_LINUX_KERNEL22
4855                 pci_memory_address = pci_devp->base_address[1];
4856 #endif
4857                 ASC_DBG1(1, "advansys_detect: pci_memory_address: 0x%lx\n",
4858                     (ulong) pci_memory_address);
4859                 if ((boardp->ioremap_addr =
4860                     ioremap(pci_memory_address & PAGE_MASK,
4861                          PAGE_SIZE)) == 0) {
4862                    ASC_PRINT3(
4863 "advansys_detect: board %d: ioremap(%x, %d) returned NULL\n",
4864                        boardp->id, pci_memory_address, iolen);
4865                    scsi_unregister(shp);
4866                    asc_board_count--;
4867                    continue;
4868                 }
4869                 ASC_DBG1(1, "advansys_detect: ioremap_addr: 0x%lx\n",
4870                     (ulong) boardp->ioremap_addr);
4871                 adv_dvc_varp->iop_base = (AdvPortAddr)
4872                     (boardp->ioremap_addr +
4873                      (pci_memory_address - (pci_memory_address & PAGE_MASK)));
4874                 ASC_DBG1(1, "advansys_detect: iop_base: 0x%lx\n",
4875                     adv_dvc_varp->iop_base);
4876 #endif /* CONFIG_PCI */
4877
4878                 /*
4879                  * Even though it isn't used to access wide boards, other
4880                  * than for the debug line below, save I/O Port address so
4881                  * that it can be reported.
4882                  */
4883                 boardp->ioport = iop;
4884
4885                 ASC_DBG2(1,
4886 "advansys_detect: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
4887                     (ushort) inp(iop + 1), (ushort) inpw(iop));
4888             }
4889
4890 #ifdef CONFIG_PROC_FS
4891             /*
4892              * Allocate buffer for printing information from
4893              * /proc/scsi/advansys/[0...].
4894              */
4895             if ((boardp->prtbuf =
4896                 kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) {
4897                 ASC_PRINT3(
4898 "advansys_detect: board %d: kmalloc(%d, %d) returned NULL\n",
4899                     boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC);
4900                 scsi_unregister(shp);
4901                 asc_board_count--;
4902                 continue;
4903             }
4904 #endif /* CONFIG_PROC_FS */
4905
4906             if (ASC_NARROW_BOARD(boardp)) {
4907                 /*
4908                  * Set the board bus type and PCI IRQ before
4909                  * calling AscInitGetConfig().
4910                  */
4911                 switch (asc_dvc_varp->bus_type) {
4912 #ifdef CONFIG_ISA
4913                 case ASC_IS_ISA:
4914                     shp->unchecked_isa_dma = TRUE;
4915                     share_irq = FALSE;
4916                     break;
4917                 case ASC_IS_VL:
4918                     shp->unchecked_isa_dma = FALSE;
4919                     share_irq = FALSE;
4920                     break;
4921                 case ASC_IS_EISA:
4922                     shp->unchecked_isa_dma = FALSE;
4923                     share_irq = TRUE;
4924                     break;
4925 #endif /* CONFIG_ISA */
4926 #ifdef CONFIG_PCI
4927                 case ASC_IS_PCI:
4928                     shp->irq = asc_dvc_varp->irq_no = pci_devp->irq;
4929                     asc_dvc_varp->cfg->pci_dev = pci_devp;
4930                     asc_dvc_varp->cfg->pci_slot_info =
4931                         ASC_PCI_MKID(pci_devp->bus->number,
4932                             PCI_SLOT(pci_devp->devfn),
4933                             PCI_FUNC(pci_devp->devfn));
4934                     shp->unchecked_isa_dma = FALSE;
4935                     share_irq = TRUE;
4936                     break;
4937 #endif /* CONFIG_PCI */
4938                 default:
4939                     ASC_PRINT2(
4940 "advansys_detect: board %d: unknown adapter type: %d\n",
4941                         boardp->id, asc_dvc_varp->bus_type);
4942                     shp->unchecked_isa_dma = TRUE;
4943                     share_irq = FALSE;
4944                     break;
4945                 }
4946             } else {
4947                 /*
4948                  * For Wide boards set PCI information before calling
4949                  * AdvInitGetConfig().
4950                  */
4951 #ifdef CONFIG_PCI
4952                 shp->irq = adv_dvc_varp->irq_no = pci_devp->irq;
4953                 adv_dvc_varp->cfg->pci_dev = pci_devp;
4954                 adv_dvc_varp->cfg->pci_slot_info =
4955                     ASC_PCI_MKID(pci_devp->bus->number,
4956                         PCI_SLOT(pci_devp->devfn),
4957                         PCI_FUNC(pci_devp->devfn));
4958                 shp->unchecked_isa_dma = FALSE;
4959                 share_irq = TRUE;
4960 #endif /* CONFIG_PCI */
4961             }
4962
4963             /*
4964              * Read the board configuration.
4965              */
4966             if (ASC_NARROW_BOARD(boardp)) {
4967                  /*
4968                   * NOTE: AscInitGetConfig() may change the board's
4969                   * bus_type value. The asc_bus[bus] value should no
4970                   * longer be used. If the bus_type field must be
4971                   * referenced only use the bit-wise AND operator "&".
4972                   */
4973                 ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
4974                 switch(ret = AscInitGetConfig(asc_dvc_varp)) {
4975                 case 0:    /* No error */
4976                     break;
4977                 case ASC_WARN_IO_PORT_ROTATE:
4978                     ASC_PRINT1(
4979 "AscInitGetConfig: board %d: I/O port address modified\n",
4980                         boardp->id);
4981                     break;
4982                 case ASC_WARN_AUTO_CONFIG:
4983                     ASC_PRINT1(
4984 "AscInitGetConfig: board %d: I/O port increment switch enabled\n",
4985                         boardp->id);
4986                     break;
4987                 case ASC_WARN_EEPROM_CHKSUM:
4988                     ASC_PRINT1(
4989 "AscInitGetConfig: board %d: EEPROM checksum error\n",
4990                         boardp->id);
4991                     break;
4992                 case ASC_WARN_IRQ_MODIFIED:
4993                     ASC_PRINT1(
4994 "AscInitGetConfig: board %d: IRQ modified\n",
4995                         boardp->id);
4996                     break;
4997                 case ASC_WARN_CMD_QNG_CONFLICT:
4998                     ASC_PRINT1(
4999 "AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
5000                         boardp->id);
5001                     break;
5002                 default:
5003                     ASC_PRINT2(
5004 "AscInitGetConfig: board %d: unknown warning: 0x%x\n",
5005                         boardp->id, ret);
5006                     break;
5007                 }
5008                 if ((err_code = asc_dvc_varp->err_code) != 0) {
5009                     ASC_PRINT3(
5010 "AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
5011                         boardp->id, asc_dvc_varp->init_state,
5012                         asc_dvc_varp->err_code);
5013                 }
5014             } else {
5015                 ASC_DBG(2, "advansys_detect: AdvInitGetConfig()\n");
5016                 if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
5017                     ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n",
5018                         boardp->id, ret);
5019                 }
5020                 if ((err_code = adv_dvc_varp->err_code) != 0) {
5021                     ASC_PRINT2(
5022 "AdvInitGetConfig: board %d error: err_code 0x%x\n",
5023                         boardp->id, adv_dvc_varp->err_code);
5024                 }
5025             }
5026
5027             if (err_code != 0) {
5028 #ifdef CONFIG_PROC_FS
5029                 kfree(boardp->prtbuf);
5030 #endif /* CONFIG_PROC_FS */
5031                 scsi_unregister(shp);
5032                 asc_board_count--;
5033                 continue;
5034             }
5035
5036             /*
5037              * Save the EEPROM configuration so that it can be displayed
5038              * from /proc/scsi/advansys/[0...].
5039              */
5040             if (ASC_NARROW_BOARD(boardp)) {
5041
5042                 ASCEEP_CONFIG *ep;
5043
5044                 /*
5045                  * Set the adapter's target id bit in the 'init_tidmask' field.
5046                  */
5047                 boardp->init_tidmask |=
5048                     ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
5049
5050                 /*
5051                  * Save EEPROM settings for the board.
5052                  */
5053                 ep = &boardp->eep_config.asc_eep;
5054
5055                 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
5056                 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
5057                 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
5058                 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
5059                 ep->start_motor = asc_dvc_varp->start_motor;
5060                 ep->cntl = asc_dvc_varp->dvc_cntl;
5061                 ep->no_scam = asc_dvc_varp->no_scam;
5062                 ep->max_total_qng = asc_dvc_varp->max_total_qng;
5063                 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
5064                 /* 'max_tag_qng' is set to the same value for every device. */
5065                 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
5066                 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
5067                 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
5068                 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
5069                 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
5070                 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
5071                 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
5072
5073                /*
5074                 * Modify board configuration.
5075                 */
5076                 ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n");
5077                 switch (ret = AscInitSetConfig(asc_dvc_varp)) {
5078                 case 0:    /* No error. */
5079                     break;
5080                 case ASC_WARN_IO_PORT_ROTATE:
5081                     ASC_PRINT1(
5082 "AscInitSetConfig: board %d: I/O port address modified\n",
5083                         boardp->id);
5084                     break;
5085                 case ASC_WARN_AUTO_CONFIG:
5086                     ASC_PRINT1(
5087 "AscInitSetConfig: board %d: I/O port increment switch enabled\n",
5088                         boardp->id);
5089                     break;
5090                 case ASC_WARN_EEPROM_CHKSUM:
5091                     ASC_PRINT1(
5092 "AscInitSetConfig: board %d: EEPROM checksum error\n",
5093                         boardp->id);
5094                     break;
5095                 case ASC_WARN_IRQ_MODIFIED:
5096                     ASC_PRINT1(
5097 "AscInitSetConfig: board %d: IRQ modified\n",
5098                         boardp->id);
5099                     break;
5100                 case ASC_WARN_CMD_QNG_CONFLICT:
5101                     ASC_PRINT1(
5102 "AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
5103                         boardp->id);
5104                     break;
5105                 default:
5106                     ASC_PRINT2(
5107 "AscInitSetConfig: board %d: unknown warning: 0x%x\n",
5108                         boardp->id, ret);
5109                     break;
5110                 }
5111                 if (asc_dvc_varp->err_code != 0) {
5112                     ASC_PRINT3(
5113 "AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
5114                         boardp->id, asc_dvc_varp->init_state,
5115                         asc_dvc_varp->err_code);
5116 #ifdef CONFIG_PROC_FS
5117                     kfree(boardp->prtbuf);
5118 #endif /* CONFIG_PROC_FS */
5119                     scsi_unregister(shp);
5120                     asc_board_count--;
5121                     continue;
5122                 }
5123
5124                 /*
5125                  * Finish initializing the 'Scsi_Host' structure.
5126                  */
5127                 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
5128                 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
5129                     shp->irq = asc_dvc_varp->irq_no;
5130                 }
5131             } else {
5132                 ADVEEP_3550_CONFIG      *ep_3550;
5133                 ADVEEP_38C0800_CONFIG   *ep_38C0800;
5134                 ADVEEP_38C1600_CONFIG   *ep_38C1600;
5135
5136                 /*
5137                  * Save Wide EEP Configuration Information.
5138                  */
5139                 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5140                 {
5141                     ep_3550 = &boardp->eep_config.adv_3550_eep;
5142
5143                     ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
5144                     ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
5145                     ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
5146                     ep_3550->termination = adv_dvc_varp->cfg->termination;
5147                     ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
5148                     ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
5149                     ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
5150                     ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
5151                     ep_3550->ultra_able = adv_dvc_varp->ultra_able;
5152                     ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
5153                     ep_3550->start_motor = adv_dvc_varp->start_motor;
5154                     ep_3550->scsi_reset_delay = adv_dvc_varp->scsi_reset_wait;
5155                     ep_3550->serial_number_word1 =
5156                         adv_dvc_varp->cfg->serial1;
5157                     ep_3550->serial_number_word2 =
5158                         adv_dvc_varp->cfg->serial2;
5159                     ep_3550->serial_number_word3 =
5160                         adv_dvc_varp->cfg->serial3;
5161                 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
5162                 {
5163                     ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
5164
5165                     ep_38C0800->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
5166                     ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
5167                     ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
5168                     ep_38C0800->termination_lvd =
5169                         adv_dvc_varp->cfg->termination;
5170                     ep_38C0800->disc_enable = adv_dvc_varp->cfg->disc_enable;
5171                     ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
5172                     ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
5173                     ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
5174                     ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
5175                     ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
5176                     ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
5177                     ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
5178                     ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
5179                     ep_38C0800->start_motor = adv_dvc_varp->start_motor;
5180                     ep_38C0800->scsi_reset_delay =
5181                         adv_dvc_varp->scsi_reset_wait;
5182                     ep_38C0800->serial_number_word1 =
5183                         adv_dvc_varp->cfg->serial1;
5184                     ep_38C0800->serial_number_word2 =
5185                         adv_dvc_varp->cfg->serial2;
5186                     ep_38C0800->serial_number_word3 =
5187                         adv_dvc_varp->cfg->serial3;
5188                 } else
5189                 {
5190                     ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
5191
5192                     ep_38C1600->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
5193                     ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
5194                     ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
5195                     ep_38C1600->termination_lvd =
5196                         adv_dvc_varp->cfg->termination;
5197                     ep_38C1600->disc_enable = adv_dvc_varp->cfg->disc_enable;
5198                     ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
5199                     ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
5200                     ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
5201                     ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
5202                     ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
5203                     ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
5204                     ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
5205                     ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
5206                     ep_38C1600->start_motor = adv_dvc_varp->start_motor;
5207                     ep_38C1600->scsi_reset_delay =
5208                         adv_dvc_varp->scsi_reset_wait;
5209                     ep_38C1600->serial_number_word1 =
5210                         adv_dvc_varp->cfg->serial1;
5211                     ep_38C1600->serial_number_word2 =
5212                         adv_dvc_varp->cfg->serial2;
5213                     ep_38C1600->serial_number_word3 =
5214                         adv_dvc_varp->cfg->serial3;
5215                 }
5216
5217                 /*
5218                  * Set the adapter's target id bit in the 'init_tidmask' field.
5219                  */
5220                 boardp->init_tidmask |=
5221                     ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
5222
5223                 /*
5224                  * Finish initializing the 'Scsi_Host' structure.
5225                  */
5226                 shp->irq = adv_dvc_varp->irq_no;
5227             }
5228
5229             /*
5230              * Channels are numbered beginning with 0. For AdvanSys one host
5231              * structure supports one channel. Multi-channel boards have a
5232              * separate host structure for each channel.
5233              */
5234             shp->max_channel = 0;
5235             if (ASC_NARROW_BOARD(boardp)) {
5236                 shp->max_id = ASC_MAX_TID + 1;
5237                 shp->max_lun = ASC_MAX_LUN + 1;
5238
5239                 shp->io_port = asc_dvc_varp->iop_base;
5240                 boardp->asc_n_io_port = ASC_IOADR_GAP;
5241                 shp->this_id = asc_dvc_varp->cfg->chip_scsi_id;
5242
5243                 /* Set maximum number of queues the adapter can handle. */
5244                 shp->can_queue = asc_dvc_varp->max_total_qng;
5245             } else {
5246                 shp->max_id = ADV_MAX_TID + 1;
5247                 shp->max_lun = ADV_MAX_LUN + 1;
5248
5249                 /*
5250                  * Save the I/O Port address and length even though
5251                  * I/O ports are not used to access Wide boards.
5252                  * Instead the Wide boards are accessed with
5253                  * PCI Memory Mapped I/O.
5254                  */
5255                 shp->io_port = iop;
5256                 boardp->asc_n_io_port = iolen;
5257
5258                 shp->this_id = adv_dvc_varp->chip_scsi_id;
5259
5260                 /* Set maximum number of queues the adapter can handle. */
5261                 shp->can_queue = adv_dvc_varp->max_host_qng;
5262             }
5263
5264             /*
5265              * 'n_io_port' currently is one byte.
5266              *
5267              * Set a value to 'n_io_port', but never referenced it because
5268              * it may be truncated.
5269              */
5270             shp->n_io_port = boardp->asc_n_io_port <= 255 ?
5271                 boardp->asc_n_io_port : 255;
5272
5273             /*
5274              * Following v1.3.89, 'cmd_per_lun' is no longer needed
5275              * and should be set to zero.
5276              *
5277              * But because of a bug introduced in v1.3.89 if the driver is
5278              * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
5279              * SCSI function 'allocate_device' will panic. To allow the driver
5280              * to work as a module in these kernels set 'cmd_per_lun' to 1.
5281              *
5282              * Note: This is wrong.  cmd_per_lun should be set to the depth
5283              * you want on untagged devices always.
5284 #ifdef MODULE
5285              */
5286             shp->cmd_per_lun = 1;
5287 /* #else
5288             shp->cmd_per_lun = 0;
5289 #endif */
5290
5291             /*
5292              * Set the maximum number of scatter-gather elements the
5293              * adapter can handle.
5294              */
5295             if (ASC_NARROW_BOARD(boardp)) {
5296                 /*
5297                  * Allow two commands with 'sg_tablesize' scatter-gather
5298                  * elements to be executed simultaneously. This value is
5299                  * the theoretical hardware limit. It may be decreased
5300                  * below.
5301                  */
5302                 shp->sg_tablesize =
5303                     (((asc_dvc_varp->max_total_qng - 2) / 2) *
5304                     ASC_SG_LIST_PER_Q) + 1;
5305             } else {
5306                 shp->sg_tablesize = ADV_MAX_SG_LIST;
5307             }
5308
5309             /*
5310              * The value of 'sg_tablesize' can not exceed the SCSI
5311              * mid-level driver definition of SG_ALL. SG_ALL also
5312              * must not be exceeded, because it is used to define the
5313              * size of the scatter-gather table in 'struct asc_sg_head'.
5314              */
5315             if (shp->sg_tablesize > SG_ALL) {
5316                 shp->sg_tablesize = SG_ALL;
5317             }
5318
5319             ASC_DBG1(1, "advansys_detect: sg_tablesize: %d\n",
5320                 shp->sg_tablesize);
5321
5322             /* BIOS start address. */
5323             if (ASC_NARROW_BOARD(boardp)) {
5324 #if ASC_LINUX_KERNEL24
5325                 shp->base =
5326 #elif ASC_LINUX_KERNEL22
5327                 shp->base = (char *)
5328 #endif
5329                         ((ulong) AscGetChipBiosAddress(
5330                             asc_dvc_varp->iop_base,
5331                             asc_dvc_varp->bus_type));
5332             } else {
5333                 /*
5334                  * Fill-in BIOS board variables. The Wide BIOS saves
5335                  * information in LRAM that is used by the driver.
5336                  */
5337                 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_SIGNATURE,
5338                     boardp->bios_signature);
5339                 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_VERSION,
5340                     boardp->bios_version);
5341                 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODESEG,
5342                     boardp->bios_codeseg);
5343                 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODELEN,
5344                     boardp->bios_codelen);
5345
5346                 ASC_DBG2(1,
5347                     "advansys_detect: bios_signature 0x%x, bios_version 0x%x\n",
5348                     boardp->bios_signature, boardp->bios_version);
5349
5350                 ASC_DBG2(1,
5351                     "advansys_detect: bios_codeseg 0x%x, bios_codelen 0x%x\n",
5352                     boardp->bios_codeseg, boardp->bios_codelen);
5353
5354                 /*
5355                  * If the BIOS saved a valid signature, then fill in
5356                  * the BIOS code segment base address.
5357                  */
5358                 if (boardp->bios_signature == 0x55AA) {
5359                     /*
5360                      * Convert x86 realmode code segment to a linear
5361                      * address by shifting left 4.
5362                      */
5363                     shp->base =
5364 #if ASC_LINUX_KERNEL22
5365                         (char *)
5366 #endif
5367                         ((ulong) boardp->bios_codeseg << 4);
5368                 } else {
5369                     shp->base = 0;
5370                 }
5371             }
5372
5373             /*
5374              * Register Board Resources - I/O Port, DMA, IRQ
5375              */
5376
5377             /*
5378              * Register I/O port range.
5379              *
5380              * For Wide boards the I/O ports are not used to access
5381              * the board, but request the region anyway.
5382              *
5383              * 'shp->n_io_port' is not referenced, because it may be truncated.
5384              */
5385             ASC_DBG2(2,
5386                 "advansys_detect: request_region port 0x%lx, len 0x%x\n",
5387                 (ulong) shp->io_port, boardp->asc_n_io_port);
5388 #if ASC_LINUX_KERNEL24
5389             if (request_region(shp->io_port, boardp->asc_n_io_port,
5390                                "advansys") == NULL) {
5391                 ASC_PRINT3(
5392 "advansys_detect: board %d: request_region() failed, port 0x%lx, len 0x%x\n",
5393                     boardp->id, (ulong) shp->io_port, boardp->asc_n_io_port);
5394 #ifdef CONFIG_PROC_FS
5395                 kfree(boardp->prtbuf);
5396 #endif /* CONFIG_PROC_FS */
5397                 scsi_unregister(shp);
5398                 asc_board_count--;
5399                 continue;
5400             }
5401 #elif ASC_LINUX_KERNEL22
5402             request_region(shp->io_port, boardp->asc_n_io_port, "advansys");
5403 #endif
5404
5405             /* Register DMA Channel for Narrow boards. */
5406             shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
5407 #ifdef CONFIG_ISA
5408             if (ASC_NARROW_BOARD(boardp)) {
5409                 /* Register DMA channel for ISA bus. */
5410                 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5411                     shp->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
5412                     if ((ret =
5413                          request_dma(shp->dma_channel, "advansys")) != 0) {
5414                         ASC_PRINT3(
5415 "advansys_detect: board %d: request_dma() %d failed %d\n",
5416                             boardp->id, shp->dma_channel, ret);
5417                         release_region(shp->io_port, boardp->asc_n_io_port);
5418 #ifdef CONFIG_PROC_FS
5419                         kfree(boardp->prtbuf);
5420 #endif /* CONFIG_PROC_FS */
5421                         scsi_unregister(shp);
5422                         asc_board_count--;
5423                         continue;
5424                     }
5425                     AscEnableIsaDma(shp->dma_channel);
5426                 }
5427             }
5428 #endif /* CONFIG_ISA */
5429
5430             /* Register IRQ Number. */
5431             ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
5432            /*
5433             * If request_irq() fails with the SA_INTERRUPT flag set,
5434             * then try again without the SA_INTERRUPT flag set. This
5435             * allows IRQ sharing to work even with other drivers that
5436             * do not set the SA_INTERRUPT flag.
5437             *
5438             * If SA_INTERRUPT is not set, then interrupts are enabled
5439             * before the driver interrupt function is called.
5440             */
5441             if (((ret = request_irq(shp->irq, advansys_interrupt,
5442                             SA_INTERRUPT | (share_irq == TRUE ? SA_SHIRQ : 0),
5443                             "advansys", boardp)) != 0) &&
5444                 ((ret = request_irq(shp->irq, advansys_interrupt,
5445                             (share_irq == TRUE ? SA_SHIRQ : 0),
5446                             "advansys", boardp)) != 0))
5447             {
5448                 if (ret == -EBUSY) {
5449                     ASC_PRINT2(
5450 "advansys_detect: board %d: request_irq(): IRQ 0x%x already in use.\n",
5451                         boardp->id, shp->irq);
5452                 } else if (ret == -EINVAL) {
5453                     ASC_PRINT2(
5454 "advansys_detect: board %d: request_irq(): IRQ 0x%x not valid.\n",
5455                         boardp->id, shp->irq);
5456                 } else {
5457                     ASC_PRINT3(
5458 "advansys_detect: board %d: request_irq(): IRQ 0x%x failed with %d\n",
5459                         boardp->id, shp->irq, ret);
5460                 }
5461                 release_region(shp->io_port, boardp->asc_n_io_port);
5462                 iounmap(boardp->ioremap_addr);
5463                 if (shp->dma_channel != NO_ISA_DMA) {
5464                     free_dma(shp->dma_channel);
5465                 }
5466 #ifdef CONFIG_PROC_FS
5467                 kfree(boardp->prtbuf);
5468 #endif /* CONFIG_PROC_FS */
5469                 scsi_unregister(shp);
5470                 asc_board_count--;
5471                 continue;
5472             }
5473
5474             /*
5475              * Initialize board RISC chip and enable interrupts.
5476              */
5477             if (ASC_NARROW_BOARD(boardp)) {
5478                 ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n");
5479                 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
5480                 err_code = asc_dvc_varp->err_code;
5481
5482                 if (warn_code || err_code) {
5483                     ASC_PRINT4(
5484 "advansys_detect: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
5485                         boardp->id, asc_dvc_varp->init_state,
5486                         warn_code, err_code);
5487                 }
5488             } else {
5489                 ADV_CARR_T      *carrp;
5490                 int             req_cnt = 0;
5491                 adv_req_t       *reqp = NULL;
5492                 int             sg_cnt = 0;
5493
5494                 /*
5495                  * Allocate buffer carrier structures. The total size
5496                  * is about 4 KB, so allocate all at once.
5497                  */
5498                 carrp =
5499                     (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC);
5500                 ASC_DBG1(1, "advansys_detect: carrp 0x%lx\n", (ulong) carrp);
5501
5502                 if (carrp == NULL) {
5503                     goto kmalloc_error;
5504                 }
5505
5506                 /*
5507                  * Allocate up to 'max_host_qng' request structures for
5508                  * the Wide board. The total size is about 16 KB, so
5509                  * allocate all at once. If the allocation fails decrement
5510                  * and try again.
5511                  */
5512                 for (req_cnt = adv_dvc_varp->max_host_qng;
5513                     req_cnt > 0; req_cnt--) {
5514
5515                     reqp = (adv_req_t *)
5516                         kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC);
5517
5518                     ASC_DBG3(1,
5519                         "advansys_detect: reqp 0x%lx, req_cnt %d, bytes %lu\n",
5520                         (ulong) reqp, req_cnt,
5521                         (ulong) sizeof(adv_req_t) * req_cnt);
5522
5523                     if (reqp != NULL) {
5524                         break;
5525                     }
5526                 }
5527                 if (reqp == NULL)
5528                 {
5529                     goto kmalloc_error;
5530                 }
5531
5532                 /*
5533                  * Allocate up to ADV_TOT_SG_BLOCK request structures for
5534                  * the Wide board. Each structure is about 136 bytes.
5535                  */
5536                 boardp->adv_sgblkp = NULL;
5537                 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
5538
5539                     sgp = (adv_sgblk_t *)
5540                         kmalloc(sizeof(adv_sgblk_t), GFP_ATOMIC);
5541
5542                     if (sgp == NULL) {
5543                         break;
5544                     }
5545
5546                     sgp->next_sgblkp = boardp->adv_sgblkp;
5547                     boardp->adv_sgblkp = sgp;
5548
5549                 }
5550                 ASC_DBG3(1,
5551                     "advansys_detect: sg_cnt %d * %u = %u bytes\n",
5552                     sg_cnt, sizeof(adv_sgblk_t),
5553                     (unsigned) (sizeof(adv_sgblk_t) * sg_cnt));
5554
5555                 /*
5556                  * If no request structures or scatter-gather structures could
5557                  * be allocated, then return an error. Otherwise continue with
5558                  * initialization.
5559                  */
5560     kmalloc_error:
5561                 if (carrp == NULL)
5562                 {
5563                     ASC_PRINT1(
5564 "advansys_detect: board %d error: failed to kmalloc() carrier buffer.\n",
5565                         boardp->id);
5566                     err_code = ADV_ERROR;
5567                 } else if (reqp == NULL) {
5568                     kfree(carrp);
5569                     ASC_PRINT1(
5570 "advansys_detect: board %d error: failed to kmalloc() adv_req_t buffer.\n",
5571                         boardp->id);
5572                     err_code = ADV_ERROR;
5573                 } else if (boardp->adv_sgblkp == NULL) {
5574                     kfree(carrp);
5575                     kfree(reqp);
5576                     ASC_PRINT1(
5577 "advansys_detect: board %d error: failed to kmalloc() adv_sgblk_t buffers.\n",
5578                         boardp->id);
5579                     err_code = ADV_ERROR;
5580                 } else {
5581
5582                     /* Save carrier buffer pointer. */
5583                     boardp->orig_carrp = carrp;
5584
5585                     /*
5586                      * Save original pointer for kfree() in case the
5587                      * driver is built as a module and can be unloaded.
5588                      */
5589                     boardp->orig_reqp = reqp;
5590
5591                     adv_dvc_varp->carrier_buf = carrp;
5592
5593                     /*
5594                      * Point 'adv_reqp' to the request structures and
5595                      * link them together.
5596                      */
5597                     req_cnt--;
5598                     reqp[req_cnt].next_reqp = NULL;
5599                     for (; req_cnt > 0; req_cnt--) {
5600                         reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
5601                     }
5602                     boardp->adv_reqp = &reqp[0];
5603
5604                     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5605                     {
5606                         ASC_DBG(2,
5607                             "advansys_detect: AdvInitAsc3550Driver()\n");
5608                         warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
5609                     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5610                         ASC_DBG(2,
5611                             "advansys_detect: AdvInitAsc38C0800Driver()\n");
5612                         warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
5613                     } else {
5614                         ASC_DBG(2,
5615                             "advansys_detect: AdvInitAsc38C1600Driver()\n");
5616                         warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
5617                     }
5618                     err_code = adv_dvc_varp->err_code;
5619
5620                     if (warn_code || err_code) {
5621                         ASC_PRINT3(
5622 "advansys_detect: board %d error: warn 0x%x, error 0x%x\n",
5623                             boardp->id, warn_code, err_code);
5624                     }
5625                 }
5626             }
5627
5628             if (err_code != 0) {
5629                 release_region(shp->io_port, boardp->asc_n_io_port);
5630                 if (ASC_WIDE_BOARD(boardp)) {
5631                     iounmap(boardp->ioremap_addr);
5632                     if (boardp->orig_carrp) {
5633                         kfree(boardp->orig_carrp);
5634                         boardp->orig_carrp = NULL;
5635                     }
5636                     if (boardp->orig_reqp) {
5637                         kfree(boardp->orig_reqp);
5638                         boardp->orig_reqp = boardp->adv_reqp = NULL;
5639                     }
5640                     while ((sgp = boardp->adv_sgblkp) != NULL)
5641                     {
5642                         boardp->adv_sgblkp = sgp->next_sgblkp;
5643                         kfree(sgp);
5644                     }
5645                 }
5646                 if (shp->dma_channel != NO_ISA_DMA) {
5647                     free_dma(shp->dma_channel);
5648                 }
5649 #ifdef CONFIG_PROC_FS
5650                 kfree(boardp->prtbuf);
5651 #endif /* CONFIG_PROC_FS */
5652                 free_irq(shp->irq, boardp);
5653                 scsi_unregister(shp);
5654                 asc_board_count--;
5655                 continue;
5656             }
5657             ASC_DBG_PRT_SCSI_HOST(2, shp);
5658         }
5659     }
5660
5661     ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count);
5662     return asc_board_count;
5663 }
5664
5665 /*
5666  * advansys_release()
5667  *
5668  * Release resources allocated for a single AdvanSys adapter.
5669  */
5670 int
5671 advansys_release(struct Scsi_Host *shp)
5672 {
5673     asc_board_t    *boardp;
5674
5675     ASC_DBG(1, "advansys_release: begin\n");
5676     boardp = ASC_BOARDP(shp);
5677     free_irq(shp->irq, boardp);
5678     if (shp->dma_channel != NO_ISA_DMA) {
5679         ASC_DBG(1, "advansys_release: free_dma()\n");
5680         free_dma(shp->dma_channel);
5681     }
5682     release_region(shp->io_port, boardp->asc_n_io_port);
5683     if (ASC_WIDE_BOARD(boardp)) {
5684         adv_sgblk_t    *sgp = NULL;
5685
5686         iounmap(boardp->ioremap_addr);
5687         if (boardp->orig_carrp) {
5688             kfree(boardp->orig_carrp);
5689             boardp->orig_carrp = NULL;
5690         }
5691         if (boardp->orig_reqp) {
5692             kfree(boardp->orig_reqp);
5693             boardp->orig_reqp = boardp->adv_reqp = NULL;
5694         }
5695         while ((sgp = boardp->adv_sgblkp) != NULL)
5696         {
5697             boardp->adv_sgblkp = sgp->next_sgblkp;
5698             kfree(sgp);
5699         }
5700     }
5701 #ifdef CONFIG_PROC_FS
5702     ASC_ASSERT(boardp->prtbuf != NULL);
5703     kfree(boardp->prtbuf);
5704 #endif /* CONFIG_PROC_FS */
5705     scsi_unregister(shp);
5706     ASC_DBG(1, "advansys_release: end\n");
5707     return 0;
5708 }
5709
5710 /*
5711  * advansys_info()
5712  *
5713  * Return suitable for printing on the console with the argument
5714  * adapter's configuration information.
5715  *
5716  * Note: The information line should not exceed ASC_INFO_SIZE bytes,
5717  * otherwise the static 'info' array will be overrun.
5718  */
5719 const char *
5720 advansys_info(struct Scsi_Host *shp)
5721 {
5722     static char     info[ASC_INFO_SIZE];
5723     asc_board_t     *boardp;
5724     ASC_DVC_VAR     *asc_dvc_varp;
5725     ADV_DVC_VAR     *adv_dvc_varp;
5726     char            *busname;
5727     int             iolen;
5728     char            *widename = NULL;
5729
5730     boardp = ASC_BOARDP(shp);
5731     if (ASC_NARROW_BOARD(boardp)) {
5732         asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5733         ASC_DBG(1, "advansys_info: begin\n");
5734         if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5735             if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == ASC_IS_ISAPNP) {
5736                 busname = "ISA PnP";
5737             } else {
5738                 busname = "ISA";
5739             }
5740             /* Don't reference 'shp->n_io_port'; It may be truncated. */
5741             sprintf(info,
5742 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
5743                 ASC_VERSION, busname,
5744                 (ulong) shp->io_port,
5745                 (ulong) shp->io_port + boardp->asc_n_io_port - 1,
5746                 shp->irq, shp->dma_channel);
5747         } else {
5748             if (asc_dvc_varp->bus_type & ASC_IS_VL) {
5749                 busname = "VL";
5750             } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
5751                 busname = "EISA";
5752             } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
5753                 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
5754                     == ASC_IS_PCI_ULTRA) {
5755                     busname = "PCI Ultra";
5756                 } else {
5757                     busname = "PCI";
5758                 }
5759             } else {
5760                 busname = "?";
5761                 ASC_PRINT2( "advansys_info: board %d: unknown bus type %d\n",
5762                     boardp->id, asc_dvc_varp->bus_type);
5763             }
5764             /* Don't reference 'shp->n_io_port'; It may be truncated. */
5765             sprintf(info,
5766                 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
5767                 ASC_VERSION, busname,
5768                 (ulong) shp->io_port,
5769                 (ulong) shp->io_port + boardp->asc_n_io_port - 1,
5770                 shp->irq);
5771         }
5772     } else {
5773         /*
5774          * Wide Adapter Information
5775          *
5776          * Memory-mapped I/O is used instead of I/O space to access
5777          * the adapter, but display the I/O Port range. The Memory
5778          * I/O address is displayed through the driver /proc file.
5779          */
5780         adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5781         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5782         {
5783             iolen = ADV_3550_IOLEN;
5784             widename = "Ultra-Wide";
5785         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
5786         {
5787             iolen = ADV_38C0800_IOLEN;
5788             widename = "Ultra2-Wide";
5789         } else
5790         {
5791             iolen = ADV_38C1600_IOLEN;
5792             widename = "Ultra3-Wide";
5793         }
5794         sprintf(info, "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
5795             ASC_VERSION,
5796             widename,
5797             (ulong) adv_dvc_varp->iop_base,
5798             (ulong) adv_dvc_varp->iop_base + iolen - 1,
5799             shp->irq);
5800     }
5801     ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
5802     ASC_DBG(1, "advansys_info: end\n");
5803     return info;
5804 }
5805
5806 /*
5807  * advansys_queuecommand() - interrupt-driven I/O entrypoint.
5808  *
5809  * This function always returns 0. Command return status is saved
5810  * in the 'scp' result field.
5811  */
5812 int
5813 advansys_queuecommand(Scsi_Cmnd *scp, void (*done)(Scsi_Cmnd *))
5814 {
5815     struct Scsi_Host    *shp;
5816     asc_board_t         *boardp;
5817     ulong               flags;
5818     Scsi_Cmnd           *done_scp;
5819
5820     shp = scp->device->host;
5821     boardp = ASC_BOARDP(shp);
5822     ASC_STATS(shp, queuecommand);
5823
5824     /* host_lock taken by mid-level prior to call but need to protect */
5825     /* against own ISR */
5826     spin_lock_irqsave(&boardp->lock, flags);
5827
5828     /*
5829      * Block new commands while handling a reset or abort request.
5830      */
5831     if (boardp->flags & ASC_HOST_IN_RESET) {
5832         ASC_DBG1(1,
5833             "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
5834             (ulong) scp);
5835         scp->result = HOST_BYTE(DID_RESET);
5836
5837         /*
5838          * Add blocked requests to the board's 'done' queue. The queued
5839          * requests will be completed at the end of the abort or reset
5840          * handling.
5841          */
5842         asc_enqueue(&boardp->done, scp, ASC_BACK);
5843         spin_unlock_irqrestore(&boardp->lock, flags);
5844         return 0;
5845     }
5846
5847     /*
5848      * Attempt to execute any waiting commands for the board.
5849      */
5850     if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
5851         ASC_DBG(1,
5852             "advansys_queuecommand: before asc_execute_queue() waiting\n");
5853         asc_execute_queue(&boardp->waiting);
5854     }
5855
5856     /*
5857      * Save the function pointer to Linux mid-level 'done' function
5858      * and attempt to execute the command.
5859      *
5860      * If ASC_NOERROR is returned the request has been added to the
5861      * board's 'active' queue and will be completed by the interrupt
5862      * handler.
5863      *
5864      * If ASC_BUSY is returned add the request to the board's per
5865      * target waiting list. This is the first time the request has
5866      * been tried. Add it to the back of the waiting list. It will be
5867      * retried later.
5868      *
5869      * If an error occurred, the request will have been placed on the
5870      * board's 'done' queue and must be completed before returning.
5871      */
5872     scp->scsi_done = done;
5873     switch (asc_execute_scsi_cmnd(scp)) {
5874     case ASC_NOERROR:
5875         break;
5876     case ASC_BUSY:
5877         asc_enqueue(&boardp->waiting, scp, ASC_BACK);
5878         break;
5879     case ASC_ERROR:
5880     default:
5881         done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
5882         /* Interrupts could be enabled here. */
5883         asc_scsi_done_list(done_scp, 0);
5884         break;
5885     }
5886     spin_unlock_irqrestore(&boardp->lock, flags);
5887
5888     return 0;
5889 }
5890
5891 /*
5892  * advansys_reset()
5893  *
5894  * Reset the bus associated with the command 'scp'.
5895  *
5896  * This function runs its own thread. Interrupts must be blocked but
5897  * sleeping is allowed and no locking other than for host structures is
5898  * required. Returns SUCCESS or FAILED.
5899  */
5900 int
5901 advansys_reset(Scsi_Cmnd *scp)
5902 {
5903     struct Scsi_Host     *shp;
5904     asc_board_t          *boardp;
5905     ASC_DVC_VAR          *asc_dvc_varp;
5906     ADV_DVC_VAR          *adv_dvc_varp;
5907     ulong                flags;
5908     Scsi_Cmnd            *done_scp = NULL, *last_scp = NULL;
5909     Scsi_Cmnd            *tscp, *new_last_scp;
5910     int                  status;
5911     int                  ret = SUCCESS;
5912
5913     ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong) scp);
5914
5915 #ifdef ADVANSYS_STATS
5916     if (scp->device->host != NULL) {
5917         ASC_STATS(scp->device->host, reset);
5918     }
5919 #endif /* ADVANSYS_STATS */
5920
5921     if ((shp = scp->device->host) == NULL) {
5922         scp->result = HOST_BYTE(DID_ERROR);
5923         return FAILED;
5924     }
5925
5926     boardp = ASC_BOARDP(shp);
5927
5928     ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
5929         boardp->id);
5930     /*
5931      * Check for re-entrancy.
5932      */
5933     spin_lock_irqsave(&boardp->lock, flags);
5934     if (boardp->flags & ASC_HOST_IN_RESET) {
5935         spin_unlock_irqrestore(&boardp->lock, flags);
5936         return FAILED;
5937     }
5938     boardp->flags |= ASC_HOST_IN_RESET;
5939     spin_unlock_irqrestore(&boardp->lock, flags);
5940
5941     if (ASC_NARROW_BOARD(boardp)) {
5942         /*
5943          * Narrow Board
5944          */
5945         asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5946
5947         /*
5948          * Reset the chip and SCSI bus.
5949          */
5950         ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
5951         status = AscInitAsc1000Driver(asc_dvc_varp);
5952
5953         /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
5954         if (asc_dvc_varp->err_code) {
5955             ASC_PRINT2(
5956                 "advansys_reset: board %d: SCSI bus reset error: 0x%x\n",
5957                 boardp->id, asc_dvc_varp->err_code);
5958             ret = FAILED;
5959         } else if (status) {
5960             ASC_PRINT2(
5961                 "advansys_reset: board %d: SCSI bus reset warning: 0x%x\n",
5962                 boardp->id, status);
5963         } else {
5964             ASC_PRINT1(
5965                 "advansys_reset: board %d: SCSI bus reset successful.\n",
5966                 boardp->id);
5967         }
5968
5969         ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
5970         spin_lock_irqsave(&boardp->lock, flags);
5971
5972     } else {
5973         /*
5974          * Wide Board
5975          *
5976          * If the suggest reset bus flags are set, then reset the bus.
5977          * Otherwise only reset the device.
5978          */
5979         adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5980
5981         /*
5982          * Reset the target's SCSI bus.
5983          */
5984         ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
5985         switch (AdvResetChipAndSB(adv_dvc_varp)) {
5986         case ASC_TRUE:
5987             ASC_PRINT1("advansys_reset: board %d: SCSI bus reset successful.\n",
5988                 boardp->id);
5989             break;
5990         case ASC_FALSE:
5991         default:
5992             ASC_PRINT1("advansys_reset: board %d: SCSI bus reset error.\n",
5993                 boardp->id);
5994             ret = FAILED;
5995             break;
5996         }
5997         spin_lock_irqsave(&boardp->lock, flags);
5998         (void) AdvISR(adv_dvc_varp);
5999     }
6000     /* Board lock is held. */
6001
6002     /*
6003      * Dequeue all board 'done' requests. A pointer to the last request
6004      * is returned in 'last_scp'.
6005      */
6006     done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
6007
6008     /*
6009      * Dequeue all board 'active' requests for all devices and set
6010      * the request status to DID_RESET. A pointer to the last request
6011      * is returned in 'last_scp'.
6012      */
6013     if (done_scp == NULL) {
6014         done_scp = asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL);
6015         for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
6016             tscp->result = HOST_BYTE(DID_RESET);
6017         }
6018     } else {
6019         /* Append to 'done_scp' at the end with 'last_scp'. */
6020         ASC_ASSERT(last_scp != NULL);
6021         last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
6022                         &boardp->active, &new_last_scp, ASC_TID_ALL);
6023         if (new_last_scp != NULL) {
6024             ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6025             for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
6026                 tscp->result = HOST_BYTE(DID_RESET);
6027             }
6028             last_scp = new_last_scp;
6029         }
6030     }
6031
6032     /*
6033      * Dequeue all 'waiting' requests and set the request status
6034      * to DID_RESET.
6035      */
6036     if (done_scp == NULL) {
6037         done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL);
6038         for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
6039             tscp->result = HOST_BYTE(DID_RESET);
6040         }
6041     } else {
6042         /* Append to 'done_scp' at the end with 'last_scp'. */
6043         ASC_ASSERT(last_scp != NULL);
6044         last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
6045                         &boardp->waiting, &new_last_scp, ASC_TID_ALL);
6046         if (new_last_scp != NULL) {
6047             ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6048             for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
6049                 tscp->result = HOST_BYTE(DID_RESET);
6050             }
6051             last_scp = new_last_scp;
6052         }
6053     }
6054
6055     /* Save the time of the most recently completed reset. */
6056     boardp->last_reset = jiffies;
6057
6058     /* Clear reset flag. */
6059     boardp->flags &= ~ASC_HOST_IN_RESET;
6060     spin_unlock_irqrestore(&boardp->lock, flags);
6061
6062     /*
6063      * Complete all the 'done_scp' requests.
6064      */
6065     if (done_scp != NULL) {
6066         asc_scsi_done_list(done_scp, 0);
6067     }
6068
6069     ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
6070
6071     return ret;
6072 }
6073
6074 /*
6075  * advansys_biosparam()
6076  *
6077  * Translate disk drive geometry if the "BIOS greater than 1 GB"
6078  * support is enabled for a drive.
6079  *
6080  * ip (information pointer) is an int array with the following definition:
6081  * ip[0]: heads
6082  * ip[1]: sectors
6083  * ip[2]: cylinders
6084  */
6085 int
6086 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
6087                 sector_t capacity, int ip[])
6088 {
6089     asc_board_t     *boardp;
6090
6091     ASC_DBG(1, "advansys_biosparam: begin\n");
6092     ASC_STATS(sdev->host, biosparam);
6093     boardp = ASC_BOARDP(sdev->host);
6094     if (ASC_NARROW_BOARD(boardp)) {
6095         if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
6096              ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
6097                 ip[0] = 255;
6098                 ip[1] = 63;
6099         } else {
6100                 ip[0] = 64;
6101                 ip[1] = 32;
6102         }
6103     } else {
6104         if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
6105              BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
6106                 ip[0] = 255;
6107                 ip[1] = 63;
6108         } else {
6109                 ip[0] = 64;
6110                 ip[1] = 32;
6111         }
6112     }
6113     ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
6114     ASC_DBG(1, "advansys_biosparam: end\n");
6115     return 0;
6116 }
6117
6118 /*
6119  * advansys_setup()
6120  *
6121  * This function is called from init/main.c at boot time.
6122  * It it passed LILO parameters that can be set from the
6123  * LILO command line or in /etc/lilo.conf.
6124  *
6125  * It is used by the AdvanSys driver to either disable I/O
6126  * port scanning or to limit scanning to 1 - 4 I/O ports.
6127  * Regardless of the option setting EISA and PCI boards
6128  * will still be searched for and detected. This option
6129  * only affects searching for ISA and VL boards.
6130  *
6131  * If ADVANSYS_DEBUG is defined the driver debug level may
6132  * be set using the 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port.
6133  *
6134  * Examples:
6135  * 1. Eliminate I/O port scanning:
6136  *         boot: linux advansys=
6137  *       or
6138  *         boot: linux advansys=0x0
6139  * 2. Limit I/O port scanning to one I/O port:
6140  *        boot: linux advansys=0x110
6141  * 3. Limit I/O port scanning to four I/O ports:
6142  *        boot: linux advansys=0x110,0x210,0x230,0x330
6143  * 4. If ADVANSYS_DEBUG, limit I/O port scanning to four I/O ports and
6144  *    set the driver debug level to 2.
6145  *        boot: linux advansys=0x110,0x210,0x230,0x330,0xdeb2
6146  *
6147  * ints[0] - number of arguments
6148  * ints[1] - first argument
6149  * ints[2] - second argument
6150  * ...
6151  */
6152 ASC_INITFUNC(
6153 void,
6154 advansys_setup(char *str, int *ints)
6155 )
6156 {
6157     int    i;
6158
6159     if (asc_iopflag == ASC_TRUE) {
6160         printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n");
6161         return;
6162     }
6163
6164     asc_iopflag = ASC_TRUE;
6165
6166     if (ints[0] > ASC_NUM_IOPORT_PROBE) {
6167 #ifdef ADVANSYS_DEBUG
6168         if ((ints[0] == ASC_NUM_IOPORT_PROBE + 1) &&
6169             (ints[ASC_NUM_IOPORT_PROBE + 1] >> 4 == 0xdeb)) {
6170             asc_dbglvl = ints[ASC_NUM_IOPORT_PROBE + 1] & 0xf;
6171         } else {
6172 #endif /* ADVANSYS_DEBUG */
6173             printk("AdvanSys SCSI: only %d I/O ports accepted\n",
6174                 ASC_NUM_IOPORT_PROBE);
6175 #ifdef ADVANSYS_DEBUG
6176         }
6177 #endif /* ADVANSYS_DEBUG */
6178     }
6179
6180 #ifdef ADVANSYS_DEBUG
6181     ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]);
6182     for (i = 1; i < ints[0]; i++) {
6183         ASC_DBG2(1, " ints[%d] 0x%x", i, ints[i]);
6184     }
6185     ASC_DBG(1, "\n");
6186 #endif /* ADVANSYS_DEBUG */
6187
6188     for (i = 1; i <= ints[0] && i <= ASC_NUM_IOPORT_PROBE; i++) {
6189         asc_ioport[i-1] = ints[i];
6190         ASC_DBG2(1, "advansys_setup: asc_ioport[%d] 0x%x\n",
6191             i - 1, asc_ioport[i-1]);
6192     }
6193 }
6194
6195
6196 /*
6197  * --- Loadable Driver Support
6198  */
6199
6200 static Scsi_Host_Template driver_template = {
6201     .proc_name                  = "advansys",
6202 #ifdef CONFIG_PROC_FS
6203     .proc_info                  = advansys_proc_info,
6204 #endif
6205     .name                       = "advansys",
6206     .detect                     = advansys_detect, 
6207     .release                    = advansys_release,
6208     .info                       = advansys_info,
6209     .queuecommand               = advansys_queuecommand,
6210     .eh_bus_reset_handler       = advansys_reset,
6211     .bios_param                 = advansys_biosparam,
6212     .slave_configure            = advansys_slave_configure,
6213     /*
6214      * Because the driver may control an ISA adapter 'unchecked_isa_dma'
6215      * must be set. The flag will be cleared in advansys_detect for non-ISA
6216      * adapters. Refer to the comment in scsi_module.c for more information.
6217      */
6218     .unchecked_isa_dma          = 1,
6219     /*
6220      * All adapters controlled by this driver are capable of large
6221      * scatter-gather lists. According to the mid-level SCSI documentation
6222      * this obviates any performance gain provided by setting
6223      * 'use_clustering'. But empirically while CPU utilization is increased
6224      * by enabling clustering, I/O throughput increases as well.
6225      */
6226     .use_clustering             = ENABLE_CLUSTERING,
6227 };
6228 #include "scsi_module.c"
6229
6230
6231 /*
6232  * --- Miscellaneous Driver Functions
6233  */
6234
6235 /*
6236  * First-level interrupt handler.
6237  *
6238  * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
6239  * all boards are currently checked for interrupts on each interrupt, 'dev_id'
6240  * is not referenced. 'dev_id' could be used to identify an interrupt passed
6241  * to the AdvanSys driver which is for a device sharing an interrupt with
6242  * an AdvanSys adapter.
6243  */
6244 STATIC irqreturn_t
6245 advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs)
6246 {
6247     ulong           flags;
6248     int             i;
6249     asc_board_t     *boardp;
6250     Scsi_Cmnd       *done_scp = NULL, *last_scp = NULL;
6251     Scsi_Cmnd       *new_last_scp;
6252     struct Scsi_Host *shp;
6253
6254     ASC_DBG(1, "advansys_interrupt: begin\n");
6255
6256     /*
6257      * Check for interrupts on all boards.
6258      * AscISR() will call asc_isr_callback().
6259      */
6260     for (i = 0; i < asc_board_count; i++) {
6261         shp = asc_host[i];
6262         boardp = ASC_BOARDP(shp);
6263         ASC_DBG2(2, "advansys_interrupt: i %d, boardp 0x%lx\n",
6264             i, (ulong) boardp);
6265         spin_lock_irqsave(&boardp->lock, flags);
6266         if (ASC_NARROW_BOARD(boardp)) {
6267             /*
6268              * Narrow Board
6269              */
6270             if (AscIsIntPending(shp->io_port)) {
6271                 ASC_STATS(shp, interrupt);
6272                 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
6273                 AscISR(&boardp->dvc_var.asc_dvc_var);
6274             }
6275         } else {
6276             /*
6277              * Wide Board
6278              */
6279             ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
6280             if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
6281                 ASC_STATS(shp, interrupt);
6282             }
6283         }
6284
6285         /*
6286          * Start waiting requests and create a list of completed requests.
6287          *
6288          * If a reset request is being performed for the board, the reset
6289          * handler will complete pending requests after it has completed.
6290          */
6291         if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
6292             ASC_DBG2(1, "advansys_interrupt: done_scp 0x%lx, last_scp 0x%lx\n",
6293                 (ulong) done_scp, (ulong) last_scp);
6294
6295             /* Start any waiting commands for the board. */
6296             if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
6297                 ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
6298                 asc_execute_queue(&boardp->waiting);
6299             }
6300
6301              /*
6302               * Add to the list of requests that must be completed.
6303               *
6304               * 'done_scp' will always be NULL on the first iteration
6305               * of this loop. 'last_scp' is set at the same time as
6306               * 'done_scp'.
6307               */
6308             if (done_scp == NULL) {
6309                 done_scp = asc_dequeue_list(&boardp->done, &last_scp,
6310                     ASC_TID_ALL);
6311             } else {
6312                 ASC_ASSERT(last_scp != NULL);
6313                 last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
6314                         &boardp->done, &new_last_scp, ASC_TID_ALL);
6315                 if (new_last_scp != NULL) {
6316                     ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6317                     last_scp = new_last_scp;
6318                 }
6319             }
6320         }
6321         spin_unlock_irqrestore(&boardp->lock, flags);
6322     }
6323
6324     /*
6325      * If interrupts were enabled on entry, then they
6326      * are now enabled here.
6327      *
6328      * Complete all requests on the done list.
6329      */
6330
6331     asc_scsi_done_list(done_scp, 1);
6332
6333     ASC_DBG(1, "advansys_interrupt: end\n");
6334     return IRQ_HANDLED;
6335 }
6336
6337 /*
6338  * Set the number of commands to queue per device for the
6339  * specified host adapter.
6340  */
6341 STATIC int
6342 advansys_slave_configure(Scsi_Device *device)
6343 {
6344     asc_board_t        *boardp;
6345
6346     boardp = ASC_BOARDP(device->host);
6347     boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
6348     /*
6349      * Save a pointer to the device and set its initial/maximum
6350      * queue depth.  Only save the pointer for a lun0 dev though.
6351      */
6352     if(device->lun == 0)
6353         boardp->device[device->id] = device;
6354     if(device->tagged_supported) {
6355         if (ASC_NARROW_BOARD(boardp)) {
6356             scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
6357                 boardp->dvc_var.asc_dvc_var.max_dvc_qng[device->id]);
6358         } else {
6359             scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
6360                 boardp->dvc_var.adv_dvc_var.max_dvc_qng);
6361         }
6362     } else {
6363         scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun);
6364     }
6365     ASC_DBG4(1, "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n",
6366             (ulong) device, (ulong) boardp, device->id, device->queue_depth);
6367     return 0;
6368 }
6369
6370 /*
6371  * Complete all requests on the singly linked list pointed
6372  * to by 'scp'.
6373  *
6374  * Interrupts can be enabled on entry.
6375  */
6376 STATIC void
6377 asc_scsi_done_list(Scsi_Cmnd *scp, int from_isr)
6378 {
6379     Scsi_Cmnd    *tscp;
6380     ulong         flags = 0;
6381
6382     ASC_DBG(2, "asc_scsi_done_list: begin\n");
6383     while (scp != NULL) {
6384         ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong) scp);
6385         tscp = REQPNEXT(scp);
6386         scp->host_scribble = NULL;
6387         ASC_STATS(scp->device->host, done);
6388         ASC_ASSERT(scp->scsi_done != NULL);
6389         if (from_isr)
6390             spin_lock_irqsave(scp->device->host->host_lock, flags);
6391         scp->scsi_done(scp);
6392         if (from_isr)
6393             spin_unlock_irqrestore(scp->device->host->host_lock, flags);
6394         scp = tscp;
6395     }
6396     ASC_DBG(2, "asc_scsi_done_list: done\n");
6397     return;
6398 }
6399
6400 /*
6401  * Execute a single 'Scsi_Cmnd'.
6402  *
6403  * The function 'done' is called when the request has been completed.
6404  *
6405  * Scsi_Cmnd:
6406  *
6407  *  host - board controlling device
6408  *  device - device to send command
6409  *  target - target of device
6410  *  lun - lun of device
6411  *  cmd_len - length of SCSI CDB
6412  *  cmnd - buffer for SCSI 8, 10, or 12 byte CDB
6413  *  use_sg - if non-zero indicates scatter-gather request with use_sg elements
6414  *
6415  *  if (use_sg == 0) {
6416  *    request_buffer - buffer address for request
6417  *    request_bufflen - length of request buffer
6418  *  } else {
6419  *    request_buffer - pointer to scatterlist structure
6420  *  }
6421  *
6422  *  sense_buffer - sense command buffer
6423  *
6424  *  result (4 bytes of an int):
6425  *    Byte Meaning
6426  *    0 SCSI Status Byte Code
6427  *    1 SCSI One Byte Message Code
6428  *    2 Host Error Code
6429  *    3 Mid-Level Error Code
6430  *
6431  *  host driver fields:
6432  *    SCp - Scsi_Pointer used for command processing status
6433  *    scsi_done - used to save caller's done function
6434  *    host_scribble - used for pointer to another Scsi_Cmnd
6435  *
6436  * If this function returns ASC_NOERROR the request has been enqueued
6437  * on the board's 'active' queue and will be completed from the
6438  * interrupt handler.
6439  *
6440  * If this function returns ASC_NOERROR the request has been enqueued
6441  * on the board's 'done' queue and must be completed by the caller.
6442  *
6443  * If ASC_BUSY is returned the request will be enqueued by the
6444  * caller on the target's waiting queue and re-tried later.
6445  */
6446 STATIC int
6447 asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
6448 {
6449     asc_board_t        *boardp;
6450     ASC_DVC_VAR        *asc_dvc_varp;
6451     ADV_DVC_VAR        *adv_dvc_varp;
6452     ADV_SCSI_REQ_Q     *adv_scsiqp;
6453     Scsi_Device        *device;
6454     int                ret;
6455
6456     ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
6457         (ulong) scp, (ulong) scp->scsi_done);
6458
6459     boardp = ASC_BOARDP(scp->device->host);
6460     device = boardp->device[scp->device->id];
6461
6462     if (ASC_NARROW_BOARD(boardp)) {
6463         /*
6464          * Build and execute Narrow Board request.
6465          */
6466
6467         asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6468
6469         /*
6470          * Build Asc Library request structure using the
6471          * global structures 'asc_scsi_req' and 'asc_sg_head'.
6472          *
6473          * If an error is returned, then the request has been
6474          * queued on the board done queue. It will be completed
6475          * by the caller.
6476          *
6477          * asc_build_req() can not return ASC_BUSY.
6478          */
6479         if (asc_build_req(boardp, scp) == ASC_ERROR) {
6480             ASC_STATS(scp->device->host, build_error);
6481             return ASC_ERROR;
6482         }
6483
6484         /*
6485          * Execute the command. If there is no error, add the command
6486          * to the active queue.
6487          */
6488         switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
6489         case ASC_NOERROR:
6490             ASC_STATS(scp->device->host, exe_noerror);
6491             /*
6492              * Increment monotonically increasing per device successful
6493              * request counter. Wrapping doesn't matter.
6494              */
6495             boardp->reqcnt[scp->device->id]++;
6496             asc_enqueue(&boardp->active, scp, ASC_BACK);
6497             ASC_DBG(1,
6498                 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
6499             break;
6500         case ASC_BUSY:
6501             /*
6502              * Caller will enqueue request on the target's waiting queue
6503              * and retry later.
6504              */
6505             ASC_STATS(scp->device->host, exe_busy);
6506             break;
6507         case ASC_ERROR:
6508             ASC_PRINT2(
6509 "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
6510                 boardp->id, asc_dvc_varp->err_code);
6511             ASC_STATS(scp->device->host, exe_error);
6512             scp->result = HOST_BYTE(DID_ERROR);
6513             asc_enqueue(&boardp->done, scp, ASC_BACK);
6514             break;
6515         default:
6516             ASC_PRINT2(
6517 "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
6518                 boardp->id, asc_dvc_varp->err_code);
6519             ASC_STATS(scp->device->host, exe_unknown);
6520             scp->result = HOST_BYTE(DID_ERROR);
6521             asc_enqueue(&boardp->done, scp, ASC_BACK);
6522             break;
6523         }
6524     } else {
6525         /*
6526          * Build and execute Wide Board request.
6527          */
6528         adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6529
6530         /*
6531          * Build and get a pointer to an Adv Library request structure.
6532          *
6533          * If the request is successfully built then send it below,
6534          * otherwise return with an error.
6535          */
6536         switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
6537         case ASC_NOERROR:
6538             ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
6539             break;
6540         case ASC_BUSY:
6541             ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
6542             /*
6543              * If busy is returned the request has not been enqueued.
6544              * It will be enqueued by the caller on the target's waiting
6545              * queue and retried later.
6546              *
6547              * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg'
6548              * count wide board busy conditions. They are updated in
6549              * adv_build_req and adv_get_sglist, respectively.
6550              */
6551             return ASC_BUSY;
6552         case ASC_ERROR:
6553              /* 
6554               * If an error is returned, then the request has been
6555               * queued on the board done queue. It will be completed
6556               * by the caller.
6557               */
6558         default:
6559             ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
6560             ASC_STATS(scp->device->host, build_error);
6561             return ASC_ERROR;
6562         }
6563
6564         /*
6565          * Execute the command. If there is no error, add the command
6566          * to the active queue.
6567          */
6568         switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
6569         case ASC_NOERROR:
6570             ASC_STATS(scp->device->host, exe_noerror);
6571             /*
6572              * Increment monotonically increasing per device successful
6573              * request counter. Wrapping doesn't matter.
6574              */
6575             boardp->reqcnt[scp->device->id]++;
6576             asc_enqueue(&boardp->active, scp, ASC_BACK);
6577             ASC_DBG(1,
6578                 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
6579             break;
6580         case ASC_BUSY:
6581             /*
6582              * Caller will enqueue request on the target's waiting queue
6583              * and retry later.
6584              */
6585             ASC_STATS(scp->device->host, exe_busy);
6586             break;
6587         case ASC_ERROR:
6588             ASC_PRINT2(
6589 "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
6590                 boardp->id, adv_dvc_varp->err_code);
6591             ASC_STATS(scp->device->host, exe_error);
6592             scp->result = HOST_BYTE(DID_ERROR);
6593             asc_enqueue(&boardp->done, scp, ASC_BACK);
6594             break;
6595         default:
6596             ASC_PRINT2(
6597 "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
6598                 boardp->id, adv_dvc_varp->err_code);
6599             ASC_STATS(scp->device->host, exe_unknown);
6600             scp->result = HOST_BYTE(DID_ERROR);
6601             asc_enqueue(&boardp->done, scp, ASC_BACK);
6602             break;
6603         }
6604     }
6605
6606     ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
6607     return ret;
6608 }
6609
6610 /*
6611  * Build a request structure for the Asc Library (Narrow Board).
6612  *
6613  * The global structures 'asc_scsi_q' and 'asc_sg_head' are
6614  * used to build the request.
6615  *
6616  * If an error occurs, then queue the request on the board done
6617  * queue and return ASC_ERROR.
6618  */
6619 STATIC int
6620 asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp)
6621 {
6622     /*
6623      * Mutually exclusive access is required to 'asc_scsi_q' and
6624      * 'asc_sg_head' until after the request is started.
6625      */
6626     memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
6627
6628     /*
6629      * Point the ASC_SCSI_Q to the 'Scsi_Cmnd'.
6630      */
6631     asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
6632
6633     /*
6634      * Build the ASC_SCSI_Q request.
6635      *
6636      * For narrow boards a CDB length maximum of 12 bytes
6637      * is supported.
6638      */
6639     if (scp->cmd_len > ASC_MAX_CDB_LEN) {
6640         ASC_PRINT3(
6641 "asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN  %d\n",
6642             boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN);
6643         scp->result = HOST_BYTE(DID_ERROR);
6644         asc_enqueue(&boardp->done, scp, ASC_BACK);
6645         return ASC_ERROR;
6646     }
6647     asc_scsi_q.cdbptr = &scp->cmnd[0];
6648     asc_scsi_q.q2.cdb_len = scp->cmd_len;
6649     asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
6650     asc_scsi_q.q1.target_lun = scp->device->lun;
6651     asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
6652     asc_scsi_q.q1.sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
6653     asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
6654
6655     /*
6656      * If there are any outstanding requests for the current target,
6657      * then every 255th request send an ORDERED request. This heuristic
6658      * tries to retain the benefit of request sorting while preventing
6659      * request starvation. 255 is the max number of tags or pending commands
6660      * a device may have outstanding.
6661      *
6662      * The request count is incremented below for every successfully
6663      * started request.
6664      *
6665      */
6666     if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
6667         (boardp->reqcnt[scp->device->id] % 255) == 0) {
6668         asc_scsi_q.q2.tag_code = M2_QTAG_MSG_ORDERED;
6669     } else {
6670         asc_scsi_q.q2.tag_code = M2_QTAG_MSG_SIMPLE;
6671     }
6672
6673     /*
6674      * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
6675      * buffer command.
6676      */
6677     if (scp->use_sg == 0) {
6678         /*
6679          * CDB request of single contiguous buffer.
6680          */
6681         ASC_STATS(scp->device->host, cont_cnt);
6682         asc_scsi_q.q1.data_addr =
6683             cpu_to_le32(virt_to_bus(scp->request_buffer));
6684         asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
6685         ASC_STATS_ADD(scp->device->host, cont_xfer,
6686                       ASC_CEILING(scp->request_bufflen, 512));
6687         asc_scsi_q.q1.sg_queue_cnt = 0;
6688         asc_scsi_q.sg_head = NULL;
6689     } else {
6690         /*
6691          * CDB scatter-gather request list.
6692          */
6693         int                     sgcnt;
6694         struct scatterlist      *slp;
6695
6696         if (scp->use_sg > scp->device->host->sg_tablesize) {
6697             ASC_PRINT3(
6698 "asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
6699                 boardp->id, scp->use_sg, scp->device->host->sg_tablesize);
6700             scp->result = HOST_BYTE(DID_ERROR);
6701             asc_enqueue(&boardp->done, scp, ASC_BACK);
6702             return ASC_ERROR;
6703         }
6704
6705         ASC_STATS(scp->device->host, sg_cnt);
6706
6707         /*
6708          * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
6709          * structure to point to it.
6710          */
6711         memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
6712
6713         asc_scsi_q.q1.cntl |= QC_SG_HEAD;
6714         asc_scsi_q.sg_head = &asc_sg_head;
6715         asc_scsi_q.q1.data_cnt = 0;
6716         asc_scsi_q.q1.data_addr = 0;
6717         /* This is a byte value, otherwise it would need to be swapped. */
6718         asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = scp->use_sg;
6719         ASC_STATS_ADD(scp->device->host, sg_elem, asc_sg_head.entry_cnt);
6720
6721         /*
6722          * Convert scatter-gather list into ASC_SG_HEAD list.
6723          */
6724         slp = (struct scatterlist *) scp->request_buffer;
6725         for (sgcnt = 0; sgcnt < scp->use_sg; sgcnt++, slp++) {
6726             asc_sg_head.sg_list[sgcnt].addr =
6727                 cpu_to_le32(virt_to_bus(
6728                 (unsigned char *)page_address(slp->page) + slp->offset));
6729             asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(slp->length);
6730             ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(slp->length, 512));
6731         }
6732     }
6733
6734     ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
6735     ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6736
6737     return ASC_NOERROR;
6738 }
6739
6740 /*
6741  * Build a request structure for the Adv Library (Wide Board).
6742  *
6743  * If an adv_req_t can not be allocated to issue the request,
6744  * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
6745  *
6746  * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
6747  * microcode for DMA addresses or math operations are byte swapped
6748  * to little-endian order.
6749  */
6750 STATIC int
6751 adv_build_req(asc_board_t *boardp, Scsi_Cmnd *scp,
6752     ADV_SCSI_REQ_Q **adv_scsiqpp)
6753 {
6754     adv_req_t           *reqp;
6755     ADV_SCSI_REQ_Q      *scsiqp;
6756     int                 i;
6757     int                 ret;
6758
6759     /*
6760      * Allocate an adv_req_t structure from the board to execute
6761      * the command.
6762      */
6763     if (boardp->adv_reqp == NULL) {
6764         ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
6765         ASC_STATS(scp->device->host, adv_build_noreq);
6766         return ASC_BUSY;
6767     } else {
6768         reqp = boardp->adv_reqp;
6769         boardp->adv_reqp = reqp->next_reqp;
6770         reqp->next_reqp = NULL;
6771     }
6772
6773     /*
6774      * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
6775      */
6776     scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
6777
6778     /*
6779      * Initialize the structure.
6780      */
6781     scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
6782
6783     /*
6784      * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
6785      */
6786     scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
6787
6788     /*
6789      * Set the adv_req_t 'cmndp' to point to the Scsi_Cmnd structure.
6790      */
6791     reqp->cmndp = scp;
6792
6793     /*
6794      * Build the ADV_SCSI_REQ_Q request.
6795      */
6796
6797     /*
6798      * Set CDB length and copy it to the request structure.
6799      * For wide  boards a CDB length maximum of 16 bytes
6800      * is supported.
6801      */
6802     if (scp->cmd_len > ADV_MAX_CDB_LEN) {
6803         ASC_PRINT3(
6804 "adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN  %d\n",
6805             boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
6806         scp->result = HOST_BYTE(DID_ERROR);
6807         asc_enqueue(&boardp->done, scp, ASC_BACK);
6808         return ASC_ERROR;
6809     }
6810     scsiqp->cdb_len = scp->cmd_len;
6811     /* Copy first 12 CDB bytes to cdb[]. */
6812     for (i = 0; i < scp->cmd_len && i < 12; i++) {
6813         scsiqp->cdb[i] = scp->cmnd[i];
6814     }
6815     /* Copy last 4 CDB bytes, if present, to cdb16[]. */
6816     for (; i < scp->cmd_len; i++) {
6817         scsiqp->cdb16[i - 12] = scp->cmnd[i];
6818     }
6819
6820     scsiqp->target_id = scp->device->id;
6821     scsiqp->target_lun = scp->device->lun;
6822
6823     scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
6824     scsiqp->sense_len = sizeof(scp->sense_buffer);
6825
6826     /*
6827      * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
6828      * buffer command.
6829      */
6830     scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
6831     scsiqp->vdata_addr = scp->request_buffer;
6832     scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
6833
6834     if (scp->use_sg == 0) {
6835         /*
6836          * CDB request of single contiguous buffer.
6837          */
6838         reqp->sgblkp = NULL;
6839         scsiqp->sg_list_ptr = NULL;
6840         scsiqp->sg_real_addr = 0;
6841         ASC_STATS(scp->device->host, cont_cnt);
6842         ASC_STATS_ADD(scp->device->host, cont_xfer,
6843                       ASC_CEILING(scp->request_bufflen, 512));
6844     } else {
6845         /*
6846          * CDB scatter-gather request list.
6847          */
6848         if (scp->use_sg > ADV_MAX_SG_LIST) {
6849             ASC_PRINT3(
6850 "adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
6851                 boardp->id, scp->use_sg, scp->device->host->sg_tablesize);
6852             scp->result = HOST_BYTE(DID_ERROR);
6853             asc_enqueue(&boardp->done, scp, ASC_BACK);
6854
6855             /*
6856              * Free the 'adv_req_t' structure by adding it back to the
6857              * board free list.
6858              */
6859             reqp->next_reqp = boardp->adv_reqp;
6860             boardp->adv_reqp = reqp;
6861
6862             return ASC_ERROR;
6863         }
6864
6865         if ((ret = adv_get_sglist(boardp, reqp, scp)) != ADV_SUCCESS) {
6866             /*
6867              * Free the adv_req_t structure by adding it back to the
6868              * board free list.
6869              */
6870             reqp->next_reqp = boardp->adv_reqp;
6871             boardp->adv_reqp = reqp;
6872
6873             return ret;
6874         }
6875
6876         ASC_STATS(scp->device->host, sg_cnt);
6877         ASC_STATS_ADD(scp->device->host, sg_elem, scp->use_sg);
6878     }
6879
6880     ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
6881     ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6882
6883     *adv_scsiqpp = scsiqp;
6884
6885     return ASC_NOERROR;
6886 }
6887
6888 /*
6889  * Build scatter-gather list for Adv Library (Wide Board).
6890  *
6891  * Additional ADV_SG_BLOCK structures will need to be allocated
6892  * if the total number of scatter-gather elements exceeds
6893  * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
6894  * assumed to be physically contiguous.
6895  *
6896  * Return:
6897  *      ADV_SUCCESS(1) - SG List successfully created
6898  *      ADV_ERROR(-1) - SG List creation failed
6899  */
6900 STATIC int
6901 adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, Scsi_Cmnd *scp)
6902 {
6903     adv_sgblk_t         *sgblkp;
6904     ADV_SCSI_REQ_Q      *scsiqp;
6905     struct scatterlist  *slp;
6906     int                 sg_elem_cnt;
6907     ADV_SG_BLOCK        *sg_block, *prev_sg_block;
6908     ADV_PADDR           sg_block_paddr;
6909     int                 i;
6910
6911     scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
6912     slp = (struct scatterlist *) scp->request_buffer;
6913     sg_elem_cnt = scp->use_sg;
6914     prev_sg_block = NULL;
6915     reqp->sgblkp = NULL;
6916
6917     do
6918     {
6919         /*
6920          * Allocate a 'adv_sgblk_t' structure from the board free
6921          * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
6922          * (15) scatter-gather elements.
6923          */
6924         if ((sgblkp = boardp->adv_sgblkp) == NULL) {
6925             ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
6926             ASC_STATS(scp->device->host, adv_build_nosg);
6927
6928             /*
6929              * Allocation failed. Free 'adv_sgblk_t' structures already
6930              * allocated for the request.
6931              */
6932             while ((sgblkp = reqp->sgblkp) != NULL)
6933             {
6934                 /* Remove 'sgblkp' from the request list. */
6935                 reqp->sgblkp = sgblkp->next_sgblkp;
6936
6937                 /* Add 'sgblkp' to the board free list. */
6938                 sgblkp->next_sgblkp = boardp->adv_sgblkp;
6939                 boardp->adv_sgblkp = sgblkp;
6940             }
6941             return ASC_BUSY;
6942         } else {
6943             /* Complete 'adv_sgblk_t' board allocation. */
6944             boardp->adv_sgblkp = sgblkp->next_sgblkp;
6945             sgblkp->next_sgblkp = NULL;
6946
6947             /*
6948              * Get 8 byte aligned virtual and physical addresses for
6949              * the allocated ADV_SG_BLOCK structure.
6950              */
6951             sg_block = (ADV_SG_BLOCK *) ADV_8BALIGN(&sgblkp->sg_block);
6952             sg_block_paddr = virt_to_bus(sg_block);
6953
6954             /*
6955              * Check if this is the first 'adv_sgblk_t' for the request.
6956              */
6957             if (reqp->sgblkp == NULL)
6958             {
6959                 /* Request's first scatter-gather block. */
6960                 reqp->sgblkp = sgblkp;
6961
6962                 /*
6963                  * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
6964                  * address pointers.
6965                  */
6966                 scsiqp->sg_list_ptr = sg_block;
6967                 scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr);
6968             } else
6969             {
6970                 /* Request's second or later scatter-gather block. */
6971                 sgblkp->next_sgblkp = reqp->sgblkp;
6972                 reqp->sgblkp = sgblkp;
6973
6974                 /*
6975                  * Point the previous ADV_SG_BLOCK structure to
6976                  * the newly allocated ADV_SG_BLOCK structure.
6977                  */
6978                 ASC_ASSERT(prev_sg_block != NULL);
6979                 prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr);
6980             }
6981         }
6982
6983         for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
6984         {
6985             sg_block->sg_list[i].sg_addr =
6986                 cpu_to_le32(virt_to_bus(
6987                    (unsigned char *)page_address(slp->page) + slp->offset));
6988             sg_block->sg_list[i].sg_count = cpu_to_le32(slp->length);
6989             ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(slp->length, 512));
6990
6991             if (--sg_elem_cnt == 0)
6992             {   /* Last ADV_SG_BLOCK and scatter-gather entry. */
6993                 sg_block->sg_cnt = i + 1;
6994                 sg_block->sg_ptr = 0L;    /* Last ADV_SG_BLOCK in list. */
6995                 return ADV_SUCCESS;
6996             }
6997             slp++;
6998         }
6999         sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
7000         prev_sg_block = sg_block;
7001     }
7002     while (1);
7003     /* NOTREACHED */
7004 }
7005
7006 /*
7007  * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
7008  *
7009  * Interrupt callback function for the Narrow SCSI Asc Library.
7010  */
7011 STATIC void
7012 asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
7013 {
7014     asc_board_t         *boardp;
7015     Scsi_Cmnd           *scp;
7016     struct Scsi_Host    *shp;
7017     int                 i;
7018
7019     ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
7020         (ulong) asc_dvc_varp, (ulong) qdonep);
7021     ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
7022
7023     /*
7024      * Get the Scsi_Cmnd structure and Scsi_Host structure for the
7025      * command that has been completed.
7026      */
7027     scp = (Scsi_Cmnd *) ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
7028     ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong) scp);
7029
7030     if (scp == NULL) {
7031         ASC_PRINT("asc_isr_callback: scp is NULL\n");
7032         return;
7033     }
7034     ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
7035
7036     /*
7037      * If the request's host pointer is not valid, display a
7038      * message and return.
7039      */
7040     shp = scp->device->host;
7041     for (i = 0; i < asc_board_count; i++) {
7042         if (asc_host[i] == shp) {
7043             break;
7044         }
7045     }
7046     if (i == asc_board_count) {
7047         ASC_PRINT2(
7048             "asc_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
7049             (ulong) scp, (ulong) shp);
7050         return;
7051     }
7052
7053     ASC_STATS(shp, callback);
7054     ASC_DBG1(1, "asc_isr_callback: shp 0x%lx\n", (ulong) shp);
7055
7056     /*
7057      * If the request isn't found on the active queue, it may
7058      * have been removed to handle a reset request.
7059      * Display a message and return.
7060      */
7061     boardp = ASC_BOARDP(shp);
7062     ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
7063     if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
7064         ASC_PRINT2(
7065             "asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
7066             boardp->id, (ulong) scp);
7067         return;
7068     }
7069
7070     /*
7071      * 'qdonep' contains the command's ending status.
7072      */
7073     switch (qdonep->d3.done_stat) {
7074     case QD_NO_ERROR:
7075         ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
7076         scp->result = 0;
7077
7078         /*
7079          * If an INQUIRY command completed successfully, then call
7080          * the AscInquiryHandling() function to set-up the device.
7081          */
7082         if (scp->cmnd[0] == SCSICMD_Inquiry && scp->device->lun == 0 &&
7083             (scp->request_bufflen - qdonep->remain_bytes) >= 8)
7084         {
7085             AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7,
7086                 (ASC_SCSI_INQUIRY *) scp->request_buffer);
7087         }
7088
7089 #if ASC_LINUX_KERNEL24
7090         /*
7091          * Check for an underrun condition.
7092          *
7093          * If there was no error and an underrun condition, then
7094          * then return the number of underrun bytes.
7095          */
7096         if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
7097             qdonep->remain_bytes <= scp->request_bufflen) {
7098             ASC_DBG1(1, "asc_isr_callback: underrun condition %u bytes\n",
7099             (unsigned) qdonep->remain_bytes);
7100             scp->resid = qdonep->remain_bytes;
7101         }
7102 #endif
7103         break;
7104
7105     case QD_WITH_ERROR:
7106         ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
7107         switch (qdonep->d3.host_stat) {
7108         case QHSTA_NO_ERROR:
7109             if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) {
7110                 ASC_DBG(2, "asc_isr_callback: SS_CHK_CONDITION\n");
7111                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
7112                     sizeof(scp->sense_buffer));
7113                 /*
7114                  * Note: The 'status_byte()' macro used by target drivers
7115                  * defined in scsi.h shifts the status byte returned by
7116                  * host drivers right by 1 bit. This is why target drivers
7117                  * also use right shifted status byte definitions. For
7118                  * instance target drivers use CHECK_CONDITION, defined to
7119                  * 0x1, instead of the SCSI defined check condition value
7120                  * of 0x2. Host drivers are supposed to return the status
7121                  * byte as it is defined by SCSI.
7122                  */
7123                 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
7124                     STATUS_BYTE(qdonep->d3.scsi_stat);
7125             } else {
7126                 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
7127             }
7128             break;
7129
7130         default:
7131             /* QHSTA error occurred */
7132             ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
7133                 qdonep->d3.host_stat);
7134             scp->result = HOST_BYTE(DID_BAD_TARGET);
7135             break;
7136         }
7137         break;
7138
7139     case QD_ABORTED_BY_HOST:
7140         ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
7141         scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.scsi_msg) |
7142                 STATUS_BYTE(qdonep->d3.scsi_stat);
7143         break;
7144
7145     default:
7146         ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n", qdonep->d3.done_stat);
7147         scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
7148                 STATUS_BYTE(qdonep->d3.scsi_stat);
7149         break;
7150     }
7151
7152     /*
7153      * If the 'init_tidmask' bit isn't already set for the target and the
7154      * current request finished normally, then set the bit for the target
7155      * to indicate that a device is present.
7156      */
7157     if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
7158         qdonep->d3.done_stat == QD_NO_ERROR &&
7159         qdonep->d3.host_stat == QHSTA_NO_ERROR) {
7160         boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
7161     }
7162
7163     /*
7164      * Because interrupts may be enabled by the 'Scsi_Cmnd' done
7165      * function, add the command to the end of the board's done queue.
7166      * The done function for the command will be called from
7167      * advansys_interrupt().
7168      */
7169     asc_enqueue(&boardp->done, scp, ASC_BACK);
7170
7171     return;
7172 }
7173
7174 /*
7175  * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
7176  *
7177  * Callback function for the Wide SCSI Adv Library.
7178  */
7179 STATIC void
7180 adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
7181 {
7182     asc_board_t         *boardp;
7183     adv_req_t           *reqp;
7184     adv_sgblk_t         *sgblkp;
7185     Scsi_Cmnd           *scp;
7186     struct Scsi_Host    *shp;
7187     int                 i;
7188 #if ASC_LINUX_KERNEL24
7189     ADV_DCNT            resid_cnt;
7190 #endif
7191
7192
7193     ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
7194         (ulong) adv_dvc_varp, (ulong) scsiqp);
7195     ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
7196
7197     /*
7198      * Get the adv_req_t structure for the command that has been
7199      * completed. The adv_req_t structure actually contains the
7200      * completed ADV_SCSI_REQ_Q structure.
7201      */
7202     reqp = (adv_req_t *) ADV_U32_TO_VADDR(scsiqp->srb_ptr);
7203     ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong) reqp);
7204     if (reqp == NULL) {
7205         ASC_PRINT("adv_isr_callback: reqp is NULL\n");
7206         return;
7207     }
7208
7209     /*
7210      * Get the Scsi_Cmnd structure and Scsi_Host structure for the
7211      * command that has been completed.
7212      *
7213      * Note: The adv_req_t request structure and adv_sgblk_t structure,
7214      * if any, are dropped, because a board structure pointer can not be
7215      * determined.
7216      */
7217     scp = reqp->cmndp;
7218     ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong) scp);
7219     if (scp == NULL) {
7220         ASC_PRINT("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
7221         return;
7222     }
7223     ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
7224
7225     /*
7226      * If the request's host pointer is not valid, display a message
7227      * and return.
7228      */
7229     shp = scp->device->host;
7230     for (i = 0; i < asc_board_count; i++) {
7231         if (asc_host[i] == shp) {
7232             break;
7233         }
7234     }
7235     /*
7236      * Note: If the host structure is not found, the adv_req_t request
7237      * structure and adv_sgblk_t structure, if any, is dropped.
7238      */
7239     if (i == asc_board_count) {
7240         ASC_PRINT2(
7241             "adv_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
7242             (ulong) scp, (ulong) shp);
7243         return;
7244     }
7245
7246     ASC_STATS(shp, callback);
7247     ASC_DBG1(1, "adv_isr_callback: shp 0x%lx\n", (ulong) shp);
7248
7249     /*
7250      * If the request isn't found on the active queue, it may have been
7251      * removed to handle a reset request. Display a message and return.
7252      *
7253      * Note: Because the structure may still be in use don't attempt
7254      * to free the adv_req_t and adv_sgblk_t, if any, structures.
7255      */
7256     boardp = ASC_BOARDP(shp);
7257     ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
7258     if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
7259         ASC_PRINT2(
7260             "adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
7261             boardp->id, (ulong) scp);
7262         return;
7263     }
7264
7265     /*
7266      * 'done_status' contains the command's ending status.
7267      */
7268     switch (scsiqp->done_status) {
7269     case QD_NO_ERROR:
7270         ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
7271         scp->result = 0;
7272
7273 #if ASC_LINUX_KERNEL24
7274         /*
7275          * Check for an underrun condition.
7276          *
7277          * If there was no error and an underrun condition, then
7278          * then return the number of underrun bytes.
7279          */
7280         resid_cnt = le32_to_cpu(scsiqp->data_cnt);
7281         if (scp->request_bufflen != 0 && resid_cnt != 0 &&
7282             resid_cnt <= scp->request_bufflen) {
7283             ASC_DBG1(1, "adv_isr_callback: underrun condition %lu bytes\n",
7284                 (ulong) resid_cnt);
7285             scp->resid = resid_cnt;
7286         }
7287 #endif
7288         break;
7289
7290     case QD_WITH_ERROR:
7291         ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
7292         switch (scsiqp->host_status) {
7293         case QHSTA_NO_ERROR:
7294             if (scsiqp->scsi_status == SS_CHK_CONDITION) {
7295                 ASC_DBG(2, "adv_isr_callback: SS_CHK_CONDITION\n");
7296                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
7297                     sizeof(scp->sense_buffer));
7298                 /*
7299                  * Note: The 'status_byte()' macro used by target drivers
7300                  * defined in scsi.h shifts the status byte returned by
7301                  * host drivers right by 1 bit. This is why target drivers
7302                  * also use right shifted status byte definitions. For
7303                  * instance target drivers use CHECK_CONDITION, defined to
7304                  * 0x1, instead of the SCSI defined check condition value
7305                  * of 0x2. Host drivers are supposed to return the status
7306                  * byte as it is defined by SCSI.
7307                  */
7308                 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
7309                     STATUS_BYTE(scsiqp->scsi_status);
7310             } else {
7311                 scp->result = STATUS_BYTE(scsiqp->scsi_status);
7312             }
7313             break;
7314
7315         default:
7316             /* Some other QHSTA error occurred. */
7317             ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
7318                 scsiqp->host_status);
7319             scp->result = HOST_BYTE(DID_BAD_TARGET);
7320             break;
7321         }
7322         break;
7323
7324     case QD_ABORTED_BY_HOST:
7325         ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
7326         scp->result = HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
7327         break;
7328
7329     default:
7330         ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n", scsiqp->done_status);
7331         scp->result = HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
7332         break;
7333     }
7334
7335     /*
7336      * If the 'init_tidmask' bit isn't already set for the target and the
7337      * current request finished normally, then set the bit for the target
7338      * to indicate that a device is present.
7339      */
7340     if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
7341         scsiqp->done_status == QD_NO_ERROR &&
7342         scsiqp->host_status == QHSTA_NO_ERROR) {
7343         boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
7344     }
7345
7346     /*
7347      * Because interrupts may be enabled by the 'Scsi_Cmnd' done
7348      * function, add the command to the end of the board's done queue.
7349      * The done function for the command will be called from
7350      * advansys_interrupt().
7351      */
7352     asc_enqueue(&boardp->done, scp, ASC_BACK);
7353
7354     /*
7355      * Free all 'adv_sgblk_t' structures allocated for the request.
7356      */
7357     while ((sgblkp = reqp->sgblkp) != NULL)
7358     {
7359         /* Remove 'sgblkp' from the request list. */
7360         reqp->sgblkp = sgblkp->next_sgblkp;
7361
7362         /* Add 'sgblkp' to the board free list. */
7363         sgblkp->next_sgblkp = boardp->adv_sgblkp;
7364         boardp->adv_sgblkp = sgblkp;
7365     }
7366
7367     /*
7368      * Free the adv_req_t structure used with the command by adding
7369      * it back to the board free list.
7370      */
7371     reqp->next_reqp = boardp->adv_reqp;
7372     boardp->adv_reqp = reqp;
7373
7374     ASC_DBG(1, "adv_isr_callback: done\n");
7375
7376     return;
7377 }
7378
7379 /*
7380  * adv_async_callback() - Adv Library asynchronous event callback function.
7381  */
7382 STATIC void
7383 adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
7384 {
7385     switch (code)
7386     {
7387     case ADV_ASYNC_SCSI_BUS_RESET_DET:
7388         /*
7389          * The firmware detected a SCSI Bus reset.
7390          */
7391         ASC_DBG(0, "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
7392         break;
7393
7394     case ADV_ASYNC_RDMA_FAILURE:
7395         /*
7396          * Handle RDMA failure by resetting the SCSI Bus and
7397          * possibly the chip if it is unresponsive. Log the error
7398          * with a unique code.
7399          */
7400         ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
7401         AdvResetChipAndSB(adv_dvc_varp);
7402         break;
7403
7404     case ADV_HOST_SCSI_BUS_RESET:
7405         /*
7406          * Host generated SCSI bus reset occurred.
7407          */
7408         ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
7409         break;
7410
7411     default:
7412         ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
7413         break;
7414     }
7415 }
7416
7417 /*
7418  * Add a 'REQP' to the end of specified queue. Set 'tidmask'
7419  * to indicate a command is queued for the device.
7420  *
7421  * 'flag' may be either ASC_FRONT or ASC_BACK.
7422  *
7423  * 'REQPNEXT(reqp)' returns reqp's next pointer.
7424  */
7425 STATIC void
7426 asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
7427 {
7428     int        tid;
7429
7430     ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
7431         (ulong) ascq, (ulong) reqp, flag);
7432     ASC_ASSERT(reqp != NULL);
7433     ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
7434     tid = REQPTID(reqp);
7435     ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7436     if (flag == ASC_FRONT) {
7437         reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
7438         ascq->q_first[tid] = reqp;
7439         /* If the queue was empty, set the last pointer. */
7440         if (ascq->q_last[tid] == NULL) {
7441             ascq->q_last[tid] = reqp;
7442         }
7443     } else { /* ASC_BACK */
7444         if (ascq->q_last[tid] != NULL) {
7445             ascq->q_last[tid]->host_scribble = (unsigned char *)reqp;
7446         }
7447         ascq->q_last[tid] = reqp;
7448         reqp->host_scribble = NULL;
7449         /* If the queue was empty, set the first pointer. */
7450         if (ascq->q_first[tid] == NULL) {
7451             ascq->q_first[tid] = reqp;
7452         }
7453     }
7454     /* The queue has at least one entry, set its bit. */
7455     ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
7456 #ifdef ADVANSYS_STATS
7457     /* Maintain request queue statistics. */
7458     ascq->q_tot_cnt[tid]++;
7459     ascq->q_cur_cnt[tid]++;
7460     if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
7461         ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
7462         ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
7463             tid, ascq->q_max_cnt[tid]);
7464     }
7465     REQPTIME(reqp) = REQTIMESTAMP();
7466 #endif /* ADVANSYS_STATS */
7467     ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong) reqp);
7468     return;
7469 }
7470
7471 /*
7472  * Return first queued 'REQP' on the specified queue for
7473  * the specified target device. Clear the 'tidmask' bit for
7474  * the device if no more commands are left queued for it.
7475  *
7476  * 'REQPNEXT(reqp)' returns reqp's next pointer.
7477  */
7478 STATIC REQP
7479 asc_dequeue(asc_queue_t *ascq, int tid)
7480 {
7481     REQP    reqp;
7482
7483     ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong) ascq, tid);
7484     ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7485     if ((reqp = ascq->q_first[tid]) != NULL) {
7486         ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
7487         ascq->q_first[tid] = REQPNEXT(reqp);
7488         /* If the queue is empty, clear its bit and the last pointer. */
7489         if (ascq->q_first[tid] == NULL) {
7490             ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7491             ASC_ASSERT(ascq->q_last[tid] == reqp);
7492             ascq->q_last[tid] = NULL;
7493         }
7494 #ifdef ADVANSYS_STATS
7495         /* Maintain request queue statistics. */
7496         ascq->q_cur_cnt[tid]--;
7497         ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
7498         REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
7499 #endif /* ADVANSYS_STATS */
7500     }
7501     ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong) reqp);
7502     return reqp;
7503 }
7504
7505 /*
7506  * Return a pointer to a singly linked list of all the requests queued
7507  * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
7508  *
7509  * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
7510  * the last request returned in the singly linked list.
7511  *
7512  * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
7513  * then all queued requests are concatenated into one list and
7514  * returned.
7515  *
7516  * Note: If 'lastpp' is used to append a new list to the end of
7517  * an old list, only change the old list last pointer if '*lastpp'
7518  * (or the function return value) is not NULL, i.e. use a temporary
7519  * variable for 'lastpp' and check its value after the function return
7520  * before assigning it to the list last pointer.
7521  *
7522  * Unfortunately collecting queuing time statistics adds overhead to
7523  * the function that isn't inherent to the function's algorithm.
7524  */
7525 STATIC REQP
7526 asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
7527 {
7528     REQP    firstp, lastp;
7529     int     i;
7530
7531     ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong) ascq, tid);
7532     ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
7533
7534     /*
7535      * If 'tid' is not ASC_TID_ALL, return requests only for
7536      * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
7537      * requests for all tids.
7538      */
7539     if (tid != ASC_TID_ALL) {
7540         /* Return all requests for the specified 'tid'. */
7541         if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
7542             /* List is empty; Set first and last return pointers to NULL. */
7543             firstp = lastp = NULL;
7544         } else {
7545             firstp = ascq->q_first[tid];
7546             lastp = ascq->q_last[tid];
7547             ascq->q_first[tid] = ascq->q_last[tid] = NULL;
7548             ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7549 #ifdef ADVANSYS_STATS
7550             {
7551                 REQP reqp;
7552                 ascq->q_cur_cnt[tid] = 0;
7553                 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
7554                     REQTIMESTAT("asc_dequeue_list", ascq, reqp, tid);
7555                 }
7556             }
7557 #endif /* ADVANSYS_STATS */
7558         }
7559     } else {
7560         /* Return all requests for all tids. */
7561         firstp = lastp = NULL;
7562         for (i = 0; i <= ADV_MAX_TID; i++) {
7563             if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
7564                 if (firstp == NULL) {
7565                     firstp = ascq->q_first[i];
7566                     lastp = ascq->q_last[i];
7567                 } else {
7568                     ASC_ASSERT(lastp != NULL);
7569                     lastp->host_scribble = (unsigned char *)ascq->q_first[i];
7570                     lastp = ascq->q_last[i];
7571                 }
7572                 ascq->q_first[i] = ascq->q_last[i] = NULL;
7573                 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7574 #ifdef ADVANSYS_STATS
7575                 ascq->q_cur_cnt[i] = 0;
7576 #endif /* ADVANSYS_STATS */
7577             }
7578         }
7579 #ifdef ADVANSYS_STATS
7580         {
7581             REQP reqp;
7582             for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
7583                 REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->device->id);
7584             }
7585         }
7586 #endif /* ADVANSYS_STATS */
7587     }
7588     if (lastpp) {
7589         *lastpp = lastp;
7590     }
7591     ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong) firstp);
7592     return firstp;
7593 }
7594
7595 /*
7596  * Remove the specified 'REQP' from the specified queue for
7597  * the specified target device. Clear the 'tidmask' bit for the
7598  * device if no more commands are left queued for it.
7599  *
7600  * 'REQPNEXT(reqp)' returns reqp's the next pointer.
7601  *
7602  * Return ASC_TRUE if the command was found and removed,
7603  * otherwise return ASC_FALSE.
7604  */
7605 STATIC int
7606 asc_rmqueue(asc_queue_t *ascq, REQP reqp)
7607 {
7608     REQP        currp, prevp;
7609     int         tid;
7610     int         ret = ASC_FALSE;
7611
7612     ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
7613         (ulong) ascq, (ulong) reqp);
7614     ASC_ASSERT(reqp != NULL);
7615
7616     tid = REQPTID(reqp);
7617     ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7618
7619     /*
7620      * Handle the common case of 'reqp' being the first
7621      * entry on the queue.
7622      */
7623     if (reqp == ascq->q_first[tid]) {
7624         ret = ASC_TRUE;
7625         ascq->q_first[tid] = REQPNEXT(reqp);
7626         /* If the queue is now empty, clear its bit and the last pointer. */
7627         if (ascq->q_first[tid] == NULL) {
7628             ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7629             ASC_ASSERT(ascq->q_last[tid] == reqp);
7630             ascq->q_last[tid] = NULL;
7631         }
7632     } else if (ascq->q_first[tid] != NULL) {
7633         ASC_ASSERT(ascq->q_last[tid] != NULL);
7634         /*
7635          * Because the case of 'reqp' being the first entry has been
7636          * handled above and it is known the queue is not empty, if
7637          * 'reqp' is found on the queue it is guaranteed the queue will
7638          * not become empty and that 'q_first[tid]' will not be changed.
7639          *
7640          * Set 'prevp' to the first entry, 'currp' to the second entry,
7641          * and search for 'reqp'.
7642          */
7643         for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
7644              currp; prevp = currp, currp = REQPNEXT(currp)) {
7645             if (currp == reqp) {
7646                 ret = ASC_TRUE;
7647                 prevp->host_scribble = (unsigned char *)REQPNEXT(currp);
7648                 reqp->host_scribble = NULL;
7649                 if (ascq->q_last[tid] == reqp) {
7650                     ascq->q_last[tid] = prevp;
7651                 }
7652                 break;
7653             }
7654         }
7655     }
7656 #ifdef ADVANSYS_STATS
7657     /* Maintain request queue statistics. */
7658     if (ret == ASC_TRUE) {
7659         ascq->q_cur_cnt[tid]--;
7660         REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
7661     }
7662     ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
7663 #endif /* ADVANSYS_STATS */
7664     ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong) reqp, ret);
7665     return ret;
7666 }
7667
7668 /*
7669  * Execute as many queued requests as possible for the specified queue.
7670  *
7671  * Calls asc_execute_scsi_cmnd() to execute a REQP/Scsi_Cmnd.
7672  */
7673 STATIC void
7674 asc_execute_queue(asc_queue_t *ascq)
7675 {
7676     ADV_SCSI_BIT_ID_TYPE    scan_tidmask;
7677     REQP                    reqp;
7678     int                     i;
7679
7680     ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong) ascq);
7681     /*
7682      * Execute queued commands for devices attached to
7683      * the current board in round-robin fashion.
7684      */
7685     scan_tidmask = ascq->q_tidmask;
7686     do {
7687         for (i = 0; i <= ADV_MAX_TID; i++) {
7688             if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
7689                 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
7690                     scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7691                 } else if (asc_execute_scsi_cmnd((Scsi_Cmnd *) reqp)
7692                             == ASC_BUSY) {
7693                     scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7694                     /*
7695                      * The request returned ASC_BUSY. Enqueue at the front of
7696                      * target's waiting list to maintain correct ordering.
7697                      */
7698                     asc_enqueue(ascq, reqp, ASC_FRONT);
7699                 }
7700             }
7701         }
7702     } while (scan_tidmask);
7703     return;
7704 }
7705
7706 #ifdef CONFIG_PROC_FS
7707 /*
7708  * asc_prt_board_devices()
7709  *
7710  * Print driver information for devices attached to the board.
7711  *
7712  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7713  * cf. asc_prt_line().
7714  *
7715  * Return the number of characters copied into 'cp'. No more than
7716  * 'cplen' characters will be copied to 'cp'.
7717  */
7718 STATIC int
7719 asc_prt_board_devices(struct Scsi_Host *shp, char *cp, int cplen)
7720 {
7721     asc_board_t        *boardp;
7722     int                leftlen;
7723     int                totlen;
7724     int                len;
7725     int                chip_scsi_id;
7726     int                i;
7727
7728     boardp = ASC_BOARDP(shp);
7729     leftlen = cplen;
7730     totlen = len = 0;
7731
7732     len = asc_prt_line(cp, leftlen,
7733 "\nDevice Information for AdvanSys SCSI Host %d:\n", shp->host_no);
7734     ASC_PRT_NEXT();
7735
7736     if (ASC_NARROW_BOARD(boardp)) {
7737         chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7738     } else {
7739         chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7740     }
7741
7742     len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
7743     ASC_PRT_NEXT();
7744     for (i = 0; i <= ADV_MAX_TID; i++) {
7745         if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
7746             len = asc_prt_line(cp, leftlen, " %X,", i);
7747             ASC_PRT_NEXT();
7748         }
7749     }
7750     len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
7751     ASC_PRT_NEXT();
7752
7753     return totlen;
7754 }
7755
7756 /*
7757  * Display Wide Board BIOS Information.
7758  */
7759 STATIC int
7760 asc_prt_adv_bios(struct Scsi_Host *shp, char *cp, int cplen)
7761 {
7762     asc_board_t        *boardp;
7763     int                leftlen;
7764     int                totlen;
7765     int                len;
7766     ushort             major, minor, letter;
7767
7768     boardp = ASC_BOARDP(shp);
7769     leftlen = cplen;
7770     totlen = len = 0;
7771
7772     len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
7773     ASC_PRT_NEXT();
7774
7775     /*
7776      * If the BIOS saved a valid signature, then fill in
7777      * the BIOS code segment base address.
7778      */
7779     if (boardp->bios_signature != 0x55AA) {
7780         len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
7781         ASC_PRT_NEXT();
7782         len = asc_prt_line(cp, leftlen,
7783 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
7784         ASC_PRT_NEXT();
7785         len = asc_prt_line(cp, leftlen,
7786 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
7787         ASC_PRT_NEXT();
7788     } else {
7789         major = (boardp->bios_version >> 12) & 0xF;
7790         minor = (boardp->bios_version >> 8) & 0xF;
7791         letter = (boardp->bios_version & 0xFF);
7792
7793         len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
7794             major, minor, letter >= 26 ? '?' : letter + 'A');
7795         ASC_PRT_NEXT();
7796
7797         /*
7798          * Current available ROM BIOS release is 3.1I for UW
7799          * and 3.2I for U2W. This code doesn't differentiate
7800          * UW and U2W boards.
7801          */
7802         if (major < 3 || (major <= 3 && minor < 1) ||
7803             (major <= 3 && minor <= 1 && letter < ('I'- 'A'))) {
7804             len = asc_prt_line(cp, leftlen,
7805 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
7806             ASC_PRT_NEXT();
7807             len = asc_prt_line(cp, leftlen,
7808 "ftp://ftp.connectcom.net/pub\n");
7809             ASC_PRT_NEXT();
7810         }
7811     }
7812
7813     return totlen;
7814 }
7815
7816 /*
7817  * Add serial number to information bar if signature AAh
7818  * is found in at bit 15-9 (7 bits) of word 1.
7819  *
7820  * Serial Number consists fo 12 alpha-numeric digits.
7821  *
7822  *       1 - Product type (A,B,C,D..)  Word0: 15-13 (3 bits)
7823  *       2 - MFG Location (A,B,C,D..)  Word0: 12-10 (3 bits)
7824  *     3-4 - Product ID (0-99)         Word0: 9-0 (10 bits)
7825  *       5 - Product revision (A-J)    Word0:  "         "
7826  *
7827  *           Signature                 Word1: 15-9 (7 bits)
7828  *       6 - Year (0-9)                Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
7829  *     7-8 - Week of the year (1-52)   Word1: 5-0 (6 bits)
7830  *
7831  *    9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
7832  *
7833  * Note 1: Only production cards will have a serial number.
7834  *
7835  * Note 2: Signature is most significant 7 bits (0xFE).
7836  *
7837  * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
7838  */
7839 STATIC int
7840 asc_get_eeprom_string(ushort *serialnum, uchar *cp)
7841 {
7842     ushort      w, num;
7843
7844     if ((serialnum[1] & 0xFE00) != ((ushort) 0xAA << 8)) {
7845         return ASC_FALSE;
7846     } else {
7847         /*
7848          * First word - 6 digits.
7849          */
7850         w = serialnum[0];
7851
7852         /* Product type - 1st digit. */
7853         if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
7854             /* Product type is P=Prototype */
7855             *cp += 0x8;
7856         }
7857         cp++;
7858
7859         /* Manufacturing location - 2nd digit. */
7860         *cp++ = 'A' + ((w & 0x1C00) >> 10);
7861
7862         /* Product ID - 3rd, 4th digits. */
7863         num = w & 0x3FF;
7864         *cp++ = '0' + (num / 100);
7865         num %= 100;
7866         *cp++ = '0' + (num / 10);
7867
7868         /* Product revision - 5th digit. */
7869         *cp++ = 'A' + (num % 10);
7870
7871         /*
7872          * Second word
7873          */
7874         w = serialnum[1];
7875
7876         /*
7877          * Year - 6th digit.
7878          *
7879          * If bit 15 of third word is set, then the
7880          * last digit of the year is greater than 7.
7881          */
7882         if (serialnum[2] & 0x8000) {
7883             *cp++ = '8' + ((w & 0x1C0) >> 6);
7884         } else {
7885             *cp++ = '0' + ((w & 0x1C0) >> 6);
7886         }
7887
7888         /* Week of year - 7th, 8th digits. */
7889         num = w & 0x003F;
7890         *cp++ = '0' + num / 10;
7891         num %= 10;
7892         *cp++ = '0' + num;
7893
7894         /*
7895          * Third word
7896          */
7897         w = serialnum[2] & 0x7FFF;
7898
7899         /* Serial number - 9th digit. */
7900         *cp++ = 'A' + (w / 1000);
7901
7902         /* 10th, 11th, 12th digits. */
7903         num = w % 1000;
7904         *cp++ = '0' + num / 100;
7905         num %= 100;
7906         *cp++ = '0' + num / 10;
7907         num %= 10;
7908         *cp++ = '0' + num;
7909
7910         *cp = '\0';     /* Null Terminate the string. */
7911         return ASC_TRUE;
7912     }
7913 }
7914
7915 /*
7916  * asc_prt_asc_board_eeprom()
7917  *
7918  * Print board EEPROM configuration.
7919  *
7920  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7921  * cf. asc_prt_line().
7922  *
7923  * Return the number of characters copied into 'cp'. No more than
7924  * 'cplen' characters will be copied to 'cp'.
7925  */
7926 STATIC int
7927 asc_prt_asc_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
7928 {
7929     asc_board_t        *boardp;
7930     ASC_DVC_VAR        *asc_dvc_varp;
7931     int                leftlen;
7932     int                totlen;
7933     int                len;
7934     ASCEEP_CONFIG      *ep;
7935     int                i;
7936 #ifdef CONFIG_ISA
7937     int                isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
7938 #endif /* CONFIG_ISA */
7939     uchar              serialstr[13];
7940
7941     boardp = ASC_BOARDP(shp);
7942     asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
7943     ep = &boardp->eep_config.asc_eep;
7944
7945     leftlen = cplen;
7946     totlen = len = 0;
7947
7948     len = asc_prt_line(cp, leftlen,
7949 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
7950     ASC_PRT_NEXT();
7951
7952     if (asc_get_eeprom_string((ushort *) &ep->adapter_info[0], serialstr) ==
7953         ASC_TRUE) {
7954         len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
7955         ASC_PRT_NEXT();
7956     } else {
7957         if (ep->adapter_info[5] == 0xBB) {
7958             len = asc_prt_line(cp, leftlen,
7959                 " Default Settings Used for EEPROM-less Adapter.\n");
7960             ASC_PRT_NEXT();
7961         } else {
7962             len = asc_prt_line(cp, leftlen,
7963                 " Serial Number Signature Not Present.\n");
7964             ASC_PRT_NEXT();
7965         }
7966     }
7967
7968     len = asc_prt_line(cp, leftlen,
7969 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7970         ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng, ep->max_tag_qng);
7971     ASC_PRT_NEXT();
7972
7973     len = asc_prt_line(cp, leftlen,
7974 " cntl 0x%x, no_scam 0x%x\n",
7975         ep->cntl, ep->no_scam);
7976     ASC_PRT_NEXT();
7977
7978     len = asc_prt_line(cp, leftlen,
7979 " Target ID:           ");
7980     ASC_PRT_NEXT();
7981     for (i = 0; i <= ASC_MAX_TID; i++) {
7982         len = asc_prt_line(cp, leftlen, " %d", i);
7983         ASC_PRT_NEXT();
7984     }
7985     len = asc_prt_line(cp, leftlen, "\n");
7986     ASC_PRT_NEXT();
7987
7988     len = asc_prt_line(cp, leftlen,
7989 " Disconnects:         ");
7990     ASC_PRT_NEXT();
7991     for (i = 0; i <= ASC_MAX_TID; i++) {
7992         len = asc_prt_line(cp, leftlen, " %c",
7993             (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7994         ASC_PRT_NEXT();
7995     }
7996     len = asc_prt_line(cp, leftlen, "\n");
7997     ASC_PRT_NEXT();
7998
7999     len = asc_prt_line(cp, leftlen,
8000 " Command Queuing:     ");
8001     ASC_PRT_NEXT();
8002     for (i = 0; i <= ASC_MAX_TID; i++) {
8003         len = asc_prt_line(cp, leftlen, " %c",
8004             (ep->use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8005         ASC_PRT_NEXT();
8006     }
8007     len = asc_prt_line(cp, leftlen, "\n");
8008     ASC_PRT_NEXT();
8009
8010     len = asc_prt_line(cp, leftlen,
8011 " Start Motor:         ");
8012     ASC_PRT_NEXT();
8013     for (i = 0; i <= ASC_MAX_TID; i++) {
8014         len = asc_prt_line(cp, leftlen, " %c",
8015             (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8016         ASC_PRT_NEXT();
8017     }
8018     len = asc_prt_line(cp, leftlen, "\n");
8019     ASC_PRT_NEXT();
8020
8021     len = asc_prt_line(cp, leftlen,
8022 " Synchronous Transfer:");
8023     ASC_PRT_NEXT();
8024     for (i = 0; i <= ASC_MAX_TID; i++) {
8025         len = asc_prt_line(cp, leftlen, " %c",
8026             (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8027         ASC_PRT_NEXT();
8028     }
8029     len = asc_prt_line(cp, leftlen, "\n");
8030     ASC_PRT_NEXT();
8031
8032 #ifdef CONFIG_ISA
8033     if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
8034         len = asc_prt_line(cp, leftlen,
8035 " Host ISA DMA speed:   %d MB/S\n",
8036             isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
8037         ASC_PRT_NEXT();
8038     }
8039 #endif /* CONFIG_ISA */
8040
8041      return totlen;
8042 }
8043
8044 /*
8045  * asc_prt_adv_board_eeprom()
8046  *
8047  * Print board EEPROM configuration.
8048  *
8049  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8050  * cf. asc_prt_line().
8051  *
8052  * Return the number of characters copied into 'cp'. No more than
8053  * 'cplen' characters will be copied to 'cp'.
8054  */
8055 STATIC int
8056 asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
8057 {
8058     asc_board_t                 *boardp;
8059     ADV_DVC_VAR                 *adv_dvc_varp;
8060     int                         leftlen;
8061     int                         totlen;
8062     int                         len;
8063     int                         i;
8064     char                        *termstr;
8065     uchar                       serialstr[13];
8066     ADVEEP_3550_CONFIG          *ep_3550 = NULL;
8067     ADVEEP_38C0800_CONFIG       *ep_38C0800 = NULL;
8068     ADVEEP_38C1600_CONFIG       *ep_38C1600 = NULL;
8069     ushort                      word;
8070     ushort                      *wordp;
8071     ushort                      sdtr_speed = 0;
8072
8073     boardp = ASC_BOARDP(shp);
8074     adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
8075     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8076     {
8077         ep_3550 = &boardp->eep_config.adv_3550_eep;
8078     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8079     {
8080         ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
8081     } else
8082     {
8083         ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
8084     }
8085
8086     leftlen = cplen;
8087     totlen = len = 0;
8088
8089     len = asc_prt_line(cp, leftlen,
8090 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
8091     ASC_PRT_NEXT();
8092
8093     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8094     {
8095         wordp = &ep_3550->serial_number_word1;
8096     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8097     {
8098         wordp = &ep_38C0800->serial_number_word1;
8099     } else
8100     {
8101         wordp = &ep_38C1600->serial_number_word1;
8102     }
8103
8104     if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
8105         len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
8106         ASC_PRT_NEXT();
8107     } else {
8108         len = asc_prt_line(cp, leftlen,
8109             " Serial Number Signature Not Present.\n");
8110         ASC_PRT_NEXT();
8111     }
8112
8113     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8114     {
8115         len = asc_prt_line(cp, leftlen,
8116 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
8117             ep_3550->adapter_scsi_id, ep_3550->max_host_qng,
8118             ep_3550->max_dvc_qng);
8119         ASC_PRT_NEXT();
8120     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8121     {
8122         len = asc_prt_line(cp, leftlen,
8123 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
8124             ep_38C0800->adapter_scsi_id, ep_38C0800->max_host_qng,
8125             ep_38C0800->max_dvc_qng);
8126         ASC_PRT_NEXT();
8127     } else
8128     {
8129         len = asc_prt_line(cp, leftlen,
8130 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
8131             ep_38C1600->adapter_scsi_id, ep_38C1600->max_host_qng,
8132             ep_38C1600->max_dvc_qng);
8133         ASC_PRT_NEXT();
8134     }
8135     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8136     {
8137         word = ep_3550->termination;
8138     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8139     {
8140         word = ep_38C0800->termination_lvd;
8141     } else
8142     {
8143         word = ep_38C1600->termination_lvd;
8144     }
8145     switch (word) {
8146         case 1:
8147             termstr = "Low Off/High Off";
8148             break;
8149         case 2:
8150             termstr = "Low Off/High On";
8151             break;
8152         case 3:
8153             termstr = "Low On/High On";
8154             break;
8155         default:
8156         case 0:
8157             termstr = "Automatic";
8158             break;
8159     }
8160
8161     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8162     {
8163         len = asc_prt_line(cp, leftlen,
8164 " termination: %u (%s), bios_ctrl: 0x%x\n",
8165             ep_3550->termination, termstr, ep_3550->bios_ctrl);
8166         ASC_PRT_NEXT();
8167     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8168     {
8169         len = asc_prt_line(cp, leftlen,
8170 " termination: %u (%s), bios_ctrl: 0x%x\n",
8171             ep_38C0800->termination_lvd, termstr, ep_38C0800->bios_ctrl);
8172         ASC_PRT_NEXT();
8173     } else
8174     {
8175         len = asc_prt_line(cp, leftlen,
8176 " termination: %u (%s), bios_ctrl: 0x%x\n",
8177             ep_38C1600->termination_lvd, termstr, ep_38C1600->bios_ctrl);
8178         ASC_PRT_NEXT();
8179     }
8180
8181     len = asc_prt_line(cp, leftlen,
8182 " Target ID:           ");
8183     ASC_PRT_NEXT();
8184     for (i = 0; i <= ADV_MAX_TID; i++) {
8185         len = asc_prt_line(cp, leftlen, " %X", i);
8186         ASC_PRT_NEXT();
8187     }
8188     len = asc_prt_line(cp, leftlen, "\n");
8189     ASC_PRT_NEXT();
8190
8191     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8192     {
8193         word = ep_3550->disc_enable;
8194     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8195     {
8196         word = ep_38C0800->disc_enable;
8197     } else
8198     {
8199         word = ep_38C1600->disc_enable;
8200     }
8201     len = asc_prt_line(cp, leftlen,
8202 " Disconnects:         ");
8203     ASC_PRT_NEXT();
8204     for (i = 0; i <= ADV_MAX_TID; i++) {
8205         len = asc_prt_line(cp, leftlen, " %c",
8206             (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8207         ASC_PRT_NEXT();
8208     }
8209     len = asc_prt_line(cp, leftlen, "\n");
8210     ASC_PRT_NEXT();
8211
8212     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8213     {
8214         word = ep_3550->tagqng_able;
8215     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8216     {
8217         word = ep_38C0800->tagqng_able;
8218     } else
8219     {
8220         word = ep_38C1600->tagqng_able;
8221     }
8222     len = asc_prt_line(cp, leftlen,
8223 " Command Queuing:     ");
8224     ASC_PRT_NEXT();
8225     for (i = 0; i <= ADV_MAX_TID; i++) {
8226         len = asc_prt_line(cp, leftlen, " %c",
8227             (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8228         ASC_PRT_NEXT();
8229     }
8230     len = asc_prt_line(cp, leftlen, "\n");
8231     ASC_PRT_NEXT();
8232
8233     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8234     {
8235         word = ep_3550->start_motor;
8236     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8237     {
8238         word = ep_38C0800->start_motor;
8239     } else
8240     {
8241         word = ep_38C1600->start_motor;
8242     }
8243     len = asc_prt_line(cp, leftlen,
8244 " Start Motor:         ");
8245     ASC_PRT_NEXT();
8246     for (i = 0; i <= ADV_MAX_TID; i++) {
8247         len = asc_prt_line(cp, leftlen, " %c",
8248             (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8249         ASC_PRT_NEXT();
8250     }
8251     len = asc_prt_line(cp, leftlen, "\n");
8252     ASC_PRT_NEXT();
8253
8254     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8255     {
8256         len = asc_prt_line(cp, leftlen,
8257 " Synchronous Transfer:");
8258         ASC_PRT_NEXT();
8259         for (i = 0; i <= ADV_MAX_TID; i++) {
8260             len = asc_prt_line(cp, leftlen, " %c",
8261                 (ep_3550->sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8262             ASC_PRT_NEXT();
8263         }
8264         len = asc_prt_line(cp, leftlen, "\n");
8265         ASC_PRT_NEXT();
8266     }
8267
8268     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8269     {
8270         len = asc_prt_line(cp, leftlen,
8271 " Ultra Transfer:      ");
8272     ASC_PRT_NEXT();
8273         for (i = 0; i <= ADV_MAX_TID; i++) {
8274             len = asc_prt_line(cp, leftlen, " %c",
8275                 (ep_3550->ultra_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8276             ASC_PRT_NEXT();
8277         }
8278         len = asc_prt_line(cp, leftlen, "\n");
8279         ASC_PRT_NEXT();
8280     }
8281
8282     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8283     {
8284         word = ep_3550->wdtr_able;
8285     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8286     {
8287         word = ep_38C0800->wdtr_able;
8288     } else
8289     {
8290         word = ep_38C1600->wdtr_able;
8291     }
8292     len = asc_prt_line(cp, leftlen,
8293 " Wide Transfer:       ");
8294     ASC_PRT_NEXT();
8295     for (i = 0; i <= ADV_MAX_TID; i++) {
8296         len = asc_prt_line(cp, leftlen, " %c",
8297             (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8298         ASC_PRT_NEXT();
8299     }
8300     len = asc_prt_line(cp, leftlen, "\n");
8301     ASC_PRT_NEXT();
8302
8303     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
8304         adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600)
8305     {
8306         len = asc_prt_line(cp, leftlen,
8307 " Synchronous Transfer Speed (Mhz):\n  ");
8308         ASC_PRT_NEXT();
8309         for (i = 0; i <= ADV_MAX_TID; i++) {
8310             char *speed_str;
8311
8312             if (i == 0)
8313             {
8314                 sdtr_speed = adv_dvc_varp->sdtr_speed1;
8315             } else if (i == 4)
8316             {
8317                 sdtr_speed = adv_dvc_varp->sdtr_speed2;
8318             } else if (i == 8)
8319             {
8320                 sdtr_speed = adv_dvc_varp->sdtr_speed3;
8321             } else if (i == 12)
8322             {
8323                 sdtr_speed = adv_dvc_varp->sdtr_speed4;
8324             }
8325             switch (sdtr_speed & ADV_MAX_TID)
8326             {
8327                 case 0:  speed_str = "Off"; break;
8328                 case 1:  speed_str = "  5"; break;
8329                 case 2:  speed_str = " 10"; break;
8330                 case 3:  speed_str = " 20"; break;
8331                 case 4:  speed_str = " 40"; break;
8332                 case 5:  speed_str = " 80"; break;
8333                 default: speed_str = "Unk"; break;
8334             }
8335             len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
8336             ASC_PRT_NEXT();
8337             if (i == 7)
8338             {
8339                 len = asc_prt_line(cp, leftlen, "\n  ");
8340                 ASC_PRT_NEXT();
8341             }
8342             sdtr_speed >>= 4;
8343         }
8344         len = asc_prt_line(cp, leftlen, "\n");
8345         ASC_PRT_NEXT();
8346     }
8347
8348     return totlen;
8349 }
8350
8351 /*
8352  * asc_prt_driver_conf()
8353  *
8354  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8355  * cf. asc_prt_line().
8356  *
8357  * Return the number of characters copied into 'cp'. No more than
8358  * 'cplen' characters will be copied to 'cp'.
8359  */
8360 STATIC int
8361 asc_prt_driver_conf(struct Scsi_Host *shp, char *cp, int cplen)
8362 {
8363     asc_board_t            *boardp;
8364     int                    leftlen;
8365     int                    totlen;
8366     int                    len;
8367     int                    chip_scsi_id;
8368
8369     boardp = ASC_BOARDP(shp);
8370
8371     leftlen = cplen;
8372     totlen = len = 0;
8373
8374     len = asc_prt_line(cp, leftlen,
8375 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
8376         shp->host_no);
8377     ASC_PRT_NEXT();
8378
8379     len = asc_prt_line(cp, leftlen,
8380 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
8381         shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun,
8382         shp->max_channel);
8383     ASC_PRT_NEXT();
8384
8385     len = asc_prt_line(cp, leftlen,
8386 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
8387         shp->unique_id, shp->can_queue, shp->this_id, shp->sg_tablesize,
8388         shp->cmd_per_lun);
8389     ASC_PRT_NEXT();
8390
8391     len = asc_prt_line(cp, leftlen,
8392 " unchecked_isa_dma %d, use_clustering %d\n",
8393         shp->unchecked_isa_dma, shp->use_clustering);
8394     ASC_PRT_NEXT();
8395
8396     len = asc_prt_line(cp, leftlen,
8397 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
8398         boardp->flags, boardp->last_reset, jiffies, boardp->asc_n_io_port);
8399     ASC_PRT_NEXT();
8400
8401      /* 'shp->n_io_port' may be truncated because it is only one byte. */
8402     len = asc_prt_line(cp, leftlen,
8403 " io_port 0x%x, n_io_port 0x%x\n",
8404         shp->io_port, shp->n_io_port);
8405     ASC_PRT_NEXT();
8406
8407     if (ASC_NARROW_BOARD(boardp)) {
8408         chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
8409     } else {
8410         chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
8411     }
8412
8413     return totlen;
8414 }
8415
8416 /*
8417  * asc_prt_asc_board_info()
8418  *
8419  * Print dynamic board configuration information.
8420  *
8421  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8422  * cf. asc_prt_line().
8423  *
8424  * Return the number of characters copied into 'cp'. No more than
8425  * 'cplen' characters will be copied to 'cp'.
8426  */
8427 STATIC int
8428 asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8429 {
8430     asc_board_t            *boardp;
8431     int                    chip_scsi_id;
8432     int                    leftlen;
8433     int                    totlen;
8434     int                    len;
8435     ASC_DVC_VAR            *v;
8436     ASC_DVC_CFG            *c;
8437     int                    i;
8438     int                    renegotiate = 0;
8439
8440     boardp = ASC_BOARDP(shp);
8441     v = &boardp->dvc_var.asc_dvc_var;
8442     c = &boardp->dvc_cfg.asc_dvc_cfg;
8443     chip_scsi_id = c->chip_scsi_id;
8444
8445     leftlen = cplen;
8446     totlen = len = 0;
8447
8448     len = asc_prt_line(cp, leftlen,
8449 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8450     shp->host_no);
8451     ASC_PRT_NEXT();
8452
8453     len = asc_prt_line(cp, leftlen,
8454 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
8455         c->chip_version, c->lib_version, c->lib_serial_no, c->mcode_date);
8456     ASC_PRT_NEXT();
8457
8458     len = asc_prt_line(cp, leftlen,
8459 " mcode_version 0x%x, err_code %u\n",
8460          c->mcode_version, v->err_code);
8461     ASC_PRT_NEXT();
8462
8463     /* Current number of commands waiting for the host. */
8464     len = asc_prt_line(cp, leftlen,
8465 " Total Command Pending: %d\n", v->cur_total_qng);
8466     ASC_PRT_NEXT();
8467
8468     len = asc_prt_line(cp, leftlen,
8469 " Command Queuing:");
8470     ASC_PRT_NEXT();
8471     for (i = 0; i <= ASC_MAX_TID; i++) {
8472         if ((chip_scsi_id == i) ||
8473             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8474             continue;
8475         }
8476         len = asc_prt_line(cp, leftlen, " %X:%c",
8477             i, (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8478         ASC_PRT_NEXT();
8479     }
8480     len = asc_prt_line(cp, leftlen, "\n");
8481     ASC_PRT_NEXT();
8482
8483     /* Current number of commands waiting for a device. */
8484     len = asc_prt_line(cp, leftlen,
8485 " Command Queue Pending:");
8486     ASC_PRT_NEXT();
8487     for (i = 0; i <= ASC_MAX_TID; i++) {
8488         if ((chip_scsi_id == i) ||
8489             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8490             continue;
8491         }
8492         len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
8493         ASC_PRT_NEXT();
8494     }
8495     len = asc_prt_line(cp, leftlen, "\n");
8496     ASC_PRT_NEXT();
8497
8498     /* Current limit on number of commands that can be sent to a device. */
8499     len = asc_prt_line(cp, leftlen,
8500 " Command Queue Limit:");
8501     ASC_PRT_NEXT();
8502     for (i = 0; i <= ASC_MAX_TID; i++) {
8503         if ((chip_scsi_id == i) ||
8504             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8505             continue;
8506         }
8507         len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
8508         ASC_PRT_NEXT();
8509     }
8510     len = asc_prt_line(cp, leftlen, "\n");
8511     ASC_PRT_NEXT();
8512
8513     /* Indicate whether the device has returned queue full status. */
8514     len = asc_prt_line(cp, leftlen,
8515 " Command Queue Full:");
8516     ASC_PRT_NEXT();
8517     for (i = 0; i <= ASC_MAX_TID; i++) {
8518         if ((chip_scsi_id == i) ||
8519             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8520             continue;
8521         }
8522         if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
8523             len = asc_prt_line(cp, leftlen, " %X:Y-%d",
8524                 i, boardp->queue_full_cnt[i]);
8525         } else {
8526             len = asc_prt_line(cp, leftlen, " %X:N", i);
8527         }
8528         ASC_PRT_NEXT();
8529     }
8530     len = asc_prt_line(cp, leftlen, "\n");
8531     ASC_PRT_NEXT();
8532
8533     len = asc_prt_line(cp, leftlen,
8534 " Synchronous Transfer:");
8535     ASC_PRT_NEXT();
8536     for (i = 0; i <= ASC_MAX_TID; i++) {
8537         if ((chip_scsi_id == i) ||
8538             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8539             continue;
8540         }
8541         len = asc_prt_line(cp, leftlen, " %X:%c",
8542             i, (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8543         ASC_PRT_NEXT();
8544     }
8545     len = asc_prt_line(cp, leftlen, "\n");
8546     ASC_PRT_NEXT();
8547
8548     for (i = 0; i <= ASC_MAX_TID; i++) {
8549         uchar syn_period_ix;
8550
8551         if ((chip_scsi_id == i) ||
8552             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
8553             ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
8554             continue;
8555         }
8556
8557         len = asc_prt_line(cp, leftlen, "  %X:", i);
8558         ASC_PRT_NEXT();
8559
8560         if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0)
8561         {
8562             len = asc_prt_line(cp, leftlen, " Asynchronous");
8563             ASC_PRT_NEXT();
8564         } else
8565         {
8566             syn_period_ix =
8567                 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1);
8568
8569             len = asc_prt_line(cp, leftlen,
8570                 " Transfer Period Factor: %d (%d.%d Mhz),",
8571                 v->sdtr_period_tbl[syn_period_ix],
8572                 250 / v->sdtr_period_tbl[syn_period_ix],
8573                 ASC_TENTHS(250, v->sdtr_period_tbl[syn_period_ix]));
8574             ASC_PRT_NEXT();
8575
8576             len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
8577                 boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET);
8578             ASC_PRT_NEXT();
8579         }
8580
8581         if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8582             len = asc_prt_line(cp, leftlen, "*\n");
8583             renegotiate = 1;
8584         } else
8585         {
8586             len = asc_prt_line(cp, leftlen, "\n");
8587         }
8588         ASC_PRT_NEXT();
8589     }
8590
8591     if (renegotiate)
8592     {
8593         len = asc_prt_line(cp, leftlen,
8594             " * = Re-negotiation pending before next command.\n");
8595         ASC_PRT_NEXT();
8596     }
8597
8598     return totlen;
8599 }
8600
8601 /*
8602  * asc_prt_adv_board_info()
8603  *
8604  * Print dynamic board configuration information.
8605  *
8606  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8607  * cf. asc_prt_line().
8608  *
8609  * Return the number of characters copied into 'cp'. No more than
8610  * 'cplen' characters will be copied to 'cp'.
8611  */
8612 STATIC int
8613 asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8614 {
8615     asc_board_t            *boardp;
8616     int                    leftlen;
8617     int                    totlen;
8618     int                    len;
8619     int                    i;
8620     ADV_DVC_VAR            *v;
8621     ADV_DVC_CFG            *c;
8622     AdvPortAddr            iop_base;
8623     ushort                 chip_scsi_id;
8624     ushort                 lramword;
8625     uchar                  lrambyte;
8626     ushort                 tagqng_able;
8627     ushort                 sdtr_able, wdtr_able;
8628     ushort                 wdtr_done, sdtr_done;
8629     ushort                 period = 0;
8630     int                    renegotiate = 0;
8631
8632     boardp = ASC_BOARDP(shp);
8633     v = &boardp->dvc_var.adv_dvc_var;
8634     c = &boardp->dvc_cfg.adv_dvc_cfg;
8635     iop_base = v->iop_base;
8636     chip_scsi_id = v->chip_scsi_id;
8637
8638     leftlen = cplen;
8639     totlen = len = 0;
8640
8641     len = asc_prt_line(cp, leftlen,
8642 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8643     shp->host_no);
8644     ASC_PRT_NEXT();
8645
8646     len = asc_prt_line(cp, leftlen,
8647 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
8648          v->iop_base,
8649          AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1) & CABLE_DETECT,
8650          v->err_code);
8651     ASC_PRT_NEXT();
8652
8653     len = asc_prt_line(cp, leftlen,
8654 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
8655         c->chip_version, c->lib_version, c->mcode_date, c->mcode_version);
8656     ASC_PRT_NEXT();
8657
8658     AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8659     len = asc_prt_line(cp, leftlen,
8660 " Queuing Enabled:");
8661     ASC_PRT_NEXT();
8662     for (i = 0; i <= ADV_MAX_TID; i++) {
8663         if ((chip_scsi_id == i) ||
8664             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8665             continue;
8666         }
8667
8668         len = asc_prt_line(cp, leftlen, " %X:%c",
8669             i, (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8670         ASC_PRT_NEXT();
8671     }
8672     len = asc_prt_line(cp, leftlen, "\n");
8673     ASC_PRT_NEXT();
8674
8675     len = asc_prt_line(cp, leftlen,
8676 " Queue Limit:");
8677     ASC_PRT_NEXT();
8678     for (i = 0; i <= ADV_MAX_TID; i++) {
8679         if ((chip_scsi_id == i) ||
8680             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8681             continue;
8682         }
8683
8684         AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, lrambyte);
8685
8686         len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
8687         ASC_PRT_NEXT();
8688     }
8689     len = asc_prt_line(cp, leftlen, "\n");
8690     ASC_PRT_NEXT();
8691
8692     len = asc_prt_line(cp, leftlen,
8693 " Command Pending:");
8694     ASC_PRT_NEXT();
8695     for (i = 0; i <= ADV_MAX_TID; i++) {
8696         if ((chip_scsi_id == i) ||
8697             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8698             continue;
8699         }
8700
8701         AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, lrambyte);
8702
8703         len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
8704         ASC_PRT_NEXT();
8705     }
8706     len = asc_prt_line(cp, leftlen, "\n");
8707     ASC_PRT_NEXT();
8708
8709     AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8710     len = asc_prt_line(cp, leftlen,
8711 " Wide Enabled:");
8712     ASC_PRT_NEXT();
8713     for (i = 0; i <= ADV_MAX_TID; i++) {
8714         if ((chip_scsi_id == i) ||
8715             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8716             continue;
8717         }
8718
8719         len = asc_prt_line(cp, leftlen, " %X:%c",
8720             i, (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8721         ASC_PRT_NEXT();
8722     }
8723     len = asc_prt_line(cp, leftlen, "\n");
8724     ASC_PRT_NEXT();
8725
8726     AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
8727     len = asc_prt_line(cp, leftlen,
8728 " Transfer Bit Width:");
8729     ASC_PRT_NEXT();
8730     for (i = 0; i <= ADV_MAX_TID; i++) {
8731         if ((chip_scsi_id == i) ||
8732             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8733             continue;
8734         }
8735
8736         AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
8737             lramword);
8738
8739         len = asc_prt_line(cp, leftlen, " %X:%d",
8740             i, (lramword & 0x8000) ? 16 : 8);
8741         ASC_PRT_NEXT();
8742
8743         if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
8744             (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8745             len = asc_prt_line(cp, leftlen, "*");
8746             ASC_PRT_NEXT();
8747             renegotiate = 1;
8748         }
8749     }
8750     len = asc_prt_line(cp, leftlen, "\n");
8751     ASC_PRT_NEXT();
8752
8753     AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8754     len = asc_prt_line(cp, leftlen,
8755 " Synchronous Enabled:");
8756     ASC_PRT_NEXT();
8757     for (i = 0; i <= ADV_MAX_TID; i++) {
8758         if ((chip_scsi_id == i) ||
8759             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8760             continue;
8761         }
8762
8763         len = asc_prt_line(cp, leftlen, " %X:%c",
8764             i, (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8765         ASC_PRT_NEXT();
8766     }
8767     len = asc_prt_line(cp, leftlen, "\n");
8768     ASC_PRT_NEXT();
8769
8770     AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
8771     for (i = 0; i <= ADV_MAX_TID; i++) {
8772
8773         AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
8774             lramword);
8775         lramword &= ~0x8000;
8776
8777         if ((chip_scsi_id == i) ||
8778             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
8779             ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
8780             continue;
8781         }
8782
8783         len = asc_prt_line(cp, leftlen, "  %X:", i);
8784         ASC_PRT_NEXT();
8785
8786         if ((lramword & 0x1F) == 0) /* Check for REQ/ACK Offset 0. */
8787         {
8788             len = asc_prt_line(cp, leftlen, " Asynchronous");
8789             ASC_PRT_NEXT();
8790         } else
8791         {
8792             len = asc_prt_line(cp, leftlen, " Transfer Period Factor: ");
8793             ASC_PRT_NEXT();
8794
8795             if ((lramword & 0x1F00) == 0x1100) /* 80 Mhz */
8796             {
8797                 len = asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
8798                 ASC_PRT_NEXT();
8799             } else if ((lramword & 0x1F00) == 0x1000) /* 40 Mhz */
8800             {
8801                 len = asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
8802                 ASC_PRT_NEXT();
8803             } else /* 20 Mhz or below. */
8804             {
8805                 period = (((lramword >> 8) * 25) + 50)/4;
8806
8807                 if (period == 0) /* Should never happen. */
8808                 {
8809                     len = asc_prt_line(cp, leftlen, "%d (? Mhz), ");
8810                     ASC_PRT_NEXT();
8811                 } else
8812                 {
8813                     len = asc_prt_line(cp, leftlen,
8814                         "%d (%d.%d Mhz),",
8815                         period, 250/period, ASC_TENTHS(250, period));
8816                     ASC_PRT_NEXT();
8817                 }
8818             }
8819
8820             len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
8821                 lramword & 0x1F);
8822             ASC_PRT_NEXT();
8823         }
8824
8825         if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8826             len = asc_prt_line(cp, leftlen, "*\n");
8827             renegotiate = 1;
8828         } else
8829         {
8830             len = asc_prt_line(cp, leftlen, "\n");
8831         }
8832         ASC_PRT_NEXT();
8833     }
8834
8835     if (renegotiate)
8836     {
8837         len = asc_prt_line(cp, leftlen,
8838             " * = Re-negotiation pending before next command.\n");
8839         ASC_PRT_NEXT();
8840     }
8841
8842     return totlen;
8843 }
8844
8845 /*
8846  * asc_proc_copy()
8847  *
8848  * Copy proc information to a read buffer taking into account the current
8849  * read offset in the file and the remaining space in the read buffer.
8850  */
8851 STATIC int
8852 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
8853               char *cp, int cplen)
8854 {
8855     int cnt = 0;
8856
8857     ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
8858             (unsigned) offset, (unsigned) advoffset, cplen);
8859     if (offset <= advoffset) {
8860         /* Read offset below current offset, copy everything. */
8861         cnt = ASC_MIN(cplen, leftlen);
8862         ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
8863                 (ulong) curbuf, (ulong) cp, cnt);
8864         memcpy(curbuf, cp, cnt);
8865     } else if (offset < advoffset + cplen) {
8866         /* Read offset within current range, partial copy. */
8867         cnt = (advoffset + cplen) - offset;
8868         cp = (cp + cplen) - cnt;
8869         cnt = ASC_MIN(cnt, leftlen);
8870         ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
8871                 (ulong) curbuf, (ulong) cp, cnt);
8872         memcpy(curbuf, cp, cnt);
8873     }
8874     return cnt;
8875 }
8876
8877 /*
8878  * asc_prt_line()
8879  *
8880  * If 'cp' is NULL print to the console, otherwise print to a buffer.
8881  *
8882  * Return 0 if printing to the console, otherwise return the number of
8883  * bytes written to the buffer.
8884  *
8885  * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
8886  * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
8887  */
8888 STATIC int
8889 asc_prt_line(char *buf, int buflen, char *fmt, ...)
8890 {
8891     va_list        args;
8892     int            ret;
8893     char           s[ASC_PRTLINE_SIZE];
8894
8895     va_start(args, fmt);
8896     ret = vsprintf(s, fmt, args);
8897     ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
8898     if (buf == NULL) {
8899         (void) printk(s);
8900         ret = 0;
8901     } else {
8902         ret = ASC_MIN(buflen, ret);
8903         memcpy(buf, s, ret);
8904     }
8905     va_end(args);
8906     return ret;
8907 }
8908 #endif /* CONFIG_PROC_FS */
8909
8910
8911 /*
8912  * --- Functions Required by the Asc Library
8913  */
8914
8915 /*
8916  * Delay for 'n' milliseconds. Don't use the 'jiffies'
8917  * global variable which is incremented once every 5 ms
8918  * from a timer interrupt, because this function may be
8919  * called when interrupts are disabled.
8920  */
8921 STATIC void
8922 DvcSleepMilliSecond(ADV_DCNT n)
8923 {
8924     ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong) n);
8925     mdelay(n);
8926 }
8927
8928 /*
8929  * Currently and inline noop but leave as a placeholder.
8930  * Leave DvcEnterCritical() as a noop placeholder.
8931  */
8932 STATIC inline ulong
8933 DvcEnterCritical(void)
8934 {
8935     return 0;
8936 }
8937
8938 /*
8939  * Critical sections are all protected by the board spinlock.
8940  * Leave DvcLeaveCritical() as a noop placeholder.
8941  */
8942 STATIC inline void
8943 DvcLeaveCritical(ulong flags)
8944 {
8945     return;
8946 }
8947
8948 /*
8949  * void
8950  * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
8951  *
8952  * Calling/Exit State:
8953  *    none
8954  *
8955  * Description:
8956  *     Output an ASC_SCSI_Q structure to the chip
8957  */
8958 STATIC void
8959 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
8960 {
8961     int    i;
8962
8963     ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
8964     AscSetChipLramAddr(iop_base, s_addr);
8965     for (i = 0; i < 2 * words; i += 2) {
8966         if (i == 4 || i == 20) {
8967             continue;
8968         }
8969         outpw(iop_base + IOP_RAM_DATA,
8970             ((ushort) outbuf[i + 1] << 8) | outbuf[i]);
8971     }
8972 }
8973
8974 /*
8975  * void
8976  * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
8977  *
8978  * Calling/Exit State:
8979  *    none
8980  *
8981  * Description:
8982  *     Input an ASC_QDONE_INFO structure from the chip
8983  */
8984 STATIC void
8985 DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
8986 {
8987     int    i;
8988     ushort word;
8989
8990     AscSetChipLramAddr(iop_base, s_addr);
8991     for (i = 0; i < 2 * words; i += 2) {
8992         if (i == 10) {
8993             continue;
8994         }
8995         word = inpw(iop_base + IOP_RAM_DATA);
8996         inbuf[i] = word & 0xff;
8997         inbuf[i + 1] = (word >> 8) & 0xff;
8998     }
8999     ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
9000 }
9001
9002 /*
9003  * Read a PCI configuration byte.
9004  */
9005 ASC_INITFUNC(
9006 STATIC uchar,
9007 DvcReadPCIConfigByte(
9008         ASC_DVC_VAR *asc_dvc,
9009         ushort offset)
9010 )
9011 {
9012 #ifdef CONFIG_PCI
9013     uchar byte_data;
9014     pci_read_config_byte(asc_dvc->cfg->pci_dev, offset, &byte_data);
9015     return byte_data;
9016 #else /* !defined(CONFIG_PCI) */
9017     return 0;
9018 #endif /* !defined(CONFIG_PCI) */
9019 }
9020
9021 /*
9022  * Write a PCI configuration byte.
9023  */
9024 ASC_INITFUNC(
9025 STATIC void,
9026 DvcWritePCIConfigByte(
9027         ASC_DVC_VAR *asc_dvc,
9028         ushort offset,
9029         uchar  byte_data)
9030 )
9031 {
9032 #ifdef CONFIG_PCI
9033     pci_write_config_byte(asc_dvc->cfg->pci_dev, offset, byte_data);
9034 #endif /* CONFIG_PCI */
9035 }
9036
9037 /*
9038  * Return the BIOS address of the adapter at the specified
9039  * I/O port and with the specified bus type.
9040  */
9041 ASC_INITFUNC(
9042 STATIC ushort,
9043 AscGetChipBiosAddress(
9044         PortAddr iop_base,
9045         ushort bus_type
9046 )
9047 )
9048 {
9049     ushort  cfg_lsw;
9050     ushort  bios_addr;
9051
9052     /*
9053      * The PCI BIOS is re-located by the motherboard BIOS. Because
9054      * of this the driver can not determine where a PCI BIOS is
9055      * loaded and executes.
9056      */
9057     if (bus_type & ASC_IS_PCI)
9058     {
9059         return(0);
9060     }
9061
9062 #ifdef CONFIG_ISA
9063     if((bus_type & ASC_IS_EISA) != 0)
9064     {
9065         cfg_lsw = AscGetEisaChipCfg(iop_base);
9066         cfg_lsw &= 0x000F;
9067         bios_addr = (ushort)(ASC_BIOS_MIN_ADDR  +
9068                                 (cfg_lsw * ASC_BIOS_BANK_SIZE));
9069         return(bios_addr);
9070     }/* if */
9071 #endif /* CONFIG_ISA */
9072
9073     cfg_lsw = AscGetChipCfgLsw(iop_base);
9074
9075     /*
9076     *  ISA PnP uses the top bit as the 32K BIOS flag
9077     */
9078     if (bus_type == ASC_IS_ISAPNP)
9079     {
9080         cfg_lsw &= 0x7FFF;
9081     }/* if */
9082
9083     bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
9084             ASC_BIOS_MIN_ADDR);
9085     return(bios_addr);
9086 }
9087
9088
9089 /*
9090  * --- Functions Required by the Adv Library
9091  */
9092
9093 /*
9094  * DvcGetPhyAddr()
9095  *
9096  * Return the physical address of 'vaddr' and set '*lenp' to the
9097  * number of physically contiguous bytes that follow 'vaddr'.
9098  * 'flag' indicates the type of structure whose physical address
9099  * is being translated.
9100  *
9101  * Note: Because Linux currently doesn't page the kernel and all
9102  * kernel buffers are physically contiguous, leave '*lenp' unchanged.
9103  */
9104 ADV_PADDR
9105 DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
9106         uchar *vaddr, ADV_SDCNT *lenp, int flag)
9107 {
9108     ADV_PADDR           paddr;
9109
9110     paddr = virt_to_bus(vaddr);
9111
9112     ASC_DBG4(4,
9113         "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
9114         (ulong) vaddr, (ulong) lenp, (ulong) *((ulong *) lenp), (ulong) paddr);
9115
9116     return paddr;
9117 }
9118
9119 /*
9120  * Read a PCI configuration byte.
9121  */
9122 ASC_INITFUNC(
9123 STATIC uchar,
9124 DvcAdvReadPCIConfigByte(
9125         ADV_DVC_VAR *asc_dvc,
9126         ushort offset)
9127 )
9128 {
9129 #ifdef CONFIG_PCI
9130     uchar byte_data;
9131     pci_read_config_byte(asc_dvc->cfg->pci_dev, offset, &byte_data);
9132     return byte_data;
9133 #else /* CONFIG_PCI */
9134     return 0;
9135 #endif /* CONFIG_PCI */
9136 }
9137
9138 /*
9139  * Write a PCI configuration byte.
9140  */
9141 ASC_INITFUNC(
9142 STATIC void,
9143 DvcAdvWritePCIConfigByte(
9144         ADV_DVC_VAR *asc_dvc,
9145         ushort offset,
9146         uchar  byte_data)
9147 )
9148 {
9149 #ifdef CONFIG_PCI
9150     pci_write_config_byte(asc_dvc->cfg->pci_dev, offset, byte_data);
9151 #else /* CONFIG_PCI */
9152     return 0;
9153 #endif /* CONFIG_PCI */
9154 }
9155
9156 /*
9157  * --- Tracing and Debugging Functions
9158  */
9159
9160 #ifdef ADVANSYS_STATS
9161 #ifdef CONFIG_PROC_FS
9162 /*
9163  * asc_prt_board_stats()
9164  *
9165  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
9166  * cf. asc_prt_line().
9167  *
9168  * Return the number of characters copied into 'cp'. No more than
9169  * 'cplen' characters will be copied to 'cp'.
9170  */
9171 STATIC int
9172 asc_prt_board_stats(struct Scsi_Host *shp, char *cp, int cplen)
9173 {
9174     int                    leftlen;
9175     int                    totlen;
9176     int                    len;
9177     struct asc_stats       *s;
9178     asc_board_t            *boardp;
9179
9180     leftlen = cplen;
9181     totlen = len = 0;
9182
9183     boardp = ASC_BOARDP(shp);
9184     s = &boardp->asc_stats;
9185
9186     len = asc_prt_line(cp, leftlen,
9187 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", shp->host_no);
9188     ASC_PRT_NEXT();
9189
9190     len = asc_prt_line(cp, leftlen,
9191 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
9192         s->queuecommand, s->reset, s->biosparam, s->interrupt);
9193     ASC_PRT_NEXT();
9194
9195     len = asc_prt_line(cp, leftlen,
9196 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
9197         s->callback, s->done, s->build_error, s->adv_build_noreq,
9198         s->adv_build_nosg);
9199     ASC_PRT_NEXT();
9200
9201     len = asc_prt_line(cp, leftlen,
9202 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
9203         s->exe_noerror, s->exe_busy, s->exe_error, s->exe_unknown);
9204     ASC_PRT_NEXT();
9205
9206     /*
9207      * Display data transfer statistics.
9208      */
9209     if (s->cont_cnt > 0) {
9210         len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
9211         ASC_PRT_NEXT();
9212
9213         len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
9214                     s->cont_xfer/2,
9215                     ASC_TENTHS(s->cont_xfer, 2));
9216         ASC_PRT_NEXT();
9217
9218         /* Contiguous transfer average size */
9219         len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
9220                     (s->cont_xfer/2)/s->cont_cnt,
9221                     ASC_TENTHS((s->cont_xfer/2), s->cont_cnt));
9222         ASC_PRT_NEXT();
9223     }
9224
9225     if (s->sg_cnt > 0) {
9226
9227         len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
9228                     s->sg_cnt, s->sg_elem);
9229         ASC_PRT_NEXT();
9230
9231         len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
9232                     s->sg_xfer/2,
9233                     ASC_TENTHS(s->sg_xfer, 2));
9234         ASC_PRT_NEXT();
9235
9236         /* Scatter gather transfer statistics */
9237         len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
9238                     s->sg_elem/s->sg_cnt,
9239                     ASC_TENTHS(s->sg_elem, s->sg_cnt));
9240         ASC_PRT_NEXT();
9241
9242         len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
9243                     (s->sg_xfer/2)/s->sg_elem,
9244                     ASC_TENTHS((s->sg_xfer/2), s->sg_elem));
9245         ASC_PRT_NEXT();
9246
9247         len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
9248                     (s->sg_xfer/2)/s->sg_cnt,
9249                     ASC_TENTHS((s->sg_xfer/2), s->sg_cnt));
9250         ASC_PRT_NEXT();
9251     }
9252
9253     /*
9254      * Display request queuing statistics.
9255      */
9256     len = asc_prt_line(cp, leftlen,
9257 " Active and Waiting Request Queues (Time Unit: %d HZ):\n", HZ);
9258     ASC_PRT_NEXT();
9259
9260
9261      return totlen;
9262 }
9263
9264 /*
9265  * asc_prt_target_stats()
9266  *
9267  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
9268  * cf. asc_prt_line().
9269  *
9270  * This is separated from asc_prt_board_stats because a full set
9271  * of targets will overflow ASC_PRTBUF_SIZE.
9272  *
9273  * Return the number of characters copied into 'cp'. No more than
9274  * 'cplen' characters will be copied to 'cp'.
9275  */
9276 STATIC int
9277 asc_prt_target_stats(struct Scsi_Host *shp, int tgt_id, char *cp, int cplen)
9278 {
9279     int                    leftlen;
9280     int                    totlen;
9281     int                    len;
9282     struct asc_stats       *s;
9283     ushort                 chip_scsi_id;
9284     asc_board_t            *boardp;
9285     asc_queue_t            *active;
9286     asc_queue_t            *waiting;
9287
9288     leftlen = cplen;
9289     totlen = len = 0;
9290
9291     boardp = ASC_BOARDP(shp);
9292     s = &boardp->asc_stats;
9293
9294     active = &ASC_BOARDP(shp)->active;
9295     waiting = &ASC_BOARDP(shp)->waiting;
9296
9297     if (ASC_NARROW_BOARD(boardp)) {
9298         chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
9299     } else {
9300         chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
9301     }
9302
9303     if ((chip_scsi_id == tgt_id) ||
9304         ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
9305         return 0;
9306     }
9307
9308     do {
9309         if (active->q_tot_cnt[tgt_id] > 0 || waiting->q_tot_cnt[tgt_id] > 0) {
9310             len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
9311             ASC_PRT_NEXT();
9312
9313             len = asc_prt_line(cp, leftlen,
9314 "   active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
9315                 active->q_cur_cnt[tgt_id], active->q_max_cnt[tgt_id],
9316                 active->q_tot_cnt[tgt_id],
9317                 active->q_min_tim[tgt_id], active->q_max_tim[tgt_id],
9318                 (active->q_tot_cnt[tgt_id] == 0) ? 0 :
9319                 (active->q_tot_tim[tgt_id]/active->q_tot_cnt[tgt_id]),
9320                 (active->q_tot_cnt[tgt_id] == 0) ? 0 :
9321                 ASC_TENTHS(active->q_tot_tim[tgt_id],
9322                 active->q_tot_cnt[tgt_id]));
9323              ASC_PRT_NEXT();
9324
9325              len = asc_prt_line(cp, leftlen,
9326 "   waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
9327                 waiting->q_cur_cnt[tgt_id], waiting->q_max_cnt[tgt_id],
9328                 waiting->q_tot_cnt[tgt_id],
9329                 waiting->q_min_tim[tgt_id], waiting->q_max_tim[tgt_id],
9330                 (waiting->q_tot_cnt[tgt_id] == 0) ? 0 :
9331                 (waiting->q_tot_tim[tgt_id]/waiting->q_tot_cnt[tgt_id]),
9332                 (waiting->q_tot_cnt[tgt_id] == 0) ? 0 :
9333                 ASC_TENTHS(waiting->q_tot_tim[tgt_id],
9334                 waiting->q_tot_cnt[tgt_id]));
9335              ASC_PRT_NEXT();
9336         }
9337     } while (0);
9338
9339      return totlen;
9340 }
9341 #endif /* CONFIG_PROC_FS */
9342 #endif /* ADVANSYS_STATS */
9343
9344 #ifdef ADVANSYS_DEBUG
9345 /*
9346  * asc_prt_scsi_host()
9347  */
9348 STATIC void
9349 asc_prt_scsi_host(struct Scsi_Host *s)
9350 {
9351     asc_board_t         *boardp;
9352
9353     boardp = ASC_BOARDP(s);
9354
9355     printk("Scsi_Host at addr 0x%lx\n", (ulong) s);
9356     printk(
9357 " host_busy %u, host_no %d, last_reset %d,\n",
9358         s->host_busy, s->host_no,
9359         (unsigned) s->last_reset);
9360
9361 #if ASC_LINUX_KERNEL24
9362     printk(
9363 " hostt 0x%lx\n",
9364         (ulong) s->hostt);
9365 #elif ASC_LINUX_KERNEL22
9366     printk(
9367 " host_queue 0x%lx, hostt 0x%lx, block 0x%lx,\n",
9368         (ulong) s->host_queue, (ulong) s->hostt, (ulong) s->block);
9369 #endif
9370
9371     printk(
9372 " base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
9373         (ulong) s->base, (ulong) s->io_port, s->n_io_port, s->irq);
9374
9375     printk(
9376 " dma_channel %d, this_id %d, can_queue %d,\n",
9377         s->dma_channel, s->this_id, s->can_queue);
9378
9379     printk(
9380 " cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
9381         s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
9382
9383     if (ASC_NARROW_BOARD(boardp)) {
9384         asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
9385         asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
9386     } else {
9387         asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
9388         asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
9389     }
9390 }
9391
9392 /*
9393  * asc_prt_scsi_cmnd()
9394  */
9395 STATIC void
9396 asc_prt_scsi_cmnd(Scsi_Cmnd *s)
9397 {
9398     printk("Scsi_Cmnd at addr 0x%lx\n", (ulong) s);
9399
9400     printk(
9401 " host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
9402         (ulong) s->device->host, (ulong) s->device, s->device->id, s->device->lun,
9403         s->device->channel);
9404
9405     asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
9406
9407 #if ASC_LINUX_KERNEL24
9408     printk (
9409 "sc_data_direction %u, resid %d\n",
9410         s->sc_data_direction, s->resid);
9411 #endif
9412
9413     printk(
9414 " use_sg %u, sglist_len %u, abort_reason 0x%x\n",
9415         s->use_sg, s->sglist_len, s->abort_reason);
9416
9417     printk(
9418 " serial_number 0x%x, serial_number_at_timeout 0x%x, retries %d, allowed %d\n",
9419         (unsigned) s->serial_number, (unsigned) s->serial_number_at_timeout,
9420          s->retries, s->allowed);
9421
9422     printk(
9423 " timeout_per_command %d, timeout_total %d, timeout %d\n",
9424         s->timeout_per_command, s->timeout_total, s->timeout);
9425
9426 #if ASC_LINUX_KERNEL24
9427     printk(
9428 " internal_timeout %u, flags %u\n",
9429         s->internal_timeout, s->flags);
9430 #elif ASC_LINUX_KERNEL22
9431     printk(
9432 " internal_timeout %u, flags %u, this_count %d\n",
9433         s->internal_timeout, s->flags,s->this_count);
9434 #endif
9435
9436     printk(
9437 " scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
9438         (ulong) s->scsi_done, (ulong) s->done,
9439         (ulong) s->host_scribble, s->result);
9440
9441     printk(
9442 " tag %u, pid %u\n",
9443         (unsigned) s->tag, (unsigned) s->pid);
9444 }
9445
9446 /*
9447  * asc_prt_asc_dvc_var()
9448  */
9449 STATIC void
9450 asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
9451 {
9452     printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong) h);
9453
9454     printk(
9455 " iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n",
9456         h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
9457
9458     printk(
9459 " bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n",
9460         h->bus_type, (ulong) h->isr_callback, (ulong) h->exe_callback,
9461         (unsigned) h->init_sdtr);
9462
9463     printk(
9464 " sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n",
9465         (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng,
9466         (unsigned) h->unit_not_ready, (unsigned) h->chip_no);
9467
9468     printk(
9469 " queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n",
9470         (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor,
9471         (unsigned) h->scsi_reset_wait);
9472
9473     printk(
9474 " is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n",
9475         (unsigned) h->is_in_int, (unsigned) h->max_total_qng,
9476         (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt);
9477
9478     printk(
9479 " last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n",
9480         (unsigned) h->last_q_shortage, (unsigned) h->init_state,
9481         (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer);
9482
9483     printk(
9484 " cfg 0x%lx, irq_no 0x%x\n",
9485         (ulong) h->cfg, (unsigned) h->irq_no);
9486 }
9487
9488 /*
9489  * asc_prt_asc_dvc_cfg()
9490  */
9491 STATIC void
9492 asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
9493 {
9494     printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong) h);
9495
9496     printk(
9497 " can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
9498             h->can_tagged_qng, h->cmd_qng_enabled);
9499     printk(
9500 " disc_enable 0x%x, sdtr_enable 0x%x,\n",
9501             h->disc_enable, h->sdtr_enable);
9502
9503     printk(
9504 " chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
9505              h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
9506              h->chip_version);
9507
9508     printk(
9509 " pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
9510           h->pci_dev->device, h->lib_serial_no, h->lib_version, h->mcode_date);
9511
9512     printk(
9513 " mcode_version %d, overrun_buf 0x%lx\n",
9514             h->mcode_version, (ulong) h->overrun_buf);
9515 }
9516
9517 /*
9518  * asc_prt_asc_scsi_q()
9519  */
9520 STATIC void
9521 asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
9522 {
9523     ASC_SG_HEAD    *sgp;
9524     int i;
9525
9526     printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong) q);
9527
9528     printk(
9529 " target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
9530             q->q2.target_ix, q->q1.target_lun,
9531             (ulong) q->q2.srb_ptr, q->q2.tag_code);
9532
9533     printk(
9534 " data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
9535             (ulong) le32_to_cpu(q->q1.data_addr),
9536             (ulong) le32_to_cpu(q->q1.data_cnt),
9537             (ulong) le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
9538
9539     printk(
9540 " cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
9541             (ulong) q->cdbptr, q->q2.cdb_len,
9542             (ulong) q->sg_head, q->q1.sg_queue_cnt);
9543
9544     if (q->sg_head) {
9545         sgp = q->sg_head;
9546         printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong) sgp);
9547         printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt);
9548         for (i = 0; i < sgp->entry_cnt; i++) {
9549             printk(" [%u]: addr 0x%lx, bytes %lu\n",
9550                 i, (ulong) le32_to_cpu(sgp->sg_list[i].addr),
9551                 (ulong) le32_to_cpu(sgp->sg_list[i].bytes));
9552         }
9553
9554     }
9555 }
9556
9557 /*
9558  * asc_prt_asc_qdone_info()
9559  */
9560 STATIC void
9561 asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
9562 {
9563     printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong) q);
9564     printk(
9565 " srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
9566             (ulong) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
9567             q->d2.tag_code);
9568     printk(
9569 " done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
9570             q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
9571 }
9572
9573 /*
9574  * asc_prt_adv_dvc_var()
9575  *
9576  * Display an ADV_DVC_VAR structure.
9577  */
9578 STATIC void
9579 asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
9580 {
9581     printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong) h);
9582
9583     printk(
9584 "  iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
9585         (ulong) h->iop_base, h->err_code, (unsigned) h->ultra_able);
9586
9587     printk(
9588 "  isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
9589         (ulong) h->isr_callback, (unsigned) h->sdtr_able,
9590         (unsigned) h->wdtr_able);
9591
9592     printk(
9593 "  start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
9594         (unsigned) h->start_motor,
9595         (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
9596
9597     printk(
9598 "  max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
9599         (unsigned) h->max_host_qng, (unsigned) h->max_dvc_qng,
9600         (ulong) h->carr_freelist);
9601
9602     printk(
9603 "  icq_sp 0x%lx, irq_sp 0x%lx\n",
9604         (ulong) h->icq_sp, (ulong) h->irq_sp);
9605
9606     printk(
9607 "  no_scam 0x%x, tagqng_able 0x%x\n",
9608         (unsigned) h->no_scam, (unsigned) h->tagqng_able);
9609
9610     printk(
9611 "  chip_scsi_id 0x%x, cfg 0x%lx\n",
9612         (unsigned) h->chip_scsi_id, (ulong) h->cfg);
9613 }
9614
9615 /*
9616  * asc_prt_adv_dvc_cfg()
9617  *
9618  * Display an ADV_DVC_CFG structure.
9619  */
9620 STATIC void
9621 asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
9622 {
9623     printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong) h);
9624
9625     printk(
9626 "  disc_enable 0x%x, termination 0x%x\n",
9627         h->disc_enable, h->termination);
9628
9629     printk(
9630 "  chip_version 0x%x, mcode_date 0x%x\n",
9631         h->chip_version, h->mcode_date);
9632
9633     printk(
9634 "  mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
9635        h->mcode_version, h->pci_dev->device, h->lib_version);
9636
9637     printk(
9638 "  control_flag 0x%x, pci_slot_info 0x%x\n",
9639        h->control_flag, h->pci_slot_info);
9640 }
9641
9642 /*
9643  * asc_prt_adv_scsi_req_q()
9644  *
9645  * Display an ADV_SCSI_REQ_Q structure.
9646  */
9647 STATIC void
9648 asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
9649 {
9650     int                 sg_blk_cnt;
9651     struct asc_sg_block *sg_ptr;
9652
9653     printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong) q);
9654
9655     printk(
9656 "  target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
9657             q->target_id, q->target_lun, (ulong) q->srb_ptr, q->a_flag);
9658
9659     printk("  cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
9660             q->cntl, (ulong) le32_to_cpu(q->data_addr), (ulong) q->vdata_addr);
9661
9662     printk(
9663 "  data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
9664             (ulong) le32_to_cpu(q->data_cnt),
9665             (ulong) le32_to_cpu(q->sense_addr), q->sense_len);
9666
9667     printk(
9668 "  cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
9669             q->cdb_len, q->done_status, q->host_status, q->scsi_status);
9670
9671     printk(
9672 "  sg_working_ix 0x%x, target_cmd %u\n",
9673             q->sg_working_ix, q->target_cmd);
9674
9675     printk(
9676 "  scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
9677             (ulong) le32_to_cpu(q->scsiq_rptr),
9678             (ulong) le32_to_cpu(q->sg_real_addr), (ulong) q->sg_list_ptr);
9679
9680     /* Display the request's ADV_SG_BLOCK structures. */
9681     if (q->sg_list_ptr != NULL)
9682     {
9683         sg_blk_cnt = 0;
9684         while (1) {
9685             /*
9686              * 'sg_ptr' is a physical address. Convert it to a virtual
9687              * address by indexing 'sg_blk_cnt' into the virtual address
9688              * array 'sg_list_ptr'.
9689              *
9690              * XXX - Assumes all SG physical blocks are virtually contiguous.
9691              */
9692             sg_ptr = &(((ADV_SG_BLOCK *) (q->sg_list_ptr))[sg_blk_cnt]);
9693             asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
9694             if (sg_ptr->sg_ptr == 0)
9695             {
9696                 break;
9697             }
9698             sg_blk_cnt++;
9699         }
9700     }
9701 }
9702
9703 /*
9704  * asc_prt_adv_sgblock()
9705  *
9706  * Display an ADV_SG_BLOCK structure.
9707  */
9708 STATIC void
9709 asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
9710 {
9711     int i;
9712
9713     printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
9714         (ulong) b, sgblockno);
9715     printk("  sg_cnt %u, sg_ptr 0x%lx\n",
9716         b->sg_cnt, (ulong) le32_to_cpu(b->sg_ptr));
9717     ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
9718     if (b->sg_ptr != 0)
9719     {
9720         ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
9721     }
9722     for (i = 0; i < b->sg_cnt; i++) {
9723         printk("  [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
9724             i, (ulong) b->sg_list[i].sg_addr, (ulong) b->sg_list[i].sg_count);
9725     }
9726 }
9727
9728 /*
9729  * asc_prt_hex()
9730  *
9731  * Print hexadecimal output in 4 byte groupings 32 bytes
9732  * or 8 double-words per line.
9733  */
9734 STATIC void
9735 asc_prt_hex(char *f, uchar *s, int l)
9736 {
9737     int            i;
9738     int            j;
9739     int            k;
9740     int            m;
9741
9742     printk("%s: (%d bytes)\n", f, l);
9743
9744     for (i = 0; i < l; i += 32) {
9745
9746         /* Display a maximum of 8 double-words per line. */
9747         if ((k = (l - i) / 4) >= 8) {
9748             k = 8;
9749             m = 0;
9750         } else {
9751             m = (l - i) % 4;
9752         }
9753
9754         for (j = 0; j < k; j++) {
9755             printk(" %2.2X%2.2X%2.2X%2.2X",
9756                 (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1],
9757                 (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]);
9758         }
9759
9760         switch (m) {
9761         case 0:
9762         default:
9763             break;
9764         case 1:
9765             printk(" %2.2X",
9766                 (unsigned) s[i+(j*4)]);
9767             break;
9768         case 2:
9769             printk(" %2.2X%2.2X",
9770                 (unsigned) s[i+(j*4)],
9771                 (unsigned) s[i+(j*4)+1]);
9772             break;
9773         case 3:
9774             printk(" %2.2X%2.2X%2.2X",
9775                 (unsigned) s[i+(j*4)+1],
9776                 (unsigned) s[i+(j*4)+2],
9777                 (unsigned) s[i+(j*4)+3]);
9778             break;
9779         }
9780
9781         printk("\n");
9782     }
9783 }
9784 #endif /* ADVANSYS_DEBUG */
9785
9786 /*
9787  * --- Asc Library Functions
9788  */
9789
9790 ASC_INITFUNC(
9791 STATIC ushort,
9792 AscGetEisaChipCfg(
9793                      PortAddr iop_base
9794 )
9795 )
9796 {
9797     PortAddr            eisa_cfg_iop;
9798
9799     eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
9800       (PortAddr) (ASC_EISA_CFG_IOP_MASK);
9801     return (inpw(eisa_cfg_iop));
9802 }
9803
9804 ASC_INITFUNC(
9805 STATIC uchar,
9806 AscSetChipScsiID(
9807                     PortAddr iop_base,
9808                     uchar new_host_id
9809 )
9810 )
9811 {
9812     ushort              cfg_lsw;
9813
9814     if (AscGetChipScsiID(iop_base) == new_host_id) {
9815         return (new_host_id);
9816     }
9817     cfg_lsw = AscGetChipCfgLsw(iop_base);
9818     cfg_lsw &= 0xF8FF;
9819     cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID) << 8);
9820     AscSetChipCfgLsw(iop_base, cfg_lsw);
9821     return (AscGetChipScsiID(iop_base));
9822 }
9823
9824 ASC_INITFUNC(
9825 STATIC uchar,
9826 AscGetChipScsiCtrl(
9827                       PortAddr iop_base
9828 )
9829 )
9830 {
9831     uchar               sc;
9832
9833     AscSetBank(iop_base, 1);
9834     sc = inp(iop_base + IOP_REG_SC);
9835     AscSetBank(iop_base, 0);
9836     return (sc);
9837 }
9838
9839 ASC_INITFUNC(
9840 STATIC uchar,
9841 AscGetChipVersion(
9842                      PortAddr iop_base,
9843                      ushort bus_type
9844 )
9845 )
9846 {
9847     if ((bus_type & ASC_IS_EISA) != 0) {
9848         PortAddr            eisa_iop;
9849         uchar               revision;
9850         eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
9851           (PortAddr) ASC_EISA_REV_IOP_MASK;
9852         revision = inp(eisa_iop);
9853         return ((uchar) ((ASC_CHIP_MIN_VER_EISA - 1) + revision));
9854     }
9855     return (AscGetChipVerNo(iop_base));
9856 }
9857
9858 ASC_INITFUNC(
9859 STATIC ushort,
9860 AscGetChipBusType(
9861                      PortAddr iop_base
9862 )
9863 )
9864 {
9865     ushort              chip_ver;
9866
9867     chip_ver = AscGetChipVerNo(iop_base);
9868     if (
9869            (chip_ver >= ASC_CHIP_MIN_VER_VL)
9870            && (chip_ver <= ASC_CHIP_MAX_VER_VL)
9871 ) {
9872         if (
9873                ((iop_base & 0x0C30) == 0x0C30)
9874                || ((iop_base & 0x0C50) == 0x0C50)
9875 ) {
9876             return (ASC_IS_EISA);
9877         }
9878         return (ASC_IS_VL);
9879     }
9880     if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
9881         (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
9882         if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
9883             return (ASC_IS_ISAPNP);
9884         }
9885         return (ASC_IS_ISA);
9886     } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
9887                (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
9888         return (ASC_IS_PCI);
9889     }
9890     return (0);
9891 }
9892
9893 STATIC ASC_DCNT
9894 AscLoadMicroCode(
9895                     PortAddr iop_base,
9896                     ushort s_addr,
9897                     uchar *mcode_buf,
9898                     ushort mcode_size
9899 )
9900 {
9901     ASC_DCNT            chksum;
9902     ushort              mcode_word_size;
9903     ushort              mcode_chksum;
9904
9905     /* Write the microcode buffer starting at LRAM address 0. */
9906     mcode_word_size = (ushort) (mcode_size >> 1);
9907     AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
9908     AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
9909
9910     chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
9911     ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong) chksum);
9912     mcode_chksum = (ushort) AscMemSumLramWord(iop_base,
9913           (ushort) ASC_CODE_SEC_BEG,
9914           (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2));
9915     ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
9916         (ulong) mcode_chksum);
9917     AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
9918     AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
9919     return (chksum);
9920 }
9921
9922 STATIC int
9923 AscFindSignature(
9924                     PortAddr iop_base
9925 )
9926 {
9927     ushort              sig_word;
9928
9929     ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
9930         iop_base, AscGetChipSignatureByte(iop_base));
9931     if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) {
9932         ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
9933             iop_base, AscGetChipSignatureWord(iop_base));
9934         sig_word = AscGetChipSignatureWord(iop_base);
9935         if ((sig_word == (ushort) ASC_1000_ID0W) ||
9936             (sig_word == (ushort) ASC_1000_ID0W_FIX)) {
9937             return (1);
9938         }
9939     }
9940     return (0);
9941 }
9942
9943 STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] ASC_INITDATA =
9944 {
9945     0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
9946     ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
9947 };
9948
9949 #ifdef CONFIG_ISA
9950 STATIC uchar _isa_pnp_inited ASC_INITDATA = 0;
9951
9952 ASC_INITFUNC(
9953 STATIC PortAddr,
9954 AscSearchIOPortAddr(
9955                        PortAddr iop_beg,
9956                        ushort bus_type
9957 )
9958 )
9959 {
9960     if (bus_type & ASC_IS_VL) {
9961         while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
9962             if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL) {
9963                 return (iop_beg);
9964             }
9965         }
9966         return (0);
9967     }
9968     if (bus_type & ASC_IS_ISA) {
9969         if (_isa_pnp_inited == 0) {
9970             AscSetISAPNPWaitForKey();
9971             _isa_pnp_inited++;
9972         }
9973         while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
9974             if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT) != 0) {
9975                 return (iop_beg);
9976             }
9977         }
9978         return (0);
9979     }
9980     if (bus_type & ASC_IS_EISA) {
9981         if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
9982             return (iop_beg);
9983         }
9984         return (0);
9985     }
9986     return (0);
9987 }
9988
9989 ASC_INITFUNC(
9990 STATIC PortAddr,
9991 AscSearchIOPortAddr11(
9992                          PortAddr s_addr
9993 )
9994 )
9995 {
9996     int                 i;
9997     PortAddr            iop_base;
9998
9999     for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
10000         if (_asc_def_iop_base[i] > s_addr) {
10001             break;
10002         }
10003     }
10004     for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
10005         iop_base = _asc_def_iop_base[i];
10006         if (check_region(iop_base, ASC_IOADR_GAP) != 0) {
10007             ASC_DBG1(1,
10008                "AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n",
10009                      iop_base);
10010             continue;
10011         }
10012         ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n", iop_base);
10013         if (AscFindSignature(iop_base)) {
10014             return (iop_base);
10015         }
10016     }
10017     return (0);
10018 }
10019
10020 ASC_INITFUNC(
10021 STATIC void,
10022 AscSetISAPNPWaitForKey(
10023     void)
10024 )
10025 {
10026     outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
10027     outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
10028     return;
10029 }
10030 #endif /* CONFIG_ISA */
10031
10032 ASC_INITFUNC(
10033 STATIC void,
10034 AscToggleIRQAct(
10035                    PortAddr iop_base
10036 )
10037 )
10038 {
10039     AscSetChipStatus(iop_base, CIW_IRQ_ACT);
10040     AscSetChipStatus(iop_base, 0);
10041     return;
10042 }
10043
10044 ASC_INITFUNC(
10045 STATIC uchar,
10046 AscGetChipIRQ(
10047                  PortAddr iop_base,
10048                  ushort bus_type
10049 )
10050 )
10051 {
10052     ushort              cfg_lsw;
10053     uchar               chip_irq;
10054
10055     if ((bus_type & ASC_IS_EISA) != 0) {
10056         cfg_lsw = AscGetEisaChipCfg(iop_base);
10057         chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10);
10058         if ((chip_irq == 13) || (chip_irq > 15)) {
10059             return (0);
10060         }
10061         return (chip_irq);
10062     }
10063     if ((bus_type & ASC_IS_VL) != 0) {
10064         cfg_lsw = AscGetChipCfgLsw(iop_base);
10065         chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07));
10066         if ((chip_irq == 0) ||
10067             (chip_irq == 4) ||
10068             (chip_irq == 7)) {
10069             return (0);
10070         }
10071         return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1)));
10072     }
10073     cfg_lsw = AscGetChipCfgLsw(iop_base);
10074     chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03));
10075     if (chip_irq == 3)
10076         chip_irq += (uchar) 2;
10077     return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
10078 }
10079
10080 ASC_INITFUNC(
10081 STATIC uchar,
10082 AscSetChipIRQ(
10083                  PortAddr iop_base,
10084                  uchar irq_no,
10085                  ushort bus_type
10086 )
10087 )
10088 {
10089     ushort              cfg_lsw;
10090
10091     if ((bus_type & ASC_IS_VL) != 0) {
10092         if (irq_no != 0) {
10093             if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) {
10094                 irq_no = 0;
10095             } else {
10096                 irq_no -= (uchar) ((ASC_MIN_IRQ_NO - 1));
10097             }
10098         }
10099         cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE3);
10100         cfg_lsw |= (ushort) 0x0010;
10101         AscSetChipCfgLsw(iop_base, cfg_lsw);
10102         AscToggleIRQAct(iop_base);
10103         cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE0);
10104         cfg_lsw |= (ushort) ((irq_no & 0x07) << 2);
10105         AscSetChipCfgLsw(iop_base, cfg_lsw);
10106         AscToggleIRQAct(iop_base);
10107         return (AscGetChipIRQ(iop_base, bus_type));
10108     }
10109     if ((bus_type & (ASC_IS_ISA)) != 0) {
10110         if (irq_no == 15)
10111             irq_no -= (uchar) 2;
10112         irq_no -= (uchar) ASC_MIN_IRQ_NO;
10113         cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFF3);
10114         cfg_lsw |= (ushort) ((irq_no & 0x03) << 2);
10115         AscSetChipCfgLsw(iop_base, cfg_lsw);
10116         return (AscGetChipIRQ(iop_base, bus_type));
10117     }
10118     return (0);
10119 }
10120
10121 #ifdef CONFIG_ISA
10122 ASC_INITFUNC(
10123 STATIC void,
10124 AscEnableIsaDma(
10125                    uchar dma_channel
10126 )
10127 )
10128 {
10129     if (dma_channel < 4) {
10130         outp(0x000B, (ushort) (0xC0 | dma_channel));
10131         outp(0x000A, dma_channel);
10132     } else if (dma_channel < 8) {
10133         outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4)));
10134         outp(0x00D4, (ushort) (dma_channel - 4));
10135     }
10136     return;
10137 }
10138 #endif /* CONFIG_ISA */
10139
10140 STATIC int
10141 AscIsrChipHalted(
10142                     ASC_DVC_VAR *asc_dvc
10143 )
10144 {
10145     EXT_MSG             ext_msg;
10146     EXT_MSG             out_msg;
10147     ushort              halt_q_addr;
10148     int                 sdtr_accept;
10149     ushort              int_halt_code;
10150     ASC_SCSI_BIT_ID_TYPE scsi_busy;
10151     ASC_SCSI_BIT_ID_TYPE target_id;
10152     PortAddr            iop_base;
10153     uchar               tag_code;
10154     uchar               q_status;
10155     uchar               halt_qp;
10156     uchar               sdtr_data;
10157     uchar               target_ix;
10158     uchar               q_cntl, tid_no;
10159     uchar               cur_dvc_qng;
10160     uchar               asyn_sdtr;
10161     uchar               scsi_status;
10162     asc_board_t         *boardp;
10163
10164     ASC_ASSERT(asc_dvc->drv_ptr != NULL);
10165     boardp = asc_dvc->drv_ptr;
10166
10167     iop_base = asc_dvc->iop_base;
10168     int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
10169
10170     halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
10171     halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
10172     target_ix = AscReadLramByte(iop_base,
10173                    (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX));
10174     q_cntl = AscReadLramByte(iop_base,
10175                         (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL));
10176     tid_no = ASC_TIX_TO_TID(target_ix);
10177     target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no);
10178     if (asc_dvc->pci_fix_asyn_xfer & target_id) {
10179         asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
10180     } else {
10181         asyn_sdtr = 0;
10182     }
10183     if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
10184         if (asc_dvc->pci_fix_asyn_xfer & target_id) {
10185             AscSetChipSDTR(iop_base, 0, tid_no);
10186             boardp->sdtr_data[tid_no] = 0;
10187         }
10188         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10189         return (0);
10190     } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
10191         if (asc_dvc->pci_fix_asyn_xfer & target_id) {
10192             AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10193             boardp->sdtr_data[tid_no] = asyn_sdtr;
10194         }
10195         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10196         return (0);
10197     } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
10198
10199         AscMemWordCopyPtrFromLram(iop_base,
10200                                ASCV_MSGIN_BEG,
10201                                (uchar *) &ext_msg,
10202                                sizeof(EXT_MSG) >> 1);
10203
10204         if (ext_msg.msg_type == MS_EXTEND &&
10205             ext_msg.msg_req == MS_SDTR_CODE &&
10206             ext_msg.msg_len == MS_SDTR_LEN) {
10207             sdtr_accept = TRUE;
10208             if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
10209
10210                 sdtr_accept = FALSE;
10211                 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
10212             }
10213             if ((ext_msg.xfer_period <
10214                  asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index]) ||
10215                 (ext_msg.xfer_period >
10216                  asc_dvc->sdtr_period_tbl[asc_dvc->max_sdtr_index])) {
10217                 sdtr_accept = FALSE;
10218                 ext_msg.xfer_period =
10219                     asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index];
10220             }
10221             if (sdtr_accept) {
10222                 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
10223                                            ext_msg.req_ack_offset);
10224                 if ((sdtr_data == 0xFF)) {
10225
10226                     q_cntl |= QC_MSG_OUT;
10227                     asc_dvc->init_sdtr &= ~target_id;
10228                     asc_dvc->sdtr_done &= ~target_id;
10229                     AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10230                     boardp->sdtr_data[tid_no] = asyn_sdtr;
10231                 }
10232             }
10233             if (ext_msg.req_ack_offset == 0) {
10234
10235                 q_cntl &= ~QC_MSG_OUT;
10236                 asc_dvc->init_sdtr &= ~target_id;
10237                 asc_dvc->sdtr_done &= ~target_id;
10238                 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10239             } else {
10240                 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
10241
10242                     q_cntl &= ~QC_MSG_OUT;
10243                     asc_dvc->sdtr_done |= target_id;
10244                     asc_dvc->init_sdtr |= target_id;
10245                     asc_dvc->pci_fix_asyn_xfer &= ~target_id;
10246                     sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
10247                                                ext_msg.req_ack_offset);
10248                     AscSetChipSDTR(iop_base, sdtr_data, tid_no);
10249                     boardp->sdtr_data[tid_no] = sdtr_data;
10250                 } else {
10251
10252                     q_cntl |= QC_MSG_OUT;
10253                     AscMsgOutSDTR(asc_dvc,
10254                                   ext_msg.xfer_period,
10255                                   ext_msg.req_ack_offset);
10256                     asc_dvc->pci_fix_asyn_xfer &= ~target_id;
10257                     sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
10258                                                ext_msg.req_ack_offset);
10259                     AscSetChipSDTR(iop_base, sdtr_data, tid_no);
10260                     boardp->sdtr_data[tid_no] = sdtr_data;
10261                     asc_dvc->sdtr_done |= target_id;
10262                     asc_dvc->init_sdtr |= target_id;
10263                 }
10264             }
10265
10266             AscWriteLramByte(iop_base,
10267                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10268                              q_cntl);
10269             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10270             return (0);
10271         } else if (ext_msg.msg_type == MS_EXTEND &&
10272                    ext_msg.msg_req == MS_WDTR_CODE &&
10273                    ext_msg.msg_len == MS_WDTR_LEN) {
10274
10275             ext_msg.wdtr_width = 0;
10276             AscMemWordCopyPtrToLram(iop_base,
10277                                  ASCV_MSGOUT_BEG,
10278                                  (uchar *) &ext_msg,
10279                                  sizeof(EXT_MSG) >> 1);
10280             q_cntl |= QC_MSG_OUT;
10281             AscWriteLramByte(iop_base,
10282                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10283                              q_cntl);
10284             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10285             return (0);
10286         } else {
10287
10288             ext_msg.msg_type = M1_MSG_REJECT;
10289             AscMemWordCopyPtrToLram(iop_base,
10290                                  ASCV_MSGOUT_BEG,
10291                                  (uchar *) &ext_msg,
10292                                  sizeof(EXT_MSG) >> 1);
10293             q_cntl |= QC_MSG_OUT;
10294             AscWriteLramByte(iop_base,
10295                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10296                              q_cntl);
10297             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10298             return (0);
10299         }
10300     } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
10301
10302         q_cntl |= QC_REQ_SENSE;
10303
10304         if ((asc_dvc->init_sdtr & target_id) != 0) {
10305
10306             asc_dvc->sdtr_done &= ~target_id;
10307
10308             sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10309             q_cntl |= QC_MSG_OUT;
10310             AscMsgOutSDTR(asc_dvc,
10311                           asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
10312                            (uchar) (asc_dvc->max_sdtr_index - 1)],
10313                           (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
10314         }
10315
10316         AscWriteLramByte(iop_base,
10317                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10318                          q_cntl);
10319
10320         tag_code = AscReadLramByte(iop_base,
10321                     (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
10322         tag_code &= 0xDC;
10323         if (
10324                (asc_dvc->pci_fix_asyn_xfer & target_id)
10325                && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
10326 ) {
10327
10328             tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
10329                          | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
10330
10331         }
10332         AscWriteLramByte(iop_base,
10333                      (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE),
10334                          tag_code);
10335
10336         q_status = AscReadLramByte(iop_base,
10337                       (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS));
10338         q_status |= (QS_READY | QS_BUSY);
10339         AscWriteLramByte(iop_base,
10340                        (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10341                          q_status);
10342
10343         scsi_busy = AscReadLramByte(iop_base,
10344                                     (ushort) ASCV_SCSIBUSY_B);
10345         scsi_busy &= ~target_id;
10346         AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10347
10348         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10349         return (0);
10350     } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
10351
10352         AscMemWordCopyPtrFromLram(iop_base,
10353                                ASCV_MSGOUT_BEG,
10354                                (uchar *) &out_msg,
10355                                sizeof(EXT_MSG) >> 1);
10356
10357         if ((out_msg.msg_type == MS_EXTEND) &&
10358             (out_msg.msg_len == MS_SDTR_LEN) &&
10359             (out_msg.msg_req == MS_SDTR_CODE)) {
10360
10361             asc_dvc->init_sdtr &= ~target_id;
10362             asc_dvc->sdtr_done &= ~target_id;
10363             AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10364             boardp->sdtr_data[tid_no] = asyn_sdtr;
10365         }
10366         q_cntl &= ~QC_MSG_OUT;
10367         AscWriteLramByte(iop_base,
10368                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10369                          q_cntl);
10370         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10371         return (0);
10372     } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
10373
10374         scsi_status = AscReadLramByte(iop_base,
10375           (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS));
10376         cur_dvc_qng = AscReadLramByte(iop_base,
10377                      (ushort) ((ushort) ASC_QADR_BEG + (ushort) target_ix));
10378         if ((cur_dvc_qng > 0) &&
10379             (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
10380
10381             scsi_busy = AscReadLramByte(iop_base,
10382                                         (ushort) ASCV_SCSIBUSY_B);
10383             scsi_busy |= target_id;
10384             AscWriteLramByte(iop_base,
10385                              (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10386             asc_dvc->queue_full_or_busy |= target_id;
10387
10388             if (scsi_status == SS_QUEUE_FULL) {
10389                 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
10390                     cur_dvc_qng -= 1;
10391                     asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
10392
10393                     AscWriteLramByte(iop_base,
10394                           (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG +
10395                            (ushort) tid_no),
10396                           cur_dvc_qng);
10397
10398                     /*
10399                      * Set the device queue depth to the number of
10400                      * active requests when the QUEUE FULL condition
10401                      * was encountered.
10402                      */
10403                     boardp->queue_full |= target_id;
10404                     boardp->queue_full_cnt[tid_no] = cur_dvc_qng;
10405                 }
10406             }
10407         }
10408         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10409         return (0);
10410     }
10411 #if CC_VERY_LONG_SG_LIST
10412     else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC)
10413     {
10414         uchar              q_no;
10415         ushort             q_addr;
10416         uchar              sg_wk_q_no;
10417         uchar              first_sg_wk_q_no;
10418         ASC_SCSI_Q         *scsiq; /* Ptr to driver request. */
10419         ASC_SG_HEAD        *sg_head; /* Ptr to driver SG request. */
10420         ASC_SG_LIST_Q      scsi_sg_q; /* Structure written to queue. */
10421         ushort             sg_list_dwords;
10422         ushort             sg_entry_cnt;
10423         uchar              next_qp;
10424         int                i;
10425
10426         q_no = AscReadLramByte(iop_base, (ushort) ASCV_REQ_SG_LIST_QP);
10427         if (q_no == ASC_QLINK_END)
10428         {
10429             return(0);
10430         }
10431
10432         q_addr = ASC_QNO_TO_QADDR(q_no);
10433
10434         /*
10435          * Convert the request's SRB pointer to a host ASC_SCSI_REQ
10436          * structure pointer using a macro provided by the driver.
10437          * The ASC_SCSI_REQ pointer provides a pointer to the
10438          * host ASC_SG_HEAD structure.
10439          */
10440         /* Read request's SRB pointer. */
10441         scsiq = (ASC_SCSI_Q *)
10442            ASC_SRB2SCSIQ(
10443                ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
10444                (ushort) (q_addr + ASC_SCSIQ_D_SRBPTR))));
10445
10446         /*
10447          * Get request's first and working SG queue.
10448          */
10449         sg_wk_q_no = AscReadLramByte(iop_base,
10450             (ushort) (q_addr + ASC_SCSIQ_B_SG_WK_QP));
10451
10452         first_sg_wk_q_no = AscReadLramByte(iop_base,
10453             (ushort) (q_addr + ASC_SCSIQ_B_FIRST_SG_WK_QP));
10454
10455         /*
10456          * Reset request's working SG queue back to the
10457          * first SG queue.
10458          */
10459         AscWriteLramByte(iop_base,
10460             (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SG_WK_QP),
10461             first_sg_wk_q_no);
10462
10463         sg_head = scsiq->sg_head;
10464
10465         /*
10466          * Set sg_entry_cnt to the number of SG elements
10467          * that will be completed on this interrupt.
10468          *
10469          * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
10470          * SG elements. The data_cnt and data_addr fields which
10471          * add 1 to the SG element capacity are not used when
10472          * restarting SG handling after a halt.
10473          */
10474         if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1))
10475         {
10476              sg_entry_cnt = ASC_MAX_SG_LIST - 1;
10477
10478              /*
10479               * Keep track of remaining number of SG elements that will
10480               * need to be handled on the next interrupt.
10481               */
10482              scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
10483         } else
10484         {
10485              sg_entry_cnt = scsiq->remain_sg_entry_cnt;
10486              scsiq->remain_sg_entry_cnt = 0;
10487         }
10488
10489         /*
10490          * Copy SG elements into the list of allocated SG queues.
10491          *
10492          * Last index completed is saved in scsiq->next_sg_index.
10493          */
10494         next_qp = first_sg_wk_q_no;
10495         q_addr = ASC_QNO_TO_QADDR(next_qp);
10496         scsi_sg_q.sg_head_qp = q_no;
10497         scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
10498         for( i = 0; i < sg_head->queue_cnt; i++)
10499         {
10500              scsi_sg_q.seq_no = i + 1;
10501              if (sg_entry_cnt > ASC_SG_LIST_PER_Q)
10502              {
10503                  sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
10504                  sg_entry_cnt -= ASC_SG_LIST_PER_Q;
10505                  /*
10506                   * After very first SG queue RISC FW uses next
10507                   * SG queue first element then checks sg_list_cnt
10508                   * against zero and then decrements, so set
10509                   * sg_list_cnt 1 less than number of SG elements
10510                   * in each SG queue.
10511                   */
10512                  scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
10513                  scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
10514              } else {
10515                  /*
10516                   * This is the last SG queue in the list of
10517                   * allocated SG queues. If there are more
10518                   * SG elements than will fit in the allocated
10519                   * queues, then set the QCSG_SG_XFER_MORE flag.
10520                   */
10521                  if (scsiq->remain_sg_entry_cnt != 0)
10522                  {
10523                      scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
10524                  } else
10525                  {
10526                      scsi_sg_q.cntl |= QCSG_SG_XFER_END;
10527                  }
10528                  /* equals sg_entry_cnt * 2 */
10529                  sg_list_dwords = sg_entry_cnt << 1;
10530                  scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
10531                  scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
10532                  sg_entry_cnt = 0;
10533              }
10534
10535              scsi_sg_q.q_no = next_qp;
10536              AscMemWordCopyPtrToLram(iop_base,
10537                           q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
10538                           (uchar *) &scsi_sg_q,
10539                           sizeof(ASC_SG_LIST_Q) >> 1);
10540
10541              AscMemDWordCopyPtrToLram(iop_base,
10542                           q_addr + ASC_SGQ_LIST_BEG,
10543                           (uchar *) &sg_head->sg_list[scsiq->next_sg_index],
10544                           sg_list_dwords);
10545
10546              scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
10547
10548              /*
10549               * If the just completed SG queue contained the
10550               * last SG element, then no more SG queues need
10551               * to be written.
10552               */
10553              if (scsi_sg_q.cntl & QCSG_SG_XFER_END)
10554              {
10555                  break;
10556              }
10557
10558              next_qp = AscReadLramByte( iop_base,
10559                           ( ushort )( q_addr+ASC_SCSIQ_B_FWD ) );
10560              q_addr = ASC_QNO_TO_QADDR( next_qp );
10561         }
10562
10563         /*
10564          * Clear the halt condition so the RISC will be restarted
10565          * after the return.
10566          */
10567         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10568         return(0);
10569     }
10570 #endif /* CC_VERY_LONG_SG_LIST */
10571     return (0);
10572 }
10573
10574 STATIC uchar
10575 _AscCopyLramScsiDoneQ(
10576                          PortAddr iop_base,
10577                          ushort q_addr,
10578                          ASC_QDONE_INFO * scsiq,
10579                          ASC_DCNT max_dma_count
10580 )
10581 {
10582     ushort              _val;
10583     uchar               sg_queue_cnt;
10584
10585     DvcGetQinfo(iop_base,
10586                 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
10587                 (uchar *) scsiq,
10588                 (sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2);
10589
10590     _val = AscReadLramWord(iop_base,
10591                            (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS));
10592     scsiq->q_status = (uchar) _val;
10593     scsiq->q_no = (uchar) (_val >> 8);
10594     _val = AscReadLramWord(iop_base,
10595                            (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL));
10596     scsiq->cntl = (uchar) _val;
10597     sg_queue_cnt = (uchar) (_val >> 8);
10598     _val = AscReadLramWord(iop_base,
10599                         (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN));
10600     scsiq->sense_len = (uchar) _val;
10601     scsiq->extra_bytes = (uchar) (_val >> 8);
10602
10603     /*
10604      * Read high word of remain bytes from alternate location.
10605      */
10606     scsiq->remain_bytes = (((ADV_DCNT) AscReadLramWord( iop_base,
10607                       (ushort) (q_addr+ (ushort) ASC_SCSIQ_W_ALT_DC1))) << 16);
10608     /*
10609      * Read low word of remain bytes from original location.
10610      */
10611     scsiq->remain_bytes += AscReadLramWord(iop_base,
10612         (ushort) (q_addr+ (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT));
10613
10614     scsiq->remain_bytes &= max_dma_count;
10615     return (sg_queue_cnt);
10616 }
10617
10618 STATIC int
10619 AscIsrQDone(
10620                ASC_DVC_VAR *asc_dvc
10621 )
10622 {
10623     uchar               next_qp;
10624     uchar               n_q_used;
10625     uchar               sg_list_qp;
10626     uchar               sg_queue_cnt;
10627     uchar               q_cnt;
10628     uchar               done_q_tail;
10629     uchar               tid_no;
10630     ASC_SCSI_BIT_ID_TYPE scsi_busy;
10631     ASC_SCSI_BIT_ID_TYPE target_id;
10632     PortAddr            iop_base;
10633     ushort              q_addr;
10634     ushort              sg_q_addr;
10635     uchar               cur_target_qng;
10636     ASC_QDONE_INFO      scsiq_buf;
10637     ASC_QDONE_INFO *scsiq;
10638     int                 false_overrun;
10639     ASC_ISR_CALLBACK    asc_isr_callback;
10640
10641     iop_base = asc_dvc->iop_base;
10642     asc_isr_callback = asc_dvc->isr_callback;
10643     n_q_used = 1;
10644     scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
10645     done_q_tail = (uchar) AscGetVarDoneQTail(iop_base);
10646     q_addr = ASC_QNO_TO_QADDR(done_q_tail);
10647     next_qp = AscReadLramByte(iop_base,
10648                               (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD));
10649     if (next_qp != ASC_QLINK_END) {
10650         AscPutVarDoneQTail(iop_base, next_qp);
10651         q_addr = ASC_QNO_TO_QADDR(next_qp);
10652         sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
10653             asc_dvc->max_dma_count);
10654         AscWriteLramByte(iop_base,
10655                          (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10656              (uchar) (scsiq->q_status & (uchar) ~ (QS_READY | QS_ABORTED)));
10657         tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
10658         target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
10659         if ((scsiq->cntl & QC_SG_HEAD) != 0) {
10660             sg_q_addr = q_addr;
10661             sg_list_qp = next_qp;
10662             for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
10663                 sg_list_qp = AscReadLramByte(iop_base,
10664                            (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_FWD));
10665                 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
10666                 if (sg_list_qp == ASC_QLINK_END) {
10667                     AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_Q_LINKS);
10668                     scsiq->d3.done_stat = QD_WITH_ERROR;
10669                     scsiq->d3.host_stat = QHSTA_D_QDONE_SG_LIST_CORRUPTED;
10670                     goto FATAL_ERR_QDONE;
10671                 }
10672                 AscWriteLramByte(iop_base,
10673                          (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10674                                  QS_FREE);
10675             }
10676             n_q_used = sg_queue_cnt + 1;
10677             AscPutVarDoneQTail(iop_base, sg_list_qp);
10678         }
10679         if (asc_dvc->queue_full_or_busy & target_id) {
10680             cur_target_qng = AscReadLramByte(iop_base,
10681             (ushort) ((ushort) ASC_QADR_BEG + (ushort) scsiq->d2.target_ix));
10682             if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
10683                 scsi_busy = AscReadLramByte(iop_base,
10684                                             (ushort) ASCV_SCSIBUSY_B);
10685                 scsi_busy &= ~target_id;
10686                 AscWriteLramByte(iop_base,
10687                                  (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10688                 asc_dvc->queue_full_or_busy &= ~target_id;
10689             }
10690         }
10691         if (asc_dvc->cur_total_qng >= n_q_used) {
10692             asc_dvc->cur_total_qng -= n_q_used;
10693             if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
10694                 asc_dvc->cur_dvc_qng[tid_no]--;
10695             }
10696         } else {
10697             AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
10698             scsiq->d3.done_stat = QD_WITH_ERROR;
10699             goto FATAL_ERR_QDONE;
10700         }
10701         if ((scsiq->d2.srb_ptr == 0UL) ||
10702             ((scsiq->q_status & QS_ABORTED) != 0)) {
10703             return (0x11);
10704         } else if (scsiq->q_status == QS_DONE) {
10705             false_overrun = FALSE;
10706             if (scsiq->extra_bytes != 0) {
10707                 scsiq->remain_bytes += (ADV_DCNT) scsiq->extra_bytes;
10708             }
10709             if (scsiq->d3.done_stat == QD_WITH_ERROR) {
10710                 if (scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN) {
10711                     if ((scsiq->cntl & (QC_DATA_IN | QC_DATA_OUT)) == 0) {
10712                         scsiq->d3.done_stat = QD_NO_ERROR;
10713                         scsiq->d3.host_stat = QHSTA_NO_ERROR;
10714                     } else if (false_overrun) {
10715                         scsiq->d3.done_stat = QD_NO_ERROR;
10716                         scsiq->d3.host_stat = QHSTA_NO_ERROR;
10717                     }
10718                 } else if (scsiq->d3.host_stat ==
10719                            QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
10720                     AscStopChip(iop_base);
10721                     AscSetChipControl(iop_base,
10722                         (uchar) (CC_SCSI_RESET | CC_HALT));
10723                     DvcDelayNanoSecond(asc_dvc, 60000);
10724                     AscSetChipControl(iop_base, CC_HALT);
10725                     AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10726                     AscSetChipStatus(iop_base, 0);
10727                     AscSetChipControl(iop_base, 0);
10728                 }
10729             }
10730             if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
10731                 (*asc_isr_callback) (asc_dvc, scsiq);
10732             } else {
10733                 if ((AscReadLramByte(iop_base,
10734                           (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) ==
10735                      SCSICMD_StartStopUnit)) {
10736                     asc_dvc->unit_not_ready &= ~target_id;
10737                     if (scsiq->d3.done_stat != QD_NO_ERROR) {
10738                         asc_dvc->start_motor &= ~target_id;
10739                     }
10740                 }
10741             }
10742             return (1);
10743         } else {
10744             AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
10745           FATAL_ERR_QDONE:
10746             if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
10747                 (*asc_isr_callback) (asc_dvc, scsiq);
10748             }
10749             return (0x80);
10750         }
10751     }
10752     return (0);
10753 }
10754
10755 STATIC int
10756 AscISR(
10757           ASC_DVC_VAR *asc_dvc
10758 )
10759 {
10760     ASC_CS_TYPE         chipstat;
10761     PortAddr            iop_base;
10762     ushort              saved_ram_addr;
10763     uchar               ctrl_reg;
10764     uchar               saved_ctrl_reg;
10765     int                 int_pending;
10766     int                 status;
10767     uchar               host_flag;
10768
10769     iop_base = asc_dvc->iop_base;
10770     int_pending = FALSE;
10771
10772     if (AscIsIntPending(iop_base) == 0)
10773     {
10774         return int_pending;
10775     }
10776
10777     if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
10778         || (asc_dvc->isr_callback == 0)
10779 ) {
10780         return (ERR);
10781     }
10782     if (asc_dvc->in_critical_cnt != 0) {
10783         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
10784         return (ERR);
10785     }
10786     if (asc_dvc->is_in_int) {
10787         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
10788         return (ERR);
10789     }
10790     asc_dvc->is_in_int = TRUE;
10791     ctrl_reg = AscGetChipControl(iop_base);
10792     saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
10793                                    CC_SINGLE_STEP | CC_DIAG | CC_TEST));
10794     chipstat = AscGetChipStatus(iop_base);
10795     if (chipstat & CSW_SCSI_RESET_LATCH) {
10796         if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
10797             int i = 10;
10798             int_pending = TRUE;
10799             asc_dvc->sdtr_done = 0;
10800             saved_ctrl_reg &= (uchar) (~CC_HALT);
10801             while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) &&
10802                    (i-- > 0))
10803             {
10804                   DvcSleepMilliSecond(100);
10805             }
10806             AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
10807             AscSetChipControl(iop_base, CC_HALT);
10808             AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10809             AscSetChipStatus(iop_base, 0);
10810             chipstat = AscGetChipStatus(iop_base);
10811         }
10812     }
10813     saved_ram_addr = AscGetChipLramAddr(iop_base);
10814     host_flag = AscReadLramByte(iop_base,
10815         ASCV_HOST_FLAG_B) & (uchar) (~ASC_HOST_FLAG_IN_ISR);
10816     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10817                      (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR));
10818     if ((chipstat & CSW_INT_PENDING)
10819         || (int_pending)
10820 ) {
10821         AscAckInterrupt(iop_base);
10822         int_pending = TRUE;
10823         if ((chipstat & CSW_HALTED) &&
10824             (ctrl_reg & CC_SINGLE_STEP)) {
10825             if (AscIsrChipHalted(asc_dvc) == ERR) {
10826                 goto ISR_REPORT_QDONE_FATAL_ERROR;
10827             } else {
10828                 saved_ctrl_reg &= (uchar) (~CC_HALT);
10829             }
10830         } else {
10831           ISR_REPORT_QDONE_FATAL_ERROR:
10832             if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
10833                 while (((status = AscIsrQDone(asc_dvc)) & 0x01) != 0) {
10834                 }
10835             } else {
10836                 do {
10837                     if ((status = AscIsrQDone(asc_dvc)) == 1) {
10838                         break;
10839                     }
10840                 } while (status == 0x11);
10841             }
10842             if ((status & 0x80) != 0)
10843                 int_pending = ERR;
10844         }
10845     }
10846     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10847     AscSetChipLramAddr(iop_base, saved_ram_addr);
10848     AscSetChipControl(iop_base, saved_ctrl_reg);
10849     asc_dvc->is_in_int = FALSE;
10850     return (int_pending);
10851 }
10852
10853 /* Microcode buffer is kept after initialization for error recovery. */
10854 STATIC uchar _asc_mcode_buf[] =
10855 {
10856   0x01,  0x03,  0x01,  0x19,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
10857   0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
10858   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
10859   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
10860   0x00,  0x00,  0x00,  0x00,  0xC3,  0x12,  0x0D,  0x05,  0x01,  0x00,  0x00,  0x00,  0x00,  0xFF,  0x00,  0x00,
10861   0x00,  0x00,  0x00,  0x00,  0xFF,  0x80,  0xFF,  0xFF,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
10862   0x00,  0x00,  0x00,  0x23,  0x00,  0x00,  0x00,  0x00,  0x00,  0x07,  0x00,  0xFF,  0x00,  0x00,  0x00,  0x00,
10863   0xFF,  0xFF,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xE4,  0x88,  0x00,  0x00,  0x00,  0x00,
10864   0x80,  0x73,  0x48,  0x04,  0x36,  0x00,  0x00,  0xA2,  0xC2,  0x00,  0x80,  0x73,  0x03,  0x23,  0x36,  0x40,
10865   0xB6,  0x00,  0x36,  0x00,  0x05,  0xD6,  0x0C,  0xD2,  0x12,  0xDA,  0x00,  0xA2,  0xC2,  0x00,  0x92,  0x80,
10866   0x1E,  0x98,  0x50,  0x00,  0xF5,  0x00,  0x48,  0x98,  0xDF,  0x23,  0x36,  0x60,  0xB6,  0x00,  0x92,  0x80,
10867   0x4F,  0x00,  0xF5,  0x00,  0x48,  0x98,  0xEF,  0x23,  0x36,  0x60,  0xB6,  0x00,  0x92,  0x80,  0x80,  0x62,
10868   0x92,  0x80,  0x00,  0x46,  0x15,  0xEE,  0x13,  0xEA,  0x02,  0x01,  0x09,  0xD8,  0xCD,  0x04,  0x4D,  0x00,
10869   0x00,  0xA3,  0xD6,  0x00,  0xA6,  0x97,  0x7F,  0x23,  0x04,  0x61,  0x84,  0x01,  0xE6,  0x84,  0xD2,  0xC1,
10870   0x80,  0x73,  0xCD,  0x04,  0x4D,  0x00,  0x00,  0xA3,  0xDA,  0x01,  0xA6,  0x97,  0xC6,  0x81,  0xC2,  0x88,
10871   0x80,  0x73,  0x80,  0x77,  0x00,  0x01,  0x01,  0xA1,  0xFE,  0x00,  0x4F,  0x00,  0x84,  0x97,  0x07,  0xA6,
10872   0x08,  0x01,  0x00,  0x33,  0x03,  0x00,  0xC2,  0x88,  0x03,  0x03,  0x01,  0xDE,  0xC2,  0x88,  0xCE,  0x00,
10873   0x69,  0x60,  0xCE,  0x00,  0x02,  0x03,  0x4A,  0x60,  0x00,  0xA2,  0x78,  0x01,  0x80,  0x63,  0x07,  0xA6,
10874   0x24,  0x01,  0x78,  0x81,  0x03,  0x03,  0x80,  0x63,  0xE2,  0x00,  0x07,  0xA6,  0x34,  0x01,  0x00,  0x33,
10875   0x04,  0x00,  0xC2,  0x88,  0x03,  0x07,  0x02,  0x01,  0x04,  0xCA,  0x0D,  0x23,  0x68,  0x98,  0x4D,  0x04,
10876   0x04,  0x85,  0x05,  0xD8,  0x0D,  0x23,  0x68,  0x98,  0xCD,  0x04,  0x15,  0x23,  0xF8,  0x88,  0xFB,  0x23,
10877   0x02,  0x61,  0x82,  0x01,  0x80,  0x63,  0x02,  0x03,  0x06,  0xA3,  0x62,  0x01,  0x00,  0x33,  0x0A,  0x00,
10878   0xC2,  0x88,  0x4E,  0x00,  0x07,  0xA3,  0x6E,  0x01,  0x00,  0x33,  0x0B,  0x00,  0xC2,  0x88,  0xCD,  0x04,
10879   0x36,  0x2D,  0x00,  0x33,  0x1A,  0x00,  0xC2,  0x88,  0x50,  0x04,  0x88,  0x81,  0x06,  0xAB,  0x82,  0x01,
10880   0x88,  0x81,  0x4E,  0x00,  0x07,  0xA3,  0x92,  0x01,  0x50,  0x00,  0x00,  0xA3,  0x3C,  0x01,  0x00,  0x05,
10881   0x7C,  0x81,  0x46,  0x97,  0x02,  0x01,  0x05,  0xC6,  0x04,  0x23,  0xA0,  0x01,  0x15,  0x23,  0xA1,  0x01,
10882   0xBE,  0x81,  0xFD,  0x23,  0x02,  0x61,  0x82,  0x01,  0x0A,  0xDA,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,
10883   0xB4,  0x01,  0x80,  0x63,  0xCD,  0x04,  0x36,  0x2D,  0x00,  0x33,  0x1B,  0x00,  0xC2,  0x88,  0x06,  0x23,
10884   0x68,  0x98,  0xCD,  0x04,  0xE6,  0x84,  0x06,  0x01,  0x00,  0xA2,  0xD4,  0x01,  0x57,  0x60,  0x00,  0xA0,
10885   0xDA,  0x01,  0xE6,  0x84,  0x80,  0x23,  0xA0,  0x01,  0xE6,  0x84,  0x80,  0x73,  0x4B,  0x00,  0x06,  0x61,
10886   0x00,  0xA2,  0x00,  0x02,  0x04,  0x01,  0x0C,  0xDE,  0x02,  0x01,  0x03,  0xCC,  0x4F,  0x00,  0x84,  0x97,
10887   0xFC,  0x81,  0x08,  0x23,  0x02,  0x41,  0x82,  0x01,  0x4F,  0x00,  0x62,  0x97,  0x48,  0x04,  0x84,  0x80,
10888   0xF0,  0x97,  0x00,  0x46,  0x56,  0x00,  0x03,  0xC0,  0x01,  0x23,  0xE8,  0x00,  0x81,  0x73,  0x06,  0x29,
10889   0x03,  0x42,  0x06,  0xE2,  0x03,  0xEE,  0x6B,  0xEB,  0x11,  0x23,  0xF8,  0x88,  0x04,  0x98,  0xF0,  0x80,
10890   0x80,  0x73,  0x80,  0x77,  0x07,  0xA4,  0x2A,  0x02,  0x7C,  0x95,  0x06,  0xA6,  0x34,  0x02,  0x03,  0xA6,
10891   0x4C,  0x04,  0x46,  0x82,  0x04,  0x01,  0x03,  0xD8,  0xB4,  0x98,  0x6A,  0x96,  0x46,  0x82,  0xFE,  0x95,
10892   0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0xB6,  0x2D,  0x02,  0xA6,  0x6C,  0x02,  0x07,  0xA6,  0x5A,  0x02,
10893   0x06,  0xA6,  0x5E,  0x02,  0x03,  0xA6,  0x62,  0x02,  0xC2,  0x88,  0x7C,  0x95,  0x48,  0x82,  0x60,  0x96,
10894   0x48,  0x82,  0x04,  0x23,  0xA0,  0x01,  0x14,  0x23,  0xA1,  0x01,  0x3C,  0x84,  0x04,  0x01,  0x0C,  0xDC,
10895   0xE0,  0x23,  0x25,  0x61,  0xEF,  0x00,  0x14,  0x01,  0x4F,  0x04,  0xA8,  0x01,  0x6F,  0x00,  0xA5,  0x01,
10896   0x03,  0x23,  0xA4,  0x01,  0x06,  0x23,  0x9C,  0x01,  0x24,  0x2B,  0x1C,  0x01,  0x02,  0xA6,  0xAA,  0x02,
10897   0x07,  0xA6,  0x5A,  0x02,  0x06,  0xA6,  0x5E,  0x02,  0x03,  0xA6,  0x20,  0x04,  0x01,  0xA6,  0xB4,  0x02,
10898   0x00,  0xA6,  0xB4,  0x02,  0x00,  0x33,  0x12,  0x00,  0xC2,  0x88,  0x00,  0x0E,  0x80,  0x63,  0x00,  0x43,
10899   0x00,  0xA0,  0x8C,  0x02,  0x4D,  0x04,  0x04,  0x01,  0x0B,  0xDC,  0xE7,  0x23,  0x04,  0x61,  0x84,  0x01,
10900   0x10,  0x31,  0x12,  0x35,  0x14,  0x01,  0xEC,  0x00,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,  0xEA,  0x82,
10901   0x18,  0x23,  0x04,  0x61,  0x18,  0xA0,  0xE2,  0x02,  0x04,  0x01,  0xA2,  0xC8,  0x00,  0x33,  0x1F,  0x00,
10902   0xC2,  0x88,  0x08,  0x31,  0x0A,  0x35,  0x0C,  0x39,  0x0E,  0x3D,  0x7E,  0x98,  0xB6,  0x2D,  0x01,  0xA6,
10903   0x14,  0x03,  0x00,  0xA6,  0x14,  0x03,  0x07,  0xA6,  0x0C,  0x03,  0x06,  0xA6,  0x10,  0x03,  0x03,  0xA6,
10904   0x20,  0x04,  0x02,  0xA6,  0x6C,  0x02,  0x00,  0x33,  0x33,  0x00,  0xC2,  0x88,  0x7C,  0x95,  0xEE,  0x82,
10905   0x60,  0x96,  0xEE,  0x82,  0x82,  0x98,  0x80,  0x42,  0x7E,  0x98,  0x64,  0xE4,  0x04,  0x01,  0x2D,  0xC8,
10906   0x31,  0x05,  0x07,  0x01,  0x00,  0xA2,  0x54,  0x03,  0x00,  0x43,  0x87,  0x01,  0x05,  0x05,  0x86,  0x98,
10907   0x7E,  0x98,  0x00,  0xA6,  0x16,  0x03,  0x07,  0xA6,  0x4C,  0x03,  0x03,  0xA6,  0x3C,  0x04,  0x06,  0xA6,
10908   0x50,  0x03,  0x01,  0xA6,  0x16,  0x03,  0x00,  0x33,  0x25,  0x00,  0xC2,  0x88,  0x7C,  0x95,  0x32,  0x83,
10909   0x60,  0x96,  0x32,  0x83,  0x04,  0x01,  0x10,  0xCE,  0x07,  0xC8,  0x05,  0x05,  0xEB,  0x04,  0x00,  0x33,
10910   0x00,  0x20,  0xC0,  0x20,  0x81,  0x62,  0x72,  0x83,  0x00,  0x01,  0x05,  0x05,  0xFF,  0xA2,  0x7A,  0x03,
10911   0xB1,  0x01,  0x08,  0x23,  0xB2,  0x01,  0x2E,  0x83,  0x05,  0x05,  0x15,  0x01,  0x00,  0xA2,  0x9A,  0x03,
10912   0xEC,  0x00,  0x6E,  0x00,  0x95,  0x01,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,  0x01,  0xA6,  0x96,  0x03,
10913   0x00,  0xA6,  0x96,  0x03,  0x10,  0x84,  0x80,  0x42,  0x7E,  0x98,  0x01,  0xA6,  0xA4,  0x03,  0x00,  0xA6,
10914   0xBC,  0x03,  0x10,  0x84,  0xA8,  0x98,  0x80,  0x42,  0x01,  0xA6,  0xA4,  0x03,  0x07,  0xA6,  0xB2,  0x03,
10915   0xD4,  0x83,  0x7C,  0x95,  0xA8,  0x83,  0x00,  0x33,  0x2F,  0x00,  0xC2,  0x88,  0xA8,  0x98,  0x80,  0x42,
10916   0x00,  0xA6,  0xBC,  0x03,  0x07,  0xA6,  0xCA,  0x03,  0xD4,  0x83,  0x7C,  0x95,  0xC0,  0x83,  0x00,  0x33,
10917   0x26,  0x00,  0xC2,  0x88,  0x38,  0x2B,  0x80,  0x32,  0x80,  0x36,  0x04,  0x23,  0xA0,  0x01,  0x12,  0x23,
10918   0xA1,  0x01,  0x10,  0x84,  0x07,  0xF0,  0x06,  0xA4,  0xF4,  0x03,  0x80,  0x6B,  0x80,  0x67,  0x05,  0x23,
10919   0x83,  0x03,  0x80,  0x63,  0x03,  0xA6,  0x0E,  0x04,  0x07,  0xA6,  0x06,  0x04,  0x06,  0xA6,  0x0A,  0x04,
10920   0x00,  0x33,  0x17,  0x00,  0xC2,  0x88,  0x7C,  0x95,  0xF4,  0x83,  0x60,  0x96,  0xF4,  0x83,  0x20,  0x84,
10921   0x07,  0xF0,  0x06,  0xA4,  0x20,  0x04,  0x80,  0x6B,  0x80,  0x67,  0x05,  0x23,  0x83,  0x03,  0x80,  0x63,
10922   0xB6,  0x2D,  0x03,  0xA6,  0x3C,  0x04,  0x07,  0xA6,  0x34,  0x04,  0x06,  0xA6,  0x38,  0x04,  0x00,  0x33,
10923   0x30,  0x00,  0xC2,  0x88,  0x7C,  0x95,  0x20,  0x84,  0x60,  0x96,  0x20,  0x84,  0x1D,  0x01,  0x06,  0xCC,
10924   0x00,  0x33,  0x00,  0x84,  0xC0,  0x20,  0x00,  0x23,  0xEA,  0x00,  0x81,  0x62,  0xA2,  0x0D,  0x80,  0x63,
10925   0x07,  0xA6,  0x5A,  0x04,  0x00,  0x33,  0x18,  0x00,  0xC2,  0x88,  0x03,  0x03,  0x80,  0x63,  0xA3,  0x01,
10926   0x07,  0xA4,  0x64,  0x04,  0x23,  0x01,  0x00,  0xA2,  0x86,  0x04,  0x0A,  0xA0,  0x76,  0x04,  0xE0,  0x00,
10927   0x00,  0x33,  0x1D,  0x00,  0xC2,  0x88,  0x0B,  0xA0,  0x82,  0x04,  0xE0,  0x00,  0x00,  0x33,  0x1E,  0x00,
10928   0xC2,  0x88,  0x42,  0x23,  0xF8,  0x88,  0x00,  0x23,  0x22,  0xA3,  0xE6,  0x04,  0x08,  0x23,  0x22,  0xA3,
10929   0xA2,  0x04,  0x28,  0x23,  0x22,  0xA3,  0xAE,  0x04,  0x02,  0x23,  0x22,  0xA3,  0xC4,  0x04,  0x42,  0x23,
10930   0xF8,  0x88,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,  0xAE,  0x04,  0x45,  0x23,  0xF8,  0x88,  0x04,  0x98,
10931   0x00,  0xA2,  0xC0,  0x04,  0xB4,  0x98,  0x00,  0x33,  0x00,  0x82,  0xC0,  0x20,  0x81,  0x62,  0xE8,  0x81,
10932   0x47,  0x23,  0xF8,  0x88,  0x04,  0x01,  0x0B,  0xDE,  0x04,  0x98,  0xB4,  0x98,  0x00,  0x33,  0x00,  0x81,
10933   0xC0,  0x20,  0x81,  0x62,  0x14,  0x01,  0x00,  0xA0,  0x00,  0x02,  0x43,  0x23,  0xF8,  0x88,  0x04,  0x23,
10934   0xA0,  0x01,  0x44,  0x23,  0xA1,  0x01,  0x80,  0x73,  0x4D,  0x00,  0x03,  0xA3,  0xF4,  0x04,  0x00,  0x33,
10935   0x27,  0x00,  0xC2,  0x88,  0x04,  0x01,  0x04,  0xDC,  0x02,  0x23,  0xA2,  0x01,  0x04,  0x23,  0xA0,  0x01,
10936   0x04,  0x98,  0x26,  0x95,  0x4B,  0x00,  0xF6,  0x00,  0x4F,  0x04,  0x4F,  0x00,  0x00,  0xA3,  0x22,  0x05,
10937   0x00,  0x05,  0x76,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x1C,  0x05,  0x0A,  0x85,  0x46,  0x97,  0xCD,  0x04,
10938   0x24,  0x85,  0x48,  0x04,  0x84,  0x80,  0x02,  0x01,  0x03,  0xDA,  0x80,  0x23,  0x82,  0x01,  0x34,  0x85,
10939   0x02,  0x23,  0xA0,  0x01,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x40,  0x05,  0x1D,  0x01,  0x04,  0xD6,
10940   0xFF,  0x23,  0x86,  0x41,  0x4B,  0x60,  0xCB,  0x00,  0xFF,  0x23,  0x80,  0x01,  0x49,  0x00,  0x81,  0x01,
10941   0x04,  0x01,  0x02,  0xC8,  0x30,  0x01,  0x80,  0x01,  0xF7,  0x04,  0x03,  0x01,  0x49,  0x04,  0x80,  0x01,
10942   0xC9,  0x00,  0x00,  0x05,  0x00,  0x01,  0xFF,  0xA0,  0x60,  0x05,  0x77,  0x04,  0x01,  0x23,  0xEA,  0x00,
10943   0x5D,  0x00,  0xFE,  0xC7,  0x00,  0x62,  0x00,  0x23,  0xEA,  0x00,  0x00,  0x63,  0x07,  0xA4,  0xF8,  0x05,
10944   0x03,  0x03,  0x02,  0xA0,  0x8E,  0x05,  0xF4,  0x85,  0x00,  0x33,  0x2D,  0x00,  0xC2,  0x88,  0x04,  0xA0,
10945   0xB8,  0x05,  0x80,  0x63,  0x00,  0x23,  0xDF,  0x00,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA2,  0xA4,  0x05,
10946   0x1D,  0x01,  0x06,  0xD6,  0x02,  0x23,  0x02,  0x41,  0x82,  0x01,  0x50,  0x00,  0x62,  0x97,  0x04,  0x85,
10947   0x04,  0x23,  0x02,  0x41,  0x82,  0x01,  0x04,  0x85,  0x08,  0xA0,  0xBE,  0x05,  0xF4,  0x85,  0x03,  0xA0,
10948   0xC4,  0x05,  0xF4,  0x85,  0x01,  0xA0,  0xCE,  0x05,  0x88,  0x00,  0x80,  0x63,  0xCC,  0x86,  0x07,  0xA0,
10949   0xEE,  0x05,  0x5F,  0x00,  0x00,  0x2B,  0xDF,  0x08,  0x00,  0xA2,  0xE6,  0x05,  0x80,  0x67,  0x80,  0x63,
10950   0x01,  0xA2,  0x7A,  0x06,  0x7C,  0x85,  0x06,  0x23,  0x68,  0x98,  0x48,  0x23,  0xF8,  0x88,  0x07,  0x23,
10951   0x80,  0x00,  0x06,  0x87,  0x80,  0x63,  0x7C,  0x85,  0x00,  0x23,  0xDF,  0x00,  0x00,  0x63,  0x4A,  0x00,
10952   0x06,  0x61,  0x00,  0xA2,  0x36,  0x06,  0x1D,  0x01,  0x16,  0xD4,  0xC0,  0x23,  0x07,  0x41,  0x83,  0x03,
10953   0x80,  0x63,  0x06,  0xA6,  0x1C,  0x06,  0x00,  0x33,  0x37,  0x00,  0xC2,  0x88,  0x1D,  0x01,  0x01,  0xD6,
10954   0x20,  0x23,  0x63,  0x60,  0x83,  0x03,  0x80,  0x63,  0x02,  0x23,  0xDF,  0x00,  0x07,  0xA6,  0x7C,  0x05,
10955   0xEF,  0x04,  0x6F,  0x00,  0x00,  0x63,  0x4B,  0x00,  0x06,  0x41,  0xCB,  0x00,  0x52,  0x00,  0x06,  0x61,
10956   0x00,  0xA2,  0x4E,  0x06,  0x1D,  0x01,  0x03,  0xCA,  0xC0,  0x23,  0x07,  0x41,  0x00,  0x63,  0x1D,  0x01,
10957   0x04,  0xCC,  0x00,  0x33,  0x00,  0x83,  0xC0,  0x20,  0x81,  0x62,  0x80,  0x23,  0x07,  0x41,  0x00,  0x63,
10958   0x80,  0x67,  0x08,  0x23,  0x83,  0x03,  0x80,  0x63,  0x00,  0x63,  0x01,  0x23,  0xDF,  0x00,  0x06,  0xA6,
10959   0x84,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x80,  0x67,  0x80,  0x63,  0x00,  0x33,  0x00,  0x40,  0xC0,  0x20,
10960   0x81,  0x62,  0x00,  0x63,  0x00,  0x00,  0xFE,  0x95,  0x83,  0x03,  0x80,  0x63,  0x06,  0xA6,  0x94,  0x06,
10961   0x07,  0xA6,  0x7C,  0x05,  0x00,  0x00,  0x01,  0xA0,  0x14,  0x07,  0x00,  0x2B,  0x40,  0x0E,  0x80,  0x63,
10962   0x01,  0x00,  0x06,  0xA6,  0xAA,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x40,  0x0E,  0x80,  0x63,  0x00,  0x43,
10963   0x00,  0xA0,  0xA2,  0x06,  0x06,  0xA6,  0xBC,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x80,  0x67,  0x40,  0x0E,
10964   0x80,  0x63,  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x23,  0xDF,  0x00,  0x00,  0x63,  0x07,  0xA6,  0xD6,  0x06,
10965   0x00,  0x33,  0x2A,  0x00,  0xC2,  0x88,  0x03,  0x03,  0x80,  0x63,  0x89,  0x00,  0x0A,  0x2B,  0x07,  0xA6,
10966   0xE8,  0x06,  0x00,  0x33,  0x29,  0x00,  0xC2,  0x88,  0x00,  0x43,  0x00,  0xA2,  0xF4,  0x06,  0xC0,  0x0E,
10967   0x80,  0x63,  0xDE,  0x86,  0xC0,  0x0E,  0x00,  0x33,  0x00,  0x80,  0xC0,  0x20,  0x81,  0x62,  0x04,  0x01,
10968   0x02,  0xDA,  0x80,  0x63,  0x7C,  0x85,  0x80,  0x7B,  0x80,  0x63,  0x06,  0xA6,  0x8C,  0x06,  0x00,  0x33,
10969   0x2C,  0x00,  0xC2,  0x88,  0x0C,  0xA2,  0x2E,  0x07,  0xFE,  0x95,  0x83,  0x03,  0x80,  0x63,  0x06,  0xA6,
10970   0x2C,  0x07,  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x33,  0x3D,  0x00,  0xC2,  0x88,  0x00,  0x00,  0x80,  0x67,
10971   0x83,  0x03,  0x80,  0x63,  0x0C,  0xA0,  0x44,  0x07,  0x07,  0xA6,  0x7C,  0x05,  0xBF,  0x23,  0x04,  0x61,
10972   0x84,  0x01,  0xE6,  0x84,  0x00,  0x63,  0xF0,  0x04,  0x01,  0x01,  0xF1,  0x00,  0x00,  0x01,  0xF2,  0x00,
10973   0x01,  0x05,  0x80,  0x01,  0x72,  0x04,  0x71,  0x00,  0x81,  0x01,  0x70,  0x04,  0x80,  0x05,  0x81,  0x05,
10974   0x00,  0x63,  0xF0,  0x04,  0xF2,  0x00,  0x72,  0x04,  0x01,  0x01,  0xF1,  0x00,  0x70,  0x00,  0x81,  0x01,
10975   0x70,  0x04,  0x71,  0x00,  0x81,  0x01,  0x72,  0x00,  0x80,  0x01,  0x71,  0x04,  0x70,  0x00,  0x80,  0x01,
10976   0x70,  0x04,  0x00,  0x63,  0xF0,  0x04,  0xF2,  0x00,  0x72,  0x04,  0x00,  0x01,  0xF1,  0x00,  0x70,  0x00,
10977   0x80,  0x01,  0x70,  0x04,  0x71,  0x00,  0x80,  0x01,  0x72,  0x00,  0x81,  0x01,  0x71,  0x04,  0x70,  0x00,
10978   0x81,  0x01,  0x70,  0x04,  0x00,  0x63,  0x00,  0x23,  0xB3,  0x01,  0x83,  0x05,  0xA3,  0x01,  0xA2,  0x01,
10979   0xA1,  0x01,  0x01,  0x23,  0xA0,  0x01,  0x00,  0x01,  0xC8,  0x00,  0x03,  0xA1,  0xC4,  0x07,  0x00,  0x33,
10980   0x07,  0x00,  0xC2,  0x88,  0x80,  0x05,  0x81,  0x05,  0x04,  0x01,  0x11,  0xC8,  0x48,  0x00,  0xB0,  0x01,
10981   0xB1,  0x01,  0x08,  0x23,  0xB2,  0x01,  0x05,  0x01,  0x48,  0x04,  0x00,  0x43,  0x00,  0xA2,  0xE4,  0x07,
10982   0x00,  0x05,  0xDA,  0x87,  0x00,  0x01,  0xC8,  0x00,  0xFF,  0x23,  0x80,  0x01,  0x05,  0x05,  0x00,  0x63,
10983   0xF7,  0x04,  0x1A,  0x09,  0xF6,  0x08,  0x6E,  0x04,  0x00,  0x02,  0x80,  0x43,  0x76,  0x08,  0x80,  0x02,
10984   0x77,  0x04,  0x00,  0x63,  0xF7,  0x04,  0x1A,  0x09,  0xF6,  0x08,  0x6E,  0x04,  0x00,  0x02,  0x00,  0xA0,
10985   0x14,  0x08,  0x16,  0x88,  0x00,  0x43,  0x76,  0x08,  0x80,  0x02,  0x77,  0x04,  0x00,  0x63,  0xF3,  0x04,
10986   0x00,  0x23,  0xF4,  0x00,  0x74,  0x00,  0x80,  0x43,  0xF4,  0x00,  0xCF,  0x40,  0x00,  0xA2,  0x44,  0x08,
10987   0x74,  0x04,  0x02,  0x01,  0xF7,  0xC9,  0xF6,  0xD9,  0x00,  0x01,  0x01,  0xA1,  0x24,  0x08,  0x04,  0x98,
10988   0x26,  0x95,  0x24,  0x88,  0x73,  0x04,  0x00,  0x63,  0xF3,  0x04,  0x75,  0x04,  0x5A,  0x88,  0x02,  0x01,
10989   0x04,  0xD8,  0x46,  0x97,  0x04,  0x98,  0x26,  0x95,  0x4A,  0x88,  0x75,  0x00,  0x00,  0xA3,  0x64,  0x08,
10990   0x00,  0x05,  0x4E,  0x88,  0x73,  0x04,  0x00,  0x63,  0x80,  0x7B,  0x80,  0x63,  0x06,  0xA6,  0x76,  0x08,
10991   0x00,  0x33,  0x3E,  0x00,  0xC2,  0x88,  0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0x00,  0x63,  0x38,  0x2B,
10992   0x9C,  0x88,  0x38,  0x2B,  0x92,  0x88,  0x32,  0x09,  0x31,  0x05,  0x92,  0x98,  0x05,  0x05,  0xB2,  0x09,
10993   0x00,  0x63,  0x00,  0x32,  0x00,  0x36,  0x00,  0x3A,  0x00,  0x3E,  0x00,  0x63,  0x80,  0x32,  0x80,  0x36,
10994   0x80,  0x3A,  0x80,  0x3E,  0xB4,  0x3D,  0x00,  0x63,  0x38,  0x2B,  0x40,  0x32,  0x40,  0x36,  0x40,  0x3A,
10995   0x40,  0x3E,  0x00,  0x63,  0x5A,  0x20,  0xC9,  0x40,  0x00,  0xA0,  0xB4,  0x08,  0x5D,  0x00,  0xFE,  0xC3,
10996   0x00,  0x63,  0x80,  0x73,  0xE6,  0x20,  0x02,  0x23,  0xE8,  0x00,  0x82,  0x73,  0xFF,  0xFD,  0x80,  0x73,
10997   0x13,  0x23,  0xF8,  0x88,  0x66,  0x20,  0xC0,  0x20,  0x04,  0x23,  0xA0,  0x01,  0xA1,  0x23,  0xA1,  0x01,
10998   0x81,  0x62,  0xE2,  0x88,  0x80,  0x73,  0x80,  0x77,  0x68,  0x00,  0x00,  0xA2,  0x80,  0x00,  0x03,  0xC2,
10999   0xF1,  0xC7,  0x41,  0x23,  0xF8,  0x88,  0x11,  0x23,  0xA1,  0x01,  0x04,  0x23,  0xA0,  0x01,  0xE6,  0x84,
11000 };
11001
11002 STATIC ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
11003 STATIC ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
11004
11005 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST  16
11006 STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] =
11007 {
11008     SCSICMD_Inquiry,
11009     SCSICMD_RequestSense,
11010     SCSICMD_ReadCapacity,
11011     SCSICMD_ReadTOC,
11012     SCSICMD_ModeSelect6,
11013     SCSICMD_ModeSense6,
11014     SCSICMD_ModeSelect10,
11015     SCSICMD_ModeSense10,
11016     0xFF,
11017     0xFF,
11018     0xFF,
11019     0xFF,
11020     0xFF,
11021     0xFF,
11022     0xFF,
11023     0xFF
11024 };
11025
11026 STATIC int
11027 AscExeScsiQueue(
11028                    ASC_DVC_VAR *asc_dvc,
11029                    ASC_SCSI_Q *scsiq
11030 )
11031 {
11032     PortAddr            iop_base;
11033     ulong               last_int_level;
11034     int                 sta;
11035     int                 n_q_required;
11036     int                 disable_syn_offset_one_fix;
11037     int                 i;
11038     ASC_PADDR           addr;
11039     ASC_EXE_CALLBACK    asc_exe_callback;
11040     ushort              sg_entry_cnt = 0;
11041     ushort              sg_entry_cnt_minus_one = 0;
11042     uchar               target_ix;
11043     uchar               tid_no;
11044     uchar               sdtr_data;
11045     uchar               extra_bytes;
11046     uchar               scsi_cmd;
11047     uchar               disable_cmd;
11048     ASC_SG_HEAD         *sg_head;
11049     ASC_DCNT            data_cnt;
11050
11051     iop_base = asc_dvc->iop_base;
11052     sg_head = scsiq->sg_head;
11053     asc_exe_callback = asc_dvc->exe_callback;
11054     if (asc_dvc->err_code != 0)
11055         return (ERR);
11056     if (scsiq == (ASC_SCSI_Q *) 0L) {
11057         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
11058         return (ERR);
11059     }
11060     scsiq->q1.q_no = 0;
11061     if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
11062         scsiq->q1.extra_bytes = 0;
11063     }
11064     sta = 0;
11065     target_ix = scsiq->q2.target_ix;
11066     tid_no = ASC_TIX_TO_TID(target_ix);
11067     n_q_required = 1;
11068     if (scsiq->cdbptr[0] == SCSICMD_RequestSense) {
11069         if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
11070             asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
11071             sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
11072             AscMsgOutSDTR(asc_dvc,
11073                           asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
11074                           (uchar) (asc_dvc->max_sdtr_index - 1)],
11075                           (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
11076             scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
11077         }
11078     }
11079     last_int_level = DvcEnterCritical();
11080     if (asc_dvc->in_critical_cnt != 0) {
11081         DvcLeaveCritical(last_int_level);
11082         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
11083         return (ERR);
11084     }
11085     asc_dvc->in_critical_cnt++;
11086     if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
11087         if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
11088             asc_dvc->in_critical_cnt--;
11089             DvcLeaveCritical(last_int_level);
11090             return (ERR);
11091         }
11092 #if !CC_VERY_LONG_SG_LIST
11093         if (sg_entry_cnt > ASC_MAX_SG_LIST)
11094         {
11095             asc_dvc->in_critical_cnt--;
11096             DvcLeaveCritical(last_int_level);
11097             return(ERR);
11098         }
11099 #endif /* !CC_VERY_LONG_SG_LIST */
11100         if (sg_entry_cnt == 1) {
11101             scsiq->q1.data_addr = (ADV_PADDR) sg_head->sg_list[0].addr;
11102             scsiq->q1.data_cnt = (ADV_DCNT) sg_head->sg_list[0].bytes;
11103             scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
11104         }
11105         sg_entry_cnt_minus_one = sg_entry_cnt - 1;
11106     }
11107     scsi_cmd = scsiq->cdbptr[0];
11108     disable_syn_offset_one_fix = FALSE;
11109     if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
11110         !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
11111         if (scsiq->q1.cntl & QC_SG_HEAD) {
11112             data_cnt = 0;
11113             for (i = 0; i < sg_entry_cnt; i++) {
11114                 data_cnt += (ADV_DCNT) le32_to_cpu(sg_head->sg_list[i].bytes);
11115             }
11116         } else {
11117             data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
11118         }
11119         if (data_cnt != 0UL) {
11120             if (data_cnt < 512UL) {
11121                 disable_syn_offset_one_fix = TRUE;
11122             } else {
11123                 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST; i++) {
11124                     disable_cmd = _syn_offset_one_disable_cmd[i];
11125                     if (disable_cmd == 0xFF) {
11126                         break;
11127                     }
11128                     if (scsi_cmd == disable_cmd) {
11129                         disable_syn_offset_one_fix = TRUE;
11130                         break;
11131                     }
11132                 }
11133             }
11134         }
11135     }
11136     if (disable_syn_offset_one_fix) {
11137         scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
11138         scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
11139                                ASC_TAG_FLAG_DISABLE_DISCONNECT);
11140     } else {
11141         scsiq->q2.tag_code &= 0x27;
11142     }
11143     if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
11144         if (asc_dvc->bug_fix_cntl) {
11145             if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
11146                 if ((scsi_cmd == SCSICMD_Read6) ||
11147                     (scsi_cmd == SCSICMD_Read10)) {
11148                     addr =
11149                         (ADV_PADDR) le32_to_cpu(
11150                             sg_head->sg_list[sg_entry_cnt_minus_one].addr) +
11151                         (ADV_DCNT) le32_to_cpu(
11152                             sg_head->sg_list[sg_entry_cnt_minus_one].bytes);
11153                     extra_bytes = (uchar) ((ushort) addr & 0x0003);
11154                     if ((extra_bytes != 0) &&
11155                         ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
11156                          == 0)) {
11157                         scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
11158                         scsiq->q1.extra_bytes = extra_bytes;
11159                         data_cnt = le32_to_cpu(
11160                             sg_head->sg_list[sg_entry_cnt_minus_one].bytes);
11161                         data_cnt -= (ASC_DCNT) extra_bytes;
11162                         sg_head->sg_list[sg_entry_cnt_minus_one].bytes =
11163                             cpu_to_le32(data_cnt);
11164                     }
11165                 }
11166             }
11167         }
11168         sg_head->entry_to_copy = sg_head->entry_cnt;
11169 #if CC_VERY_LONG_SG_LIST
11170         /*
11171          * Set the sg_entry_cnt to the maximum possible. The rest of
11172          * the SG elements will be copied when the RISC completes the
11173          * SG elements that fit and halts.
11174          */
11175         if (sg_entry_cnt > ASC_MAX_SG_LIST)
11176         {
11177              sg_entry_cnt = ASC_MAX_SG_LIST;
11178         }
11179 #endif /* CC_VERY_LONG_SG_LIST */
11180         n_q_required = AscSgListToQueue(sg_entry_cnt);
11181         if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
11182             (uint) n_q_required) || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
11183             if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
11184                                         n_q_required)) == 1) {
11185                 asc_dvc->in_critical_cnt--;
11186                 if (asc_exe_callback != 0) {
11187                     (*asc_exe_callback) (asc_dvc, scsiq);
11188                 }
11189                 DvcLeaveCritical(last_int_level);
11190                 return (sta);
11191             }
11192         }
11193     } else {
11194         if (asc_dvc->bug_fix_cntl) {
11195             if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
11196                 if ((scsi_cmd == SCSICMD_Read6) ||
11197                     (scsi_cmd == SCSICMD_Read10)) {
11198                     addr = le32_to_cpu(scsiq->q1.data_addr) +
11199                         le32_to_cpu(scsiq->q1.data_cnt);
11200                     extra_bytes = (uchar) ((ushort) addr & 0x0003);
11201                     if ((extra_bytes != 0) &&
11202                         ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
11203                           == 0)) {
11204                         data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
11205                         if (((ushort) data_cnt & 0x01FF) == 0) {
11206                             scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
11207                             data_cnt -= (ASC_DCNT) extra_bytes;
11208                             scsiq->q1.data_cnt = cpu_to_le32(data_cnt);
11209                             scsiq->q1.extra_bytes = extra_bytes;
11210                         }
11211                     }
11212                 }
11213             }
11214         }
11215         n_q_required = 1;
11216         if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
11217             ((scsiq->q1.cntl & QC_URGENT) != 0)) {
11218             if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
11219                                         n_q_required)) == 1) {
11220                 asc_dvc->in_critical_cnt--;
11221                 if (asc_exe_callback != 0) {
11222                     (*asc_exe_callback) (asc_dvc, scsiq);
11223                 }
11224                 DvcLeaveCritical(last_int_level);
11225                 return (sta);
11226             }
11227         }
11228     }
11229     asc_dvc->in_critical_cnt--;
11230     DvcLeaveCritical(last_int_level);
11231     return (sta);
11232 }
11233
11234 STATIC int
11235 AscSendScsiQueue(
11236                     ASC_DVC_VAR *asc_dvc,
11237                     ASC_SCSI_Q *scsiq,
11238                     uchar n_q_required
11239 )
11240 {
11241     PortAddr            iop_base;
11242     uchar               free_q_head;
11243     uchar               next_qp;
11244     uchar               tid_no;
11245     uchar               target_ix;
11246     int                 sta;
11247
11248     iop_base = asc_dvc->iop_base;
11249     target_ix = scsiq->q2.target_ix;
11250     tid_no = ASC_TIX_TO_TID(target_ix);
11251     sta = 0;
11252     free_q_head = (uchar) AscGetVarFreeQHead(iop_base);
11253     if (n_q_required > 1) {
11254         if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
11255                                        free_q_head, (uchar) (n_q_required)))
11256             != (uchar) ASC_QLINK_END) {
11257             asc_dvc->last_q_shortage = 0;
11258             scsiq->sg_head->queue_cnt = n_q_required - 1;
11259             scsiq->q1.q_no = free_q_head;
11260             if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
11261                                               free_q_head)) == 1) {
11262                 AscPutVarFreeQHead(iop_base, next_qp);
11263                 asc_dvc->cur_total_qng += (uchar) (n_q_required);
11264                 asc_dvc->cur_dvc_qng[tid_no]++;
11265             }
11266             return (sta);
11267         }
11268     } else if (n_q_required == 1) {
11269         if ((next_qp = AscAllocFreeQueue(iop_base,
11270                                          free_q_head)) != ASC_QLINK_END) {
11271             scsiq->q1.q_no = free_q_head;
11272             if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
11273                                         free_q_head)) == 1) {
11274                 AscPutVarFreeQHead(iop_base, next_qp);
11275                 asc_dvc->cur_total_qng++;
11276                 asc_dvc->cur_dvc_qng[tid_no]++;
11277             }
11278             return (sta);
11279         }
11280     }
11281     return (sta);
11282 }
11283
11284 STATIC int
11285 AscSgListToQueue(
11286                     int sg_list
11287 )
11288 {
11289     int                 n_sg_list_qs;
11290
11291     n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
11292     if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
11293         n_sg_list_qs++;
11294     return (n_sg_list_qs + 1);
11295 }
11296
11297
11298 STATIC uint
11299 AscGetNumOfFreeQueue(
11300                         ASC_DVC_VAR *asc_dvc,
11301                         uchar target_ix,
11302                         uchar n_qs
11303 )
11304 {
11305     uint                cur_used_qs;
11306     uint                cur_free_qs;
11307     ASC_SCSI_BIT_ID_TYPE target_id;
11308     uchar               tid_no;
11309
11310     target_id = ASC_TIX_TO_TARGET_ID(target_ix);
11311     tid_no = ASC_TIX_TO_TID(target_ix);
11312     if ((asc_dvc->unit_not_ready & target_id) ||
11313         (asc_dvc->queue_full_or_busy & target_id)) {
11314         return (0);
11315     }
11316     if (n_qs == 1) {
11317         cur_used_qs = (uint) asc_dvc->cur_total_qng +
11318           (uint) asc_dvc->last_q_shortage +
11319           (uint) ASC_MIN_FREE_Q;
11320     } else {
11321         cur_used_qs = (uint) asc_dvc->cur_total_qng +
11322           (uint) ASC_MIN_FREE_Q;
11323     }
11324     if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
11325         cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
11326         if (asc_dvc->cur_dvc_qng[tid_no] >=
11327             asc_dvc->max_dvc_qng[tid_no]) {
11328             return (0);
11329         }
11330         return (cur_free_qs);
11331     }
11332     if (n_qs > 1) {
11333         if ((n_qs > asc_dvc->last_q_shortage) && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
11334             asc_dvc->last_q_shortage = n_qs;
11335         }
11336     }
11337     return (0);
11338 }
11339
11340 STATIC int
11341 AscPutReadyQueue(
11342                     ASC_DVC_VAR *asc_dvc,
11343                     ASC_SCSI_Q *scsiq,
11344                     uchar q_no
11345 )
11346 {
11347     ushort              q_addr;
11348     uchar               tid_no;
11349     uchar               sdtr_data;
11350     uchar               syn_period_ix;
11351     uchar               syn_offset;
11352     PortAddr            iop_base;
11353
11354     iop_base = asc_dvc->iop_base;
11355     if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
11356         ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
11357         tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
11358         sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
11359         syn_period_ix = (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
11360         syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
11361         AscMsgOutSDTR(asc_dvc,
11362                       asc_dvc->sdtr_period_tbl[syn_period_ix],
11363                       syn_offset);
11364         scsiq->q1.cntl |= QC_MSG_OUT;
11365     }
11366     q_addr = ASC_QNO_TO_QADDR(q_no);
11367     if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
11368         scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
11369     }
11370     scsiq->q1.status = QS_FREE;
11371     AscMemWordCopyPtrToLram(iop_base,
11372                          q_addr + ASC_SCSIQ_CDB_BEG,
11373                          (uchar *) scsiq->cdbptr,
11374                          scsiq->q2.cdb_len >> 1);
11375
11376     DvcPutScsiQ(iop_base,
11377                 q_addr + ASC_SCSIQ_CPY_BEG,
11378                 (uchar *) &scsiq->q1.cntl,
11379                 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
11380     AscWriteLramWord(iop_base,
11381                      (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
11382              (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY));
11383     return (1);
11384 }
11385
11386 STATIC int
11387 AscPutReadySgListQueue(
11388                           ASC_DVC_VAR *asc_dvc,
11389                           ASC_SCSI_Q *scsiq,
11390                           uchar q_no
11391 )
11392 {
11393     int                 sta;
11394     int                 i;
11395     ASC_SG_HEAD *sg_head;
11396     ASC_SG_LIST_Q       scsi_sg_q;
11397     ASC_DCNT            saved_data_addr;
11398     ASC_DCNT            saved_data_cnt;
11399     PortAddr            iop_base;
11400     ushort              sg_list_dwords;
11401     ushort              sg_index;
11402     ushort              sg_entry_cnt;
11403     ushort              q_addr;
11404     uchar               next_qp;
11405
11406     iop_base = asc_dvc->iop_base;
11407     sg_head = scsiq->sg_head;
11408     saved_data_addr = scsiq->q1.data_addr;
11409     saved_data_cnt = scsiq->q1.data_cnt;
11410     scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
11411     scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
11412 #if CC_VERY_LONG_SG_LIST
11413     /*
11414      * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
11415      * then not all SG elements will fit in the allocated queues.
11416      * The rest of the SG elements will be copied when the RISC
11417      * completes the SG elements that fit and halts.
11418      */
11419     if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
11420     {
11421          /*
11422           * Set sg_entry_cnt to be the number of SG elements that
11423           * will fit in the allocated SG queues. It is minus 1, because
11424           * the first SG element is handled above. ASC_MAX_SG_LIST is
11425           * already inflated by 1 to account for this. For example it
11426           * may be 50 which is 1 + 7 queues * 7 SG elements.
11427           */
11428          sg_entry_cnt = ASC_MAX_SG_LIST - 1;
11429
11430          /*
11431           * Keep track of remaining number of SG elements that will
11432           * need to be handled from a_isr.c.
11433           */
11434          scsiq->remain_sg_entry_cnt = sg_head->entry_cnt - ASC_MAX_SG_LIST;
11435     } else
11436     {
11437 #endif /* CC_VERY_LONG_SG_LIST */
11438          /*
11439           * Set sg_entry_cnt to be the number of SG elements that
11440           * will fit in the allocated SG queues. It is minus 1, because
11441           * the first SG element is handled above.
11442           */
11443          sg_entry_cnt = sg_head->entry_cnt - 1;
11444 #if CC_VERY_LONG_SG_LIST
11445     }
11446 #endif /* CC_VERY_LONG_SG_LIST */
11447     if (sg_entry_cnt != 0) {
11448         scsiq->q1.cntl |= QC_SG_HEAD;
11449         q_addr = ASC_QNO_TO_QADDR(q_no);
11450         sg_index = 1;
11451         scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
11452         scsi_sg_q.sg_head_qp = q_no;
11453         scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
11454         for (i = 0; i < sg_head->queue_cnt; i++) {
11455             scsi_sg_q.seq_no = i + 1;
11456             if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
11457                 sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
11458                 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
11459                 if (i == 0) {
11460                     scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q;
11461                     scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q;
11462                 } else {
11463                     scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
11464                     scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
11465                 }
11466             } else {
11467 #if CC_VERY_LONG_SG_LIST
11468                 /*
11469                  * This is the last SG queue in the list of
11470                  * allocated SG queues. If there are more
11471                  * SG elements than will fit in the allocated
11472                  * queues, then set the QCSG_SG_XFER_MORE flag.
11473                  */
11474                 if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
11475                 {
11476                     scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
11477                 } else
11478                 {
11479 #endif /* CC_VERY_LONG_SG_LIST */
11480                     scsi_sg_q.cntl |= QCSG_SG_XFER_END;
11481 #if CC_VERY_LONG_SG_LIST
11482                 }
11483 #endif /* CC_VERY_LONG_SG_LIST */
11484                 sg_list_dwords = sg_entry_cnt << 1;
11485                 if (i == 0) {
11486                     scsi_sg_q.sg_list_cnt = sg_entry_cnt;
11487                     scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt;
11488                 } else {
11489                     scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
11490                     scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
11491                 }
11492                 sg_entry_cnt = 0;
11493             }
11494             next_qp = AscReadLramByte(iop_base,
11495                                       (ushort) (q_addr + ASC_SCSIQ_B_FWD));
11496             scsi_sg_q.q_no = next_qp;
11497             q_addr = ASC_QNO_TO_QADDR(next_qp);
11498             AscMemWordCopyPtrToLram(iop_base,
11499                                 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
11500                                 (uchar *) &scsi_sg_q,
11501                                 sizeof(ASC_SG_LIST_Q) >> 1);
11502             AscMemDWordCopyPtrToLram(iop_base,
11503                                 q_addr + ASC_SGQ_LIST_BEG,
11504                                 (uchar *) &sg_head->sg_list[sg_index],
11505                                 sg_list_dwords);
11506             sg_index += ASC_SG_LIST_PER_Q;
11507             scsiq->next_sg_index = sg_index;
11508         }
11509     } else {
11510         scsiq->q1.cntl &= ~QC_SG_HEAD;
11511     }
11512     sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
11513     scsiq->q1.data_addr = saved_data_addr;
11514     scsiq->q1.data_cnt = saved_data_cnt;
11515     return (sta);
11516 }
11517
11518 STATIC int
11519 AscSetRunChipSynRegAtID(
11520                            PortAddr iop_base,
11521                            uchar tid_no,
11522                            uchar sdtr_data
11523 )
11524 {
11525     int                 sta = FALSE;
11526
11527     if (AscHostReqRiscHalt(iop_base)) {
11528         sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
11529         AscStartChip(iop_base);
11530         return (sta);
11531     }
11532     return (sta);
11533 }
11534
11535 STATIC int
11536 AscSetChipSynRegAtID(
11537                         PortAddr iop_base,
11538                         uchar id,
11539                         uchar sdtr_data
11540 )
11541 {
11542     ASC_SCSI_BIT_ID_TYPE org_id;
11543     int                 i;
11544     int                 sta = TRUE;
11545
11546     AscSetBank(iop_base, 1);
11547     org_id = AscReadChipDvcID(iop_base);
11548     for (i = 0; i <= ASC_MAX_TID; i++) {
11549         if (org_id == (0x01 << i))
11550             break;
11551     }
11552     org_id = (ASC_SCSI_BIT_ID_TYPE) i;
11553     AscWriteChipDvcID(iop_base, id);
11554     if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
11555         AscSetBank(iop_base, 0);
11556         AscSetChipSyn(iop_base, sdtr_data);
11557         if (AscGetChipSyn(iop_base) != sdtr_data) {
11558             sta = FALSE;
11559         }
11560     } else {
11561         sta = FALSE;
11562     }
11563     AscSetBank(iop_base, 1);
11564     AscWriteChipDvcID(iop_base, org_id);
11565     AscSetBank(iop_base, 0);
11566     return (sta);
11567 }
11568
11569 STATIC ushort
11570 AscInitLram(
11571                ASC_DVC_VAR *asc_dvc
11572 )
11573 {
11574     uchar               i;
11575     ushort              s_addr;
11576     PortAddr            iop_base;
11577     ushort              warn_code;
11578
11579     iop_base = asc_dvc->iop_base;
11580     warn_code = 0;
11581     AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
11582                (ushort) (((int) (asc_dvc->max_total_qng + 2 + 1) * 64) >> 1)
11583 );
11584     i = ASC_MIN_ACTIVE_QNO;
11585     s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
11586     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11587                      (uchar) (i + 1));
11588     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11589                      (uchar) (asc_dvc->max_total_qng));
11590     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11591                      (uchar) i);
11592     i++;
11593     s_addr += ASC_QBLK_SIZE;
11594     for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
11595         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11596                          (uchar) (i + 1));
11597         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11598                          (uchar) (i - 1));
11599         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11600                          (uchar) i);
11601     }
11602     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11603                      (uchar) ASC_QLINK_END);
11604     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11605                      (uchar) (asc_dvc->max_total_qng - 1));
11606     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11607                      (uchar) asc_dvc->max_total_qng);
11608     i++;
11609     s_addr += ASC_QBLK_SIZE;
11610     for (; i <= (uchar) (asc_dvc->max_total_qng + 3);
11611          i++, s_addr += ASC_QBLK_SIZE) {
11612         AscWriteLramByte(iop_base,
11613                          (ushort) (s_addr + (ushort) ASC_SCSIQ_B_FWD), i);
11614         AscWriteLramByte(iop_base,
11615                          (ushort) (s_addr + (ushort) ASC_SCSIQ_B_BWD), i);
11616         AscWriteLramByte(iop_base,
11617                          (ushort) (s_addr + (ushort) ASC_SCSIQ_B_QNO), i);
11618     }
11619     return (warn_code);
11620 }
11621
11622 STATIC ushort
11623 AscInitQLinkVar(
11624                    ASC_DVC_VAR *asc_dvc
11625 )
11626 {
11627     PortAddr            iop_base;
11628     int                 i;
11629     ushort              lram_addr;
11630
11631     iop_base = asc_dvc->iop_base;
11632     AscPutRiscVarFreeQHead(iop_base, 1);
11633     AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
11634     AscPutVarFreeQHead(iop_base, 1);
11635     AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
11636     AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
11637                      (uchar) ((int) asc_dvc->max_total_qng + 1));
11638     AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
11639                      (uchar) ((int) asc_dvc->max_total_qng + 2));
11640     AscWriteLramByte(iop_base, (ushort) ASCV_TOTAL_READY_Q_B,
11641                      asc_dvc->max_total_qng);
11642     AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
11643     AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
11644     AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
11645     AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
11646     AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
11647     AscPutQDoneInProgress(iop_base, 0);
11648     lram_addr = ASC_QADR_BEG;
11649     for (i = 0; i < 32; i++, lram_addr += 2) {
11650         AscWriteLramWord(iop_base, lram_addr, 0);
11651     }
11652     return (0);
11653 }
11654
11655 STATIC int
11656 AscSetLibErrorCode(
11657                       ASC_DVC_VAR *asc_dvc,
11658                       ushort err_code
11659 )
11660 {
11661     if (asc_dvc->err_code == 0) {
11662         asc_dvc->err_code = err_code;
11663         AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
11664                          err_code);
11665     }
11666     return (err_code);
11667 }
11668
11669
11670 STATIC uchar
11671 AscMsgOutSDTR(
11672                  ASC_DVC_VAR *asc_dvc,
11673                  uchar sdtr_period,
11674                  uchar sdtr_offset
11675 )
11676 {
11677     EXT_MSG             sdtr_buf;
11678     uchar               sdtr_period_index;
11679     PortAddr            iop_base;
11680
11681     iop_base = asc_dvc->iop_base;
11682     sdtr_buf.msg_type = MS_EXTEND;
11683     sdtr_buf.msg_len = MS_SDTR_LEN;
11684     sdtr_buf.msg_req = MS_SDTR_CODE;
11685     sdtr_buf.xfer_period = sdtr_period;
11686     sdtr_offset &= ASC_SYN_MAX_OFFSET;
11687     sdtr_buf.req_ack_offset = sdtr_offset;
11688     if ((sdtr_period_index =
11689          AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
11690         asc_dvc->max_sdtr_index) {
11691         AscMemWordCopyPtrToLram(iop_base,
11692                              ASCV_MSGOUT_BEG,
11693                              (uchar *) &sdtr_buf,
11694                              sizeof (EXT_MSG) >> 1);
11695         return ((sdtr_period_index << 4) | sdtr_offset);
11696     } else {
11697
11698         sdtr_buf.req_ack_offset = 0;
11699         AscMemWordCopyPtrToLram(iop_base,
11700                              ASCV_MSGOUT_BEG,
11701                              (uchar *) &sdtr_buf,
11702                              sizeof (EXT_MSG) >> 1);
11703         return (0);
11704     }
11705 }
11706
11707 STATIC uchar
11708 AscCalSDTRData(
11709                   ASC_DVC_VAR *asc_dvc,
11710                   uchar sdtr_period,
11711                   uchar syn_offset
11712 )
11713 {
11714     uchar               byte;
11715     uchar               sdtr_period_ix;
11716
11717     sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
11718     if (
11719            (sdtr_period_ix > asc_dvc->max_sdtr_index)
11720 ) {
11721         return (0xFF);
11722     }
11723     byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
11724     return (byte);
11725 }
11726
11727 STATIC void
11728 AscSetChipSDTR(
11729                   PortAddr iop_base,
11730                   uchar sdtr_data,
11731                   uchar tid_no
11732 )
11733 {
11734     AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
11735     AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
11736     return;
11737 }
11738
11739 STATIC uchar
11740 AscGetSynPeriodIndex(
11741                         ASC_DVC_VAR *asc_dvc,
11742                         uchar syn_time
11743 )
11744 {
11745     uchar             *period_table;
11746     int                 max_index;
11747     int                 min_index;
11748     int                 i;
11749
11750     period_table = asc_dvc->sdtr_period_tbl;
11751     max_index = (int) asc_dvc->max_sdtr_index;
11752     min_index = (int)asc_dvc->host_init_sdtr_index;
11753     if ((syn_time <= period_table[max_index])) {
11754         for (i = min_index; i < (max_index - 1); i++) {
11755             if (syn_time <= period_table[i]) {
11756                 return ((uchar) i);
11757             }
11758         }
11759         return ((uchar) max_index);
11760     } else {
11761         return ((uchar) (max_index + 1));
11762     }
11763 }
11764
11765 STATIC uchar
11766 AscAllocFreeQueue(
11767                      PortAddr iop_base,
11768                      uchar free_q_head
11769 )
11770 {
11771     ushort              q_addr;
11772     uchar               next_qp;
11773     uchar               q_status;
11774
11775     q_addr = ASC_QNO_TO_QADDR(free_q_head);
11776     q_status = (uchar) AscReadLramByte(iop_base,
11777                                     (ushort) (q_addr + ASC_SCSIQ_B_STATUS));
11778     next_qp = AscReadLramByte(iop_base,
11779                               (ushort) (q_addr + ASC_SCSIQ_B_FWD));
11780     if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
11781         return (next_qp);
11782     }
11783     return (ASC_QLINK_END);
11784 }
11785
11786 STATIC uchar
11787 AscAllocMultipleFreeQueue(
11788                              PortAddr iop_base,
11789                              uchar free_q_head,
11790                              uchar n_free_q
11791 )
11792 {
11793     uchar               i;
11794
11795     for (i = 0; i < n_free_q; i++) {
11796         if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
11797             == ASC_QLINK_END) {
11798             return (ASC_QLINK_END);
11799         }
11800     }
11801     return (free_q_head);
11802 }
11803
11804 STATIC int
11805 AscHostReqRiscHalt(
11806                       PortAddr iop_base
11807 )
11808 {
11809     int                 count = 0;
11810     int                 sta = 0;
11811     uchar               saved_stop_code;
11812
11813     if (AscIsChipHalted(iop_base))
11814         return (1);
11815     saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
11816     AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11817                      ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP
11818 );
11819     do {
11820         if (AscIsChipHalted(iop_base)) {
11821             sta = 1;
11822             break;
11823         }
11824         DvcSleepMilliSecond(100);
11825     } while (count++ < 20);
11826     AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
11827     return (sta);
11828 }
11829
11830 STATIC int
11831 AscStopQueueExe(
11832                    PortAddr iop_base
11833 )
11834 {
11835     int                 count = 0;
11836
11837     if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
11838         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11839                          ASC_STOP_REQ_RISC_STOP);
11840         do {
11841             if (
11842                    AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
11843                    ASC_STOP_ACK_RISC_STOP) {
11844                 return (1);
11845             }
11846             DvcSleepMilliSecond(100);
11847         } while (count++ < 20);
11848     }
11849     return (0);
11850 }
11851
11852 STATIC void
11853 DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
11854 {
11855     udelay(micro_sec);
11856 }
11857
11858 STATIC void
11859 DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
11860 {
11861     udelay((nano_sec + 999)/1000);
11862 }
11863
11864 #ifdef CONFIG_ISA
11865 ASC_INITFUNC(
11866 STATIC ASC_DCNT,
11867 AscGetEisaProductID(
11868                        PortAddr iop_base
11869 )
11870 )
11871 {
11872     PortAddr            eisa_iop;
11873     ushort              product_id_high, product_id_low;
11874     ASC_DCNT            product_id;
11875
11876     eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
11877     product_id_low = inpw(eisa_iop);
11878     product_id_high = inpw(eisa_iop + 2);
11879     product_id = ((ASC_DCNT) product_id_high << 16) |
11880         (ASC_DCNT) product_id_low;
11881     return (product_id);
11882 }
11883
11884 ASC_INITFUNC(
11885 STATIC PortAddr,
11886 AscSearchIOPortAddrEISA(
11887                            PortAddr iop_base
11888 )
11889 )
11890 {
11891     ASC_DCNT            eisa_product_id;
11892
11893     if (iop_base == 0) {
11894         iop_base = ASC_EISA_MIN_IOP_ADDR;
11895     } else {
11896         if (iop_base == ASC_EISA_MAX_IOP_ADDR)
11897             return (0);
11898         if ((iop_base & 0x0050) == 0x0050) {
11899             iop_base += ASC_EISA_BIG_IOP_GAP;
11900         } else {
11901             iop_base += ASC_EISA_SMALL_IOP_GAP;
11902         }
11903     }
11904     while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
11905         eisa_product_id = AscGetEisaProductID(iop_base);
11906         if ((eisa_product_id == ASC_EISA_ID_740) ||
11907             (eisa_product_id == ASC_EISA_ID_750)) {
11908             if (AscFindSignature(iop_base)) {
11909                 inpw(iop_base + 4);
11910                 return (iop_base);
11911             }
11912         }
11913         if (iop_base == ASC_EISA_MAX_IOP_ADDR)
11914             return (0);
11915         if ((iop_base & 0x0050) == 0x0050) {
11916             iop_base += ASC_EISA_BIG_IOP_GAP;
11917         } else {
11918             iop_base += ASC_EISA_SMALL_IOP_GAP;
11919         }
11920     }
11921     return (0);
11922 }
11923 #endif /* CONFIG_ISA */
11924
11925 STATIC int
11926 AscStartChip(
11927                 PortAddr iop_base
11928 )
11929 {
11930     AscSetChipControl(iop_base, 0);
11931     if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
11932         return (0);
11933     }
11934     return (1);
11935 }
11936
11937 STATIC int
11938 AscStopChip(
11939                PortAddr iop_base
11940 )
11941 {
11942     uchar               cc_val;
11943
11944     cc_val = AscGetChipControl(iop_base) & (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
11945     AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT));
11946     AscSetChipIH(iop_base, INS_HALT);
11947     AscSetChipIH(iop_base, INS_RFLAG_WTM);
11948     if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
11949         return (0);
11950     }
11951     return (1);
11952 }
11953
11954 STATIC int
11955 AscIsChipHalted(
11956                    PortAddr iop_base
11957 )
11958 {
11959     if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
11960         if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
11961             return (1);
11962         }
11963     }
11964     return (0);
11965 }
11966
11967 STATIC void
11968 AscSetChipIH(
11969                 PortAddr iop_base,
11970                 ushort ins_code
11971 )
11972 {
11973     AscSetBank(iop_base, 1);
11974     AscWriteChipIH(iop_base, ins_code);
11975     AscSetBank(iop_base, 0);
11976     return;
11977 }
11978
11979 STATIC void
11980 AscAckInterrupt(
11981                    PortAddr iop_base
11982 )
11983 {
11984     uchar               host_flag;
11985     uchar               risc_flag;
11986     ushort              loop;
11987
11988     loop = 0;
11989     do {
11990         risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
11991         if (loop++ > 0x7FFF) {
11992             break;
11993         }
11994     } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
11995     host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
11996     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
11997                      (uchar) (host_flag | ASC_HOST_FLAG_ACK_INT));
11998     AscSetChipStatus(iop_base, CIW_INT_ACK);
11999     loop = 0;
12000     while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
12001         AscSetChipStatus(iop_base, CIW_INT_ACK);
12002         if (loop++ > 3) {
12003             break;
12004         }
12005     }
12006     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
12007     return;
12008 }
12009
12010 STATIC void
12011 AscDisableInterrupt(
12012                        PortAddr iop_base
12013 )
12014 {
12015     ushort              cfg;
12016
12017     cfg = AscGetChipCfgLsw(iop_base);
12018     AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
12019     return;
12020 }
12021
12022 STATIC void
12023 AscEnableInterrupt(
12024                       PortAddr iop_base
12025 )
12026 {
12027     ushort              cfg;
12028
12029     cfg = AscGetChipCfgLsw(iop_base);
12030     AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
12031     return;
12032 }
12033
12034
12035
12036 STATIC void
12037 AscSetBank(
12038               PortAddr iop_base,
12039               uchar bank
12040 )
12041 {
12042     uchar               val;
12043
12044     val = AscGetChipControl(iop_base) &
12045       (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | CC_CHIP_RESET));
12046     if (bank == 1) {
12047         val |= CC_BANK_ONE;
12048     } else if (bank == 2) {
12049         val |= CC_DIAG | CC_BANK_ONE;
12050     } else {
12051         val &= ~CC_BANK_ONE;
12052     }
12053     AscSetChipControl(iop_base, val);
12054     return;
12055 }
12056
12057 STATIC int
12058 AscResetChipAndScsiBus(
12059                           ASC_DVC_VAR *asc_dvc
12060 )
12061 {
12062     PortAddr    iop_base;
12063     int         i = 10;
12064
12065     iop_base = asc_dvc->iop_base;
12066     while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) && (i-- > 0))
12067     {
12068           DvcSleepMilliSecond(100);
12069     }
12070     AscStopChip(iop_base);
12071     AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
12072     DvcDelayNanoSecond(asc_dvc, 60000);
12073     AscSetChipIH(iop_base, INS_RFLAG_WTM);
12074     AscSetChipIH(iop_base, INS_HALT);
12075     AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
12076     AscSetChipControl(iop_base, CC_HALT);
12077     DvcSleepMilliSecond(200);
12078     AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
12079     AscSetChipStatus(iop_base, 0);
12080     return (AscIsChipHalted(iop_base));
12081 }
12082
12083 ASC_INITFUNC(
12084 STATIC ASC_DCNT,
12085 AscGetMaxDmaCount(
12086                      ushort bus_type
12087 )
12088 )
12089 {
12090     if (bus_type & ASC_IS_ISA)
12091         return (ASC_MAX_ISA_DMA_COUNT);
12092     else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
12093         return (ASC_MAX_VL_DMA_COUNT);
12094     return (ASC_MAX_PCI_DMA_COUNT);
12095 }
12096
12097 #ifdef CONFIG_ISA
12098 ASC_INITFUNC(
12099 STATIC ushort,
12100 AscGetIsaDmaChannel(
12101                        PortAddr iop_base
12102 )
12103 )
12104 {
12105     ushort              channel;
12106
12107     channel = AscGetChipCfgLsw(iop_base) & 0x0003;
12108     if (channel == 0x03)
12109         return (0);
12110     else if (channel == 0x00)
12111         return (7);
12112     return (channel + 4);
12113 }
12114
12115 ASC_INITFUNC(
12116 STATIC ushort,
12117 AscSetIsaDmaChannel(
12118                        PortAddr iop_base,
12119                        ushort dma_channel
12120 )
12121 )
12122 {
12123     ushort              cfg_lsw;
12124     uchar               value;
12125
12126     if ((dma_channel >= 5) && (dma_channel <= 7)) {
12127         if (dma_channel == 7)
12128             value = 0x00;
12129         else
12130             value = dma_channel - 4;
12131         cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
12132         cfg_lsw |= value;
12133         AscSetChipCfgLsw(iop_base, cfg_lsw);
12134         return (AscGetIsaDmaChannel(iop_base));
12135     }
12136     return (0);
12137 }
12138
12139 ASC_INITFUNC(
12140 STATIC uchar,
12141 AscSetIsaDmaSpeed(
12142                      PortAddr iop_base,
12143                      uchar speed_value
12144 )
12145 )
12146 {
12147     speed_value &= 0x07;
12148     AscSetBank(iop_base, 1);
12149     AscWriteChipDmaSpeed(iop_base, speed_value);
12150     AscSetBank(iop_base, 0);
12151     return (AscGetIsaDmaSpeed(iop_base));
12152 }
12153
12154 ASC_INITFUNC(
12155 STATIC uchar,
12156 AscGetIsaDmaSpeed(
12157                      PortAddr iop_base
12158 )
12159 )
12160 {
12161     uchar               speed_value;
12162
12163     AscSetBank(iop_base, 1);
12164     speed_value = AscReadChipDmaSpeed(iop_base);
12165     speed_value &= 0x07;
12166     AscSetBank(iop_base, 0);
12167     return (speed_value);
12168 }
12169 #endif /* CONFIG_ISA */
12170
12171 ASC_INITFUNC(
12172 STATIC ushort,
12173 AscReadPCIConfigWord(
12174     ASC_DVC_VAR *asc_dvc,
12175     ushort pci_config_offset)
12176 )
12177 {
12178     uchar       lsb, msb;
12179
12180     lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
12181     msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
12182     return ((ushort) ((msb << 8) | lsb));
12183 }
12184
12185 ASC_INITFUNC(
12186 STATIC ushort,
12187 AscInitGetConfig(
12188         ASC_DVC_VAR *asc_dvc
12189 )
12190 )
12191 {
12192     ushort              warn_code;
12193     PortAddr            iop_base;
12194     ushort              PCIDeviceID;
12195     ushort              PCIVendorID;
12196     uchar               PCIRevisionID;
12197     uchar               prevCmdRegBits;
12198
12199     warn_code = 0;
12200     iop_base = asc_dvc->iop_base;
12201     asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
12202     if (asc_dvc->err_code != 0) {
12203         return (UW_ERR);
12204     }
12205     if (asc_dvc->bus_type == ASC_IS_PCI) {
12206         PCIVendorID = AscReadPCIConfigWord(asc_dvc,
12207                                     AscPCIConfigVendorIDRegister);
12208
12209         PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
12210                                     AscPCIConfigDeviceIDRegister);
12211
12212         PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
12213                                     AscPCIConfigRevisionIDRegister);
12214
12215         if (PCIVendorID != ASC_PCI_VENDORID) {
12216             warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
12217         }
12218         prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
12219                                     AscPCIConfigCommandRegister);
12220
12221         if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
12222             AscPCICmdRegBits_IOMemBusMaster) {
12223             DvcWritePCIConfigByte(asc_dvc,
12224                             AscPCIConfigCommandRegister,
12225                             (prevCmdRegBits |
12226                              AscPCICmdRegBits_IOMemBusMaster));
12227
12228             if ((DvcReadPCIConfigByte(asc_dvc,
12229                                 AscPCIConfigCommandRegister)
12230                  & AscPCICmdRegBits_IOMemBusMaster)
12231                 != AscPCICmdRegBits_IOMemBusMaster) {
12232                 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
12233             }
12234         }
12235         if ((PCIDeviceID == ASC_PCI_DEVICEID_1200A) ||
12236             (PCIDeviceID == ASC_PCI_DEVICEID_1200B)) {
12237             DvcWritePCIConfigByte(asc_dvc,
12238                             AscPCIConfigLatencyTimer, 0x00);
12239             if (DvcReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer)
12240                 != 0x00) {
12241                 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
12242             }
12243         } else if (PCIDeviceID == ASC_PCI_DEVICEID_ULTRA) {
12244             if (DvcReadPCIConfigByte(asc_dvc,
12245                                 AscPCIConfigLatencyTimer) < 0x20) {
12246                 DvcWritePCIConfigByte(asc_dvc,
12247                                     AscPCIConfigLatencyTimer, 0x20);
12248
12249                 if (DvcReadPCIConfigByte(asc_dvc,
12250                                     AscPCIConfigLatencyTimer) < 0x20) {
12251                     warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
12252                 }
12253             }
12254         }
12255     }
12256
12257     if (AscFindSignature(iop_base)) {
12258         warn_code |= AscInitAscDvcVar(asc_dvc);
12259         warn_code |= AscInitFromEEP(asc_dvc);
12260         asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
12261         if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
12262             asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
12263         }
12264     } else {
12265         asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12266     }
12267     return(warn_code);
12268 }
12269
12270 ASC_INITFUNC(
12271 STATIC ushort,
12272 AscInitSetConfig(
12273                     ASC_DVC_VAR *asc_dvc
12274 )
12275 )
12276 {
12277     ushort              warn_code = 0;
12278
12279     asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
12280     if (asc_dvc->err_code != 0)
12281         return (UW_ERR);
12282     if (AscFindSignature(asc_dvc->iop_base)) {
12283         warn_code |= AscInitFromAscDvcVar(asc_dvc);
12284         asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
12285     } else {
12286         asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12287     }
12288     return (warn_code);
12289 }
12290
12291 ASC_INITFUNC(
12292 STATIC ushort,
12293 AscInitFromAscDvcVar(
12294                         ASC_DVC_VAR *asc_dvc
12295 )
12296 )
12297 {
12298     PortAddr            iop_base;
12299     ushort              cfg_msw;
12300     ushort              warn_code;
12301     ushort              pci_device_id;
12302
12303     iop_base = asc_dvc->iop_base;
12304     pci_device_id = asc_dvc->cfg->pci_dev->device;
12305     warn_code = 0;
12306     cfg_msw = AscGetChipCfgMsw(iop_base);
12307     if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12308         cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
12309         warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12310         AscSetChipCfgMsw(iop_base, cfg_msw);
12311     }
12312     if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
12313         asc_dvc->cfg->cmd_qng_enabled) {
12314         asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
12315         warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12316     }
12317     if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12318         warn_code |= ASC_WARN_AUTO_CONFIG;
12319     }
12320     if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
12321         if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
12322             != asc_dvc->irq_no) {
12323             asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
12324         }
12325     }
12326     if (asc_dvc->bus_type & ASC_IS_PCI) {
12327         cfg_msw &= 0xFFC0;
12328         AscSetChipCfgMsw(iop_base, cfg_msw);
12329         if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
12330         } else {
12331             if ((pci_device_id == ASC_PCI_DEVICE_ID_REV_A) ||
12332                 (pci_device_id == ASC_PCI_DEVICE_ID_REV_B)) {
12333                 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
12334                 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
12335             }
12336         }
12337     } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
12338         if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
12339             == ASC_CHIP_VER_ASYN_BUG) {
12340             asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
12341         }
12342     }
12343     if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
12344         asc_dvc->cfg->chip_scsi_id) {
12345         asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
12346     }
12347 #ifdef CONFIG_ISA
12348     if (asc_dvc->bus_type & ASC_IS_ISA) {
12349         AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
12350         AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
12351     }
12352 #endif /* CONFIG_ISA */
12353     return (warn_code);
12354 }
12355
12356 STATIC ushort
12357 AscInitAsc1000Driver(
12358                         ASC_DVC_VAR *asc_dvc
12359 )
12360 {
12361     ushort              warn_code;
12362     PortAddr            iop_base;
12363
12364     iop_base = asc_dvc->iop_base;
12365     warn_code = 0;
12366     if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
12367         !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
12368         AscResetChipAndScsiBus(asc_dvc);
12369         DvcSleepMilliSecond((ASC_DCNT)
12370             ((ushort) asc_dvc->scsi_reset_wait * 1000));
12371     }
12372     asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
12373     if (asc_dvc->err_code != 0)
12374         return (UW_ERR);
12375     if (!AscFindSignature(asc_dvc->iop_base)) {
12376         asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12377         return (warn_code);
12378     }
12379     AscDisableInterrupt(iop_base);
12380     warn_code |= AscInitLram(asc_dvc);
12381     if (asc_dvc->err_code != 0)
12382         return (UW_ERR);
12383     ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
12384         (ulong) _asc_mcode_chksum);
12385     if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
12386                          _asc_mcode_size) != _asc_mcode_chksum) {
12387         asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
12388         return (warn_code);
12389     }
12390     warn_code |= AscInitMicroCodeVar(asc_dvc);
12391     asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
12392     AscEnableInterrupt(iop_base);
12393     return (warn_code);
12394 }
12395
12396 ASC_INITFUNC(
12397 STATIC ushort,
12398 AscInitAscDvcVar(
12399                     ASC_DVC_VAR *asc_dvc
12400 )
12401 )
12402 {
12403     int                 i;
12404     PortAddr            iop_base;
12405     ushort              warn_code;
12406     uchar               chip_version;
12407
12408     iop_base = asc_dvc->iop_base;
12409     warn_code = 0;
12410     asc_dvc->err_code = 0;
12411     if ((asc_dvc->bus_type &
12412          (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
12413         asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
12414     }
12415     AscSetChipControl(iop_base, CC_HALT);
12416     AscSetChipStatus(iop_base, 0);
12417     asc_dvc->bug_fix_cntl = 0;
12418     asc_dvc->pci_fix_asyn_xfer = 0;
12419     asc_dvc->pci_fix_asyn_xfer_always = 0;
12420     /* asc_dvc->init_state initalized in AscInitGetConfig(). */
12421     asc_dvc->sdtr_done = 0;
12422     asc_dvc->cur_total_qng = 0;
12423     asc_dvc->is_in_int = 0;
12424     asc_dvc->in_critical_cnt = 0;
12425     asc_dvc->last_q_shortage = 0;
12426     asc_dvc->use_tagged_qng = 0;
12427     asc_dvc->no_scam = 0;
12428     asc_dvc->unit_not_ready = 0;
12429     asc_dvc->queue_full_or_busy = 0;
12430     asc_dvc->redo_scam = 0;
12431     asc_dvc->res2 = 0;
12432     asc_dvc->host_init_sdtr_index = 0;
12433     asc_dvc->cfg->can_tagged_qng = 0;
12434     asc_dvc->cfg->cmd_qng_enabled = 0;
12435     asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
12436     asc_dvc->init_sdtr = 0;
12437     asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
12438     asc_dvc->scsi_reset_wait = 3;
12439     asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
12440     asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
12441     asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
12442     asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
12443     asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
12444     asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
12445     asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
12446       ASC_LIB_VERSION_MINOR;
12447     chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
12448     asc_dvc->cfg->chip_version = chip_version;
12449     asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
12450     asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
12451     asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
12452     asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
12453     asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
12454     asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
12455     asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
12456     asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
12457     asc_dvc->max_sdtr_index = 7;
12458     if ((asc_dvc->bus_type & ASC_IS_PCI) &&
12459         (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
12460         asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
12461         asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
12462         asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
12463         asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
12464         asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
12465         asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
12466         asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
12467         asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
12468         asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
12469         asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
12470         asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
12471         asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
12472         asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
12473         asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
12474         asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
12475         asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
12476         asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
12477         asc_dvc->max_sdtr_index = 15;
12478         if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150)
12479         {
12480             AscSetExtraControl(iop_base,
12481                 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
12482         } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
12483             AscSetExtraControl(iop_base,
12484                 (SEC_ACTIVE_NEGATE | SEC_ENABLE_FILTER));
12485         }
12486     }
12487     if (asc_dvc->bus_type == ASC_IS_PCI) {
12488            AscSetExtraControl(iop_base, (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
12489     }
12490
12491     asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
12492     if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
12493         AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
12494         asc_dvc->bus_type = ASC_IS_ISAPNP;
12495     }
12496 #ifdef CONFIG_ISA
12497     if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
12498         asc_dvc->cfg->isa_dma_channel = (uchar) AscGetIsaDmaChannel(iop_base);
12499     }
12500 #endif /* CONFIG_ISA */
12501     for (i = 0; i <= ASC_MAX_TID; i++) {
12502         asc_dvc->cur_dvc_qng[i] = 0;
12503         asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
12504         asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *) 0L;
12505         asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *) 0L;
12506         asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
12507     }
12508     return (warn_code);
12509 }
12510
12511 ASC_INITFUNC(
12512 STATIC ushort,
12513 AscInitFromEEP(
12514                   ASC_DVC_VAR *asc_dvc
12515 )
12516 )
12517 {
12518     ASCEEP_CONFIG       eep_config_buf;
12519     ASCEEP_CONFIG       *eep_config;
12520     PortAddr            iop_base;
12521     ushort              chksum;
12522     ushort              warn_code;
12523     ushort              cfg_msw, cfg_lsw;
12524     int                 i;
12525     int                 write_eep = 0;
12526
12527     iop_base = asc_dvc->iop_base;
12528     warn_code = 0;
12529     AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
12530     AscStopQueueExe(iop_base);
12531     if ((AscStopChip(iop_base) == FALSE) ||
12532         (AscGetChipScsiCtrl(iop_base) != 0)) {
12533         asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
12534         AscResetChipAndScsiBus(asc_dvc);
12535         DvcSleepMilliSecond((ASC_DCNT)
12536             ((ushort) asc_dvc->scsi_reset_wait * 1000));
12537     }
12538     if (AscIsChipHalted(iop_base) == FALSE) {
12539         asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
12540         return (warn_code);
12541     }
12542     AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
12543     if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
12544         asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
12545         return (warn_code);
12546     }
12547     eep_config = (ASCEEP_CONFIG *) &eep_config_buf;
12548     cfg_msw = AscGetChipCfgMsw(iop_base);
12549     cfg_lsw = AscGetChipCfgLsw(iop_base);
12550     if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12551         cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
12552         warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12553         AscSetChipCfgMsw(iop_base, cfg_msw);
12554     }
12555     chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
12556     ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
12557     if (chksum == 0) {
12558         chksum = 0xaa55;
12559     }
12560     if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12561         warn_code |= ASC_WARN_AUTO_CONFIG;
12562         if (asc_dvc->cfg->chip_version == 3) {
12563             if (eep_config->cfg_lsw != cfg_lsw) {
12564                 warn_code |= ASC_WARN_EEPROM_RECOVER;
12565                 eep_config->cfg_lsw = AscGetChipCfgLsw(iop_base);
12566             }
12567             if (eep_config->cfg_msw != cfg_msw) {
12568                 warn_code |= ASC_WARN_EEPROM_RECOVER;
12569                 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
12570             }
12571         }
12572     }
12573     eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
12574     eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
12575     ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
12576         eep_config->chksum);
12577     if (chksum != eep_config->chksum) {
12578             if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
12579                     ASC_CHIP_VER_PCI_ULTRA_3050 )
12580             {
12581                 ASC_DBG(1,
12582 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
12583                 eep_config->init_sdtr = 0xFF;
12584                 eep_config->disc_enable = 0xFF;
12585                 eep_config->start_motor = 0xFF;
12586                 eep_config->use_cmd_qng = 0;
12587                 eep_config->max_total_qng = 0xF0;
12588                 eep_config->max_tag_qng = 0x20;
12589                 eep_config->cntl = 0xBFFF;
12590                 ASC_EEP_SET_CHIP_ID(eep_config, 7);
12591                 eep_config->no_scam = 0;
12592                 eep_config->adapter_info[0] = 0;
12593                 eep_config->adapter_info[1] = 0;
12594                 eep_config->adapter_info[2] = 0;
12595                 eep_config->adapter_info[3] = 0;
12596                 eep_config->adapter_info[4] = 0;
12597                 /* Indicate EEPROM-less board. */
12598                 eep_config->adapter_info[5] = 0xBB;
12599             } else {
12600                 ASC_PRINT(
12601 "AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
12602                 write_eep = 1;
12603                 warn_code |= ASC_WARN_EEPROM_CHKSUM;
12604             }
12605     }
12606     asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
12607     asc_dvc->cfg->disc_enable = eep_config->disc_enable;
12608     asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
12609     asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
12610     asc_dvc->start_motor = eep_config->start_motor;
12611     asc_dvc->dvc_cntl = eep_config->cntl;
12612     asc_dvc->no_scam = eep_config->no_scam;
12613     asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
12614     asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
12615     asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
12616     asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
12617     asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
12618     asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
12619     if (!AscTestExternalLram(asc_dvc)) {
12620         if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA)) {
12621             eep_config->max_total_qng = ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
12622             eep_config->max_tag_qng = ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
12623         } else {
12624             eep_config->cfg_msw |= 0x0800;
12625             cfg_msw |= 0x0800;
12626             AscSetChipCfgMsw(iop_base, cfg_msw);
12627             eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
12628             eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
12629         }
12630     } else {
12631     }
12632     if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
12633         eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
12634     }
12635     if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
12636         eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
12637     }
12638     if (eep_config->max_tag_qng > eep_config->max_total_qng) {
12639         eep_config->max_tag_qng = eep_config->max_total_qng;
12640     }
12641     if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
12642         eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
12643     }
12644     asc_dvc->max_total_qng = eep_config->max_total_qng;
12645     if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
12646         eep_config->use_cmd_qng) {
12647         eep_config->disc_enable = eep_config->use_cmd_qng;
12648         warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12649     }
12650     if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
12651         asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
12652     }
12653     ASC_EEP_SET_CHIP_ID(eep_config, ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
12654     asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
12655     if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
12656         !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
12657         asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
12658     }
12659
12660     for (i = 0; i <= ASC_MAX_TID; i++) {
12661         asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
12662         asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
12663         asc_dvc->cfg->sdtr_period_offset[i] =
12664             (uchar) (ASC_DEF_SDTR_OFFSET |
12665                      (asc_dvc->host_init_sdtr_index << 4));
12666     }
12667     eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
12668     if (write_eep) {
12669         if ((i = AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type)) !=
12670              0) {
12671                 ASC_PRINT1(
12672 "AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n", i);
12673         } else {
12674                 ASC_PRINT("AscInitFromEEP: Succesfully re-wrote EEPROM.");
12675         }
12676     }
12677     return (warn_code);
12678 }
12679
12680 STATIC ushort
12681 AscInitMicroCodeVar(
12682                        ASC_DVC_VAR *asc_dvc
12683 )
12684 {
12685     int                 i;
12686     ushort              warn_code;
12687     PortAddr            iop_base;
12688     ASC_PADDR           phy_addr;
12689     ASC_DCNT            phy_size;
12690
12691     iop_base = asc_dvc->iop_base;
12692     warn_code = 0;
12693     for (i = 0; i <= ASC_MAX_TID; i++) {
12694         AscPutMCodeInitSDTRAtID(iop_base, i,
12695                                 asc_dvc->cfg->sdtr_period_offset[i]
12696 );
12697     }
12698
12699     AscInitQLinkVar(asc_dvc);
12700     AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
12701                      asc_dvc->cfg->disc_enable);
12702     AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
12703                      ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
12704
12705     /* Align overrun buffer on an 8 byte boundary. */
12706     phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
12707     phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
12708     AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
12709         (uchar *) &phy_addr, 1);
12710     phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
12711     AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
12712         (uchar *) &phy_size, 1);
12713
12714     asc_dvc->cfg->mcode_date =
12715         AscReadLramWord(iop_base, (ushort) ASCV_MC_DATE_W);
12716     asc_dvc->cfg->mcode_version =
12717         AscReadLramWord(iop_base, (ushort) ASCV_MC_VER_W);
12718
12719     AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
12720     if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
12721         asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
12722         return (warn_code);
12723     }
12724     if (AscStartChip(iop_base) != 1) {
12725         asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
12726         return (warn_code);
12727     }
12728
12729     return (warn_code);
12730 }
12731
12732 ASC_INITFUNC(
12733 STATIC int,
12734 AscTestExternalLram(
12735                        ASC_DVC_VAR *asc_dvc
12736 )
12737 )
12738 {
12739     PortAddr            iop_base;
12740     ushort              q_addr;
12741     ushort              saved_word;
12742     int                 sta;
12743
12744     iop_base = asc_dvc->iop_base;
12745     sta = 0;
12746     q_addr = ASC_QNO_TO_QADDR(241);
12747     saved_word = AscReadLramWord(iop_base, q_addr);
12748     AscSetChipLramAddr(iop_base, q_addr);
12749     AscSetChipLramData(iop_base, 0x55AA);
12750     DvcSleepMilliSecond(10);
12751     AscSetChipLramAddr(iop_base, q_addr);
12752     if (AscGetChipLramData(iop_base) == 0x55AA) {
12753         sta = 1;
12754         AscWriteLramWord(iop_base, q_addr, saved_word);
12755     }
12756     return (sta);
12757 }
12758
12759 ASC_INITFUNC(
12760 STATIC int,
12761 AscWriteEEPCmdReg(
12762                      PortAddr iop_base,
12763                      uchar cmd_reg
12764 )
12765 )
12766 {
12767     uchar               read_back;
12768     int                 retry;
12769
12770     retry = 0;
12771     while (TRUE) {
12772         AscSetChipEEPCmd(iop_base, cmd_reg);
12773         DvcSleepMilliSecond(1);
12774         read_back = AscGetChipEEPCmd(iop_base);
12775         if (read_back == cmd_reg) {
12776             return (1);
12777         }
12778         if (retry++ > ASC_EEP_MAX_RETRY) {
12779             return (0);
12780         }
12781     }
12782 }
12783
12784 ASC_INITFUNC(
12785 STATIC int,
12786 AscWriteEEPDataReg(
12787                       PortAddr iop_base,
12788                       ushort data_reg
12789 )
12790 )
12791 {
12792     ushort              read_back;
12793     int                 retry;
12794
12795     retry = 0;
12796     while (TRUE) {
12797         AscSetChipEEPData(iop_base, data_reg);
12798         DvcSleepMilliSecond(1);
12799         read_back = AscGetChipEEPData(iop_base);
12800         if (read_back == data_reg) {
12801             return (1);
12802         }
12803         if (retry++ > ASC_EEP_MAX_RETRY) {
12804             return (0);
12805         }
12806     }
12807 }
12808
12809 ASC_INITFUNC(
12810 STATIC void,
12811 AscWaitEEPRead(
12812                   void
12813 )
12814 )
12815 {
12816     DvcSleepMilliSecond(1);
12817     return;
12818 }
12819
12820 ASC_INITFUNC(
12821 STATIC void,
12822 AscWaitEEPWrite(
12823                    void
12824 )
12825 )
12826 {
12827     DvcSleepMilliSecond(20);
12828     return;
12829 }
12830
12831 ASC_INITFUNC(
12832 STATIC ushort,
12833 AscReadEEPWord(
12834                   PortAddr iop_base,
12835                   uchar addr
12836 )
12837 )
12838 {
12839     ushort              read_wval;
12840     uchar               cmd_reg;
12841
12842     AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
12843     AscWaitEEPRead();
12844     cmd_reg = addr | ASC_EEP_CMD_READ;
12845     AscWriteEEPCmdReg(iop_base, cmd_reg);
12846     AscWaitEEPRead();
12847     read_wval = AscGetChipEEPData(iop_base);
12848     AscWaitEEPRead();
12849     return (read_wval);
12850 }
12851
12852 ASC_INITFUNC(
12853 STATIC ushort,
12854 AscWriteEEPWord(
12855                    PortAddr iop_base,
12856                    uchar addr,
12857                    ushort word_val
12858 )
12859 )
12860 {
12861     ushort              read_wval;
12862
12863     read_wval = AscReadEEPWord(iop_base, addr);
12864     if (read_wval != word_val) {
12865         AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
12866         AscWaitEEPRead();
12867         AscWriteEEPDataReg(iop_base, word_val);
12868         AscWaitEEPRead();
12869         AscWriteEEPCmdReg(iop_base,
12870                           (uchar) ((uchar) ASC_EEP_CMD_WRITE | addr));
12871         AscWaitEEPWrite();
12872         AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
12873         AscWaitEEPRead();
12874         return (AscReadEEPWord(iop_base, addr));
12875     }
12876     return (read_wval);
12877 }
12878
12879 ASC_INITFUNC(
12880 STATIC ushort,
12881 AscGetEEPConfig(
12882                    PortAddr iop_base,
12883                    ASCEEP_CONFIG * cfg_buf, ushort bus_type
12884 )
12885 )
12886 {
12887     ushort              wval;
12888     ushort              sum;
12889     ushort              *wbuf;
12890     int                 cfg_beg;
12891     int                 cfg_end;
12892     int                 uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
12893     int                 s_addr;
12894
12895     wbuf = (ushort *) cfg_buf;
12896     sum = 0;
12897     /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
12898     for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12899         *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
12900         sum += *wbuf;
12901     }
12902     if (bus_type & ASC_IS_VL) {
12903         cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
12904         cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
12905     } else {
12906         cfg_beg = ASC_EEP_DVC_CFG_BEG;
12907         cfg_end = ASC_EEP_MAX_DVC_ADDR;
12908     }
12909     for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
12910         wval = AscReadEEPWord( iop_base, ( uchar )s_addr ) ;
12911         if (s_addr <= uchar_end_in_config) {
12912             /*
12913              * Swap all char fields - must unswap bytes already swapped
12914              * by AscReadEEPWord().
12915              */
12916             *wbuf = le16_to_cpu(wval);
12917         } else {
12918             /* Don't swap word field at the end - cntl field. */
12919             *wbuf = wval;
12920         }
12921         sum += wval; /* Checksum treats all EEPROM data as words. */
12922     }
12923     /*
12924      * Read the checksum word which will be compared against 'sum'
12925      * by the caller. Word field already swapped.
12926      */
12927     *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
12928     return (sum);
12929 }
12930
12931 ASC_INITFUNC(
12932 STATIC int,
12933 AscSetEEPConfigOnce(
12934                        PortAddr iop_base,
12935                        ASCEEP_CONFIG * cfg_buf, ushort bus_type
12936 )
12937 )
12938 {
12939     int                 n_error;
12940     ushort              *wbuf;
12941     ushort              word;
12942     ushort              sum;
12943     int                 s_addr;
12944     int                 cfg_beg;
12945     int                 cfg_end;
12946     int                 uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
12947
12948
12949     wbuf = (ushort *) cfg_buf;
12950     n_error = 0;
12951     sum = 0;
12952     /* Write two config words; AscWriteEEPWord() will swap bytes. */
12953     for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12954         sum += *wbuf;
12955         if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
12956             n_error++;
12957         }
12958     }
12959     if (bus_type & ASC_IS_VL) {
12960         cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
12961         cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
12962     } else {
12963         cfg_beg = ASC_EEP_DVC_CFG_BEG;
12964         cfg_end = ASC_EEP_MAX_DVC_ADDR;
12965     }
12966     for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
12967         if (s_addr <= uchar_end_in_config) {
12968             /*
12969              * This is a char field. Swap char fields before they are
12970              * swapped again by AscWriteEEPWord().
12971              */
12972             word = cpu_to_le16(*wbuf);
12973             if (word != AscWriteEEPWord( iop_base, (uchar) s_addr, word)) {
12974                 n_error++;
12975             }
12976         } else {
12977             /* Don't swap word field at the end - cntl field. */
12978             if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
12979                 n_error++;
12980             }
12981         }
12982         sum += *wbuf; /* Checksum calculated from word values. */
12983     }
12984     /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
12985     *wbuf = sum;
12986     if (sum != AscWriteEEPWord(iop_base, (uchar) s_addr, sum)) {
12987         n_error++;
12988     }
12989
12990     /* Read EEPROM back again. */
12991     wbuf = (ushort *) cfg_buf;
12992     /*
12993      * Read two config words; Byte-swapping done by AscReadEEPWord().
12994      */
12995     for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12996         if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
12997             n_error++;
12998         }
12999     }
13000     if (bus_type & ASC_IS_VL) {
13001         cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
13002         cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
13003     } else {
13004         cfg_beg = ASC_EEP_DVC_CFG_BEG;
13005         cfg_end = ASC_EEP_MAX_DVC_ADDR;
13006     }
13007     for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
13008         if (s_addr <= uchar_end_in_config) {
13009             /*
13010              * Swap all char fields. Must unswap bytes already swapped
13011              * by AscReadEEPWord().
13012              */
13013             word = le16_to_cpu(AscReadEEPWord(iop_base, (uchar) s_addr));
13014         } else {
13015             /* Don't swap word field at the end - cntl field. */
13016             word = AscReadEEPWord(iop_base, (uchar) s_addr);
13017         }
13018         if (*wbuf != word) {
13019             n_error++;
13020         }
13021     }
13022     /* Read checksum; Byte swapping not needed. */
13023     if (AscReadEEPWord(iop_base, (uchar) s_addr) != sum) {
13024         n_error++;
13025     }
13026     return (n_error);
13027 }
13028
13029 ASC_INITFUNC(
13030 STATIC int,
13031 AscSetEEPConfig(
13032                    PortAddr iop_base,
13033                    ASCEEP_CONFIG * cfg_buf, ushort bus_type
13034 )
13035 )
13036 {
13037     int            retry;
13038     int            n_error;
13039
13040     retry = 0;
13041     while (TRUE) {
13042         if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
13043                                            bus_type)) == 0) {
13044             break;
13045         }
13046         if (++retry > ASC_EEP_MAX_RETRY) {
13047             break;
13048         }
13049     }
13050     return (n_error);
13051 }
13052
13053 STATIC void
13054 AscAsyncFix(
13055                ASC_DVC_VAR *asc_dvc,
13056                uchar tid_no,
13057                ASC_SCSI_INQUIRY *inq)
13058 {
13059     uchar                       dvc_type;
13060     ASC_SCSI_BIT_ID_TYPE        tid_bits;
13061
13062     dvc_type = ASC_INQ_DVC_TYPE(inq);
13063     tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
13064
13065     if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN)
13066     {
13067         if (!(asc_dvc->init_sdtr & tid_bits))
13068         {
13069             if ((dvc_type == SCSI_TYPE_CDROM) &&
13070                 (AscCompareString((uchar *) inq->vendor_id,
13071                     (uchar *) "HP ", 3) == 0))
13072             {
13073                 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
13074             }
13075             asc_dvc->pci_fix_asyn_xfer |= tid_bits;
13076             if ((dvc_type == SCSI_TYPE_PROC) ||
13077                 (dvc_type == SCSI_TYPE_SCANNER) ||
13078                 (dvc_type == SCSI_TYPE_CDROM) ||
13079                 (dvc_type == SCSI_TYPE_SASD))
13080             {
13081                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
13082             }
13083
13084             if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
13085             {
13086                 AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no,
13087                     ASYN_SDTR_DATA_FIX_PCI_REV_AB);
13088             }
13089         }
13090     }
13091     return;
13092 }
13093
13094 STATIC int
13095 AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
13096 {
13097     if ((inq->add_len >= 32) &&
13098         (AscCompareString((uchar *) inq->vendor_id,
13099             (uchar *) "QUANTUM XP34301", 15) == 0) &&
13100         (AscCompareString((uchar *) inq->product_rev_level,
13101             (uchar *) "1071", 4) == 0))
13102     {
13103         return 0;
13104     }
13105     return 1;
13106 }
13107
13108 STATIC void
13109 AscInquiryHandling(ASC_DVC_VAR *asc_dvc,
13110                    uchar tid_no, ASC_SCSI_INQUIRY *inq)
13111 {
13112     ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
13113     ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
13114
13115     orig_init_sdtr = asc_dvc->init_sdtr;
13116     orig_use_tagged_qng = asc_dvc->use_tagged_qng;
13117
13118     asc_dvc->init_sdtr &= ~tid_bit;
13119     asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
13120     asc_dvc->use_tagged_qng &= ~tid_bit;
13121
13122     if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) {
13123         if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) {
13124             asc_dvc->init_sdtr |= tid_bit;
13125         }
13126         if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) &&
13127              ASC_INQ_CMD_QUEUE(inq)) {
13128             if (AscTagQueuingSafe(inq)) {
13129                 asc_dvc->use_tagged_qng |= tid_bit;
13130                 asc_dvc->cfg->can_tagged_qng |= tid_bit;
13131             }
13132         }
13133     }
13134     if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
13135         AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
13136                          asc_dvc->cfg->disc_enable);
13137         AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
13138                          asc_dvc->use_tagged_qng);
13139         AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
13140                          asc_dvc->cfg->can_tagged_qng);
13141
13142         asc_dvc->max_dvc_qng[tid_no] =
13143           asc_dvc->cfg->max_tag_qng[tid_no];
13144         AscWriteLramByte(asc_dvc->iop_base,
13145                          (ushort) (ASCV_MAX_DVC_QNG_BEG + tid_no),
13146                          asc_dvc->max_dvc_qng[tid_no]);
13147     }
13148     if (orig_init_sdtr != asc_dvc->init_sdtr) {
13149         AscAsyncFix(asc_dvc, tid_no, inq);
13150     }
13151     return;
13152 }
13153
13154 STATIC int
13155 AscCompareString(
13156                     uchar *str1,
13157                     uchar *str2,
13158                     int len
13159 )
13160 {
13161     int                 i;
13162     int                 diff;
13163
13164     for (i = 0; i < len; i++) {
13165         diff = (int) (str1[i] - str2[i]);
13166         if (diff != 0)
13167             return (diff);
13168     }
13169     return (0);
13170 }
13171
13172 STATIC uchar
13173 AscReadLramByte(
13174                    PortAddr iop_base,
13175                    ushort addr
13176 )
13177 {
13178     uchar               byte_data;
13179     ushort              word_data;
13180
13181     if (isodd_word(addr)) {
13182         AscSetChipLramAddr(iop_base, addr - 1);
13183         word_data = AscGetChipLramData(iop_base);
13184         byte_data = (uchar) ((word_data >> 8) & 0xFF);
13185     } else {
13186         AscSetChipLramAddr(iop_base, addr);
13187         word_data = AscGetChipLramData(iop_base);
13188         byte_data = (uchar) (word_data & 0xFF);
13189     }
13190     return (byte_data);
13191 }
13192 STATIC ushort
13193 AscReadLramWord(
13194                    PortAddr iop_base,
13195                    ushort addr
13196 )
13197 {
13198     ushort              word_data;
13199
13200     AscSetChipLramAddr(iop_base, addr);
13201     word_data = AscGetChipLramData(iop_base);
13202     return (word_data);
13203 }
13204
13205 #if CC_VERY_LONG_SG_LIST
13206 STATIC ASC_DCNT
13207 AscReadLramDWord(
13208                     PortAddr iop_base,
13209                     ushort addr
13210 )
13211 {
13212     ushort              val_low, val_high;
13213     ASC_DCNT            dword_data;
13214
13215     AscSetChipLramAddr(iop_base, addr);
13216     val_low = AscGetChipLramData(iop_base);
13217     val_high = AscGetChipLramData(iop_base);
13218     dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
13219     return (dword_data);
13220 }
13221 #endif /* CC_VERY_LONG_SG_LIST */
13222
13223 STATIC void
13224 AscWriteLramWord(
13225                     PortAddr iop_base,
13226                     ushort addr,
13227                     ushort word_val
13228 )
13229 {
13230     AscSetChipLramAddr(iop_base, addr);
13231     AscSetChipLramData(iop_base, word_val);
13232     return;
13233 }
13234
13235 STATIC void
13236 AscWriteLramByte(
13237                     PortAddr iop_base,
13238                     ushort addr,
13239                     uchar byte_val
13240 )
13241 {
13242     ushort              word_data;
13243
13244     if (isodd_word(addr)) {
13245         addr--;
13246         word_data = AscReadLramWord(iop_base, addr);
13247         word_data &= 0x00FF;
13248         word_data |= (((ushort) byte_val << 8) & 0xFF00);
13249     } else {
13250         word_data = AscReadLramWord(iop_base, addr);
13251         word_data &= 0xFF00;
13252         word_data |= ((ushort) byte_val & 0x00FF);
13253     }
13254     AscWriteLramWord(iop_base, addr, word_data);
13255     return;
13256 }
13257
13258 /*
13259  * Copy 2 bytes to LRAM.
13260  *
13261  * The source data is assumed to be in little-endian order in memory
13262  * and is maintained in little-endian order when written to LRAM.
13263  */
13264 STATIC void
13265 AscMemWordCopyPtrToLram(
13266                         PortAddr iop_base,
13267                         ushort s_addr,
13268                         uchar *s_buffer,
13269                         int words
13270 )
13271 {
13272     int    i;
13273
13274     AscSetChipLramAddr(iop_base, s_addr);
13275     for (i = 0; i < 2 * words; i += 2) {
13276         /*
13277          * On a little-endian system the second argument below
13278          * produces a little-endian ushort which is written to
13279          * LRAM in little-endian order. On a big-endian system
13280          * the second argument produces a big-endian ushort which
13281          * is "transparently" byte-swapped by outpw() and written
13282          * in little-endian order to LRAM.
13283          */
13284         outpw(iop_base + IOP_RAM_DATA,
13285             ((ushort) s_buffer[i + 1] << 8) | s_buffer[i]);
13286     }
13287     return;
13288 }
13289
13290 /*
13291  * Copy 4 bytes to LRAM.
13292  *
13293  * The source data is assumed to be in little-endian order in memory
13294  * and is maintained in little-endian order when writen to LRAM.
13295  */
13296 STATIC void
13297 AscMemDWordCopyPtrToLram(
13298                          PortAddr iop_base,
13299                          ushort s_addr,
13300                          uchar *s_buffer,
13301                          int dwords
13302 )
13303 {
13304     int       i;
13305
13306     AscSetChipLramAddr(iop_base, s_addr);
13307     for (i = 0; i < 4 * dwords; i += 4) {
13308         outpw(iop_base + IOP_RAM_DATA,
13309             ((ushort) s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
13310         outpw(iop_base + IOP_RAM_DATA,
13311             ((ushort) s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
13312     }
13313     return;
13314 }
13315
13316 /*
13317  * Copy 2 bytes from LRAM.
13318  *
13319  * The source data is assumed to be in little-endian order in LRAM
13320  * and is maintained in little-endian order when written to memory.
13321  */
13322 STATIC void
13323 AscMemWordCopyPtrFromLram(
13324                           PortAddr iop_base,
13325                           ushort s_addr,
13326                           uchar *d_buffer,
13327                           int words
13328 )
13329 {
13330     int i;
13331     ushort word;
13332
13333     AscSetChipLramAddr(iop_base, s_addr);
13334     for (i = 0; i < 2 * words; i += 2) {
13335         word = inpw(iop_base + IOP_RAM_DATA);
13336         d_buffer[i] = word & 0xff;
13337         d_buffer[i + 1] = (word >> 8) & 0xff;
13338     }
13339     return;
13340 }
13341
13342 STATIC ASC_DCNT
13343 AscMemSumLramWord(
13344                      PortAddr iop_base,
13345                      ushort s_addr,
13346                      int words
13347 )
13348 {
13349     ASC_DCNT         sum;
13350     int              i;
13351
13352     sum = 0L;
13353     for (i = 0; i < words; i++, s_addr += 2) {
13354         sum += AscReadLramWord(iop_base, s_addr);
13355     }
13356     return (sum);
13357 }
13358
13359 STATIC void
13360 AscMemWordSetLram(
13361                      PortAddr iop_base,
13362                      ushort s_addr,
13363                      ushort set_wval,
13364                      int words
13365 )
13366 {
13367     int             i;
13368
13369     AscSetChipLramAddr(iop_base, s_addr);
13370     for (i = 0; i < words; i++) {
13371         AscSetChipLramData(iop_base, set_wval);
13372     }
13373     return;
13374 }
13375
13376
13377 /*
13378  * --- Adv Library Functions
13379  */
13380
13381 /* a_mcode.h */
13382
13383 /* Microcode buffer is kept after initialization for error recovery. */
13384 STATIC unsigned char _adv_asc3550_buf[] = {
13385   0x00,  0x00,  0x00,  0xf2,  0x00,  0xf0,  0x00,  0x16,  0x18,  0xe4,  0x00,  0xfc,  0x01,  0x00,  0x48,  0xe4,
13386   0xbe,  0x18,  0x18,  0x80,  0x03,  0xf6,  0x02,  0x00,  0x00,  0xfa,  0xff,  0xff,  0x28,  0x0e,  0x9e,  0xe7,
13387   0xff,  0x00,  0x82,  0xe7,  0x00,  0xea,  0x00,  0xf6,  0x01,  0xe6,  0x09,  0xe7,  0x55,  0xf0,  0x01,  0xf6,
13388   0x01,  0xfa,  0x08,  0x00,  0x03,  0x00,  0x04,  0x00,  0x18,  0xf4,  0x10,  0x00,  0x00,  0xec,  0x85,  0xf0,
13389   0xbc,  0x00,  0xd5,  0xf0,  0x8e,  0x0c,  0x38,  0x54,  0x00,  0xe6,  0x1e,  0xf0,  0x86,  0xf0,  0xb4,  0x00,
13390   0x98,  0x57,  0xd0,  0x01,  0x0c,  0x1c,  0x3e,  0x1c,  0x0c,  0x00,  0xbb,  0x00,  0xaa,  0x18,  0x02,  0x80,
13391   0x32,  0xf0,  0x01,  0xfc,  0x88,  0x0c,  0xc6,  0x12,  0x02,  0x13,  0x18,  0x40,  0x00,  0x57,  0x01,  0xea,
13392   0x3c,  0x00,  0x6c,  0x01,  0x6e,  0x01,  0x04,  0x12,  0x3e,  0x57,  0x00,  0x80,  0x03,  0xe6,  0xb6,  0x00,
13393   0xc0,  0x00,  0x01,  0x01,  0x3e,  0x01,  0xda,  0x0f,  0x22,  0x10,  0x08,  0x12,  0x02,  0x4a,  0xb9,  0x54,
13394   0x03,  0x58,  0x1b,  0x80,  0x30,  0xe4,  0x4b,  0xe4,  0x20,  0x00,  0x32,  0x00,  0x3e,  0x00,  0x80,  0x00,
13395   0x24,  0x01,  0x3c,  0x01,  0x68,  0x01,  0x6a,  0x01,  0x70,  0x01,  0x72,  0x01,  0x74,  0x01,  0x76,  0x01,
13396   0x78,  0x01,  0x62,  0x0a,  0x92,  0x0c,  0x2c,  0x10,  0x2e,  0x10,  0x06,  0x13,  0x4c,  0x1c,  0xbb,  0x55,
13397   0x3c,  0x56,  0x04,  0x80,  0x4a,  0xe4,  0x02,  0xee,  0x5b,  0xf0,  0xb1,  0xf0,  0x03,  0xf7,  0x06,  0xf7,
13398   0x03,  0xfc,  0x0f,  0x00,  0x40,  0x00,  0xbe,  0x00,  0x00,  0x01,  0xb0,  0x08,  0x30,  0x13,  0x64,  0x15,
13399   0x32,  0x1c,  0x38,  0x1c,  0x4e,  0x1c,  0x10,  0x44,  0x02,  0x48,  0x00,  0x4c,  0x04,  0xea,  0x5d,  0xf0,
13400   0x04,  0xf6,  0x02,  0xfc,  0x05,  0x00,  0x34,  0x00,  0x36,  0x00,  0x98,  0x00,  0xcc,  0x00,  0x20,  0x01,
13401   0x4e,  0x01,  0x4e,  0x0b,  0x1e,  0x0e,  0x0c,  0x10,  0x0a,  0x12,  0x04,  0x13,  0x40,  0x13,  0x30,  0x1c,
13402   0x00,  0x4e,  0xbd,  0x56,  0x06,  0x83,  0x00,  0xdc,  0x05,  0xf0,  0x09,  0xf0,  0x59,  0xf0,  0xa7,  0xf0,
13403   0xb8,  0xf0,  0x0e,  0xf7,  0x06,  0x00,  0x19,  0x00,  0x33,  0x00,  0x9b,  0x00,  0xa4,  0x00,  0xb5,  0x00,
13404   0xba,  0x00,  0xd0,  0x00,  0xe1,  0x00,  0xe7,  0x00,  0xde,  0x03,  0x56,  0x0a,  0x14,  0x0e,  0x02,  0x10,
13405   0x04,  0x10,  0x0a,  0x10,  0x36,  0x10,  0x0a,  0x13,  0x12,  0x13,  0x52,  0x13,  0x10,  0x15,  0x14,  0x15,
13406   0xac,  0x16,  0x20,  0x1c,  0x34,  0x1c,  0x36,  0x1c,  0x08,  0x44,  0x38,  0x44,  0x91,  0x44,  0x0a,  0x45,
13407   0x48,  0x46,  0x01,  0x48,  0x68,  0x54,  0x83,  0x55,  0xb0,  0x57,  0x01,  0x58,  0x83,  0x59,  0x05,  0xe6,
13408   0x0b,  0xf0,  0x0c,  0xf0,  0x5c,  0xf0,  0x4b,  0xf4,  0x04,  0xf8,  0x05,  0xf8,  0x02,  0xfa,  0x03,  0xfa,
13409   0x04,  0xfc,  0x05,  0xfc,  0x07,  0x00,  0x0a,  0x00,  0x0d,  0x00,  0x1c,  0x00,  0x9e,  0x00,  0xa8,  0x00,
13410   0xaa,  0x00,  0xb9,  0x00,  0xe0,  0x00,  0x22,  0x01,  0x26,  0x01,  0x79,  0x01,  0x7a,  0x01,  0xc0,  0x01,
13411   0xc2,  0x01,  0x7c,  0x02,  0x5a,  0x03,  0xea,  0x04,  0xe8,  0x07,  0x68,  0x08,  0x69,  0x08,  0xba,  0x08,
13412   0xe9,  0x09,  0x06,  0x0b,  0x3a,  0x0e,  0x00,  0x10,  0x1a,  0x10,  0xed,  0x10,  0xf1,  0x10,  0x06,  0x12,
13413   0x0c,  0x13,  0x16,  0x13,  0x1e,  0x13,  0x82,  0x13,  0x42,  0x14,  0xd6,  0x14,  0x8a,  0x15,  0xc6,  0x17,
13414   0xd2,  0x17,  0x6b,  0x18,  0x12,  0x1c,  0x46,  0x1c,  0x9c,  0x32,  0x00,  0x40,  0x0e,  0x47,  0x48,  0x47,
13415   0x41,  0x48,  0x89,  0x48,  0x80,  0x4c,  0x00,  0x54,  0x44,  0x55,  0xe5,  0x55,  0x14,  0x56,  0x77,  0x57,
13416   0xbf,  0x57,  0x40,  0x5c,  0x06,  0x80,  0x08,  0x90,  0x03,  0xa1,  0xfe,  0x9c,  0xf0,  0x29,  0x02,  0xfe,
13417   0xb8,  0x0c,  0xff,  0x10,  0x00,  0x00,  0xd0,  0xfe,  0xcc,  0x18,  0x00,  0xcf,  0xfe,  0x80,  0x01,  0xff,
13418   0x03,  0x00,  0x00,  0xfe,  0x93,  0x15,  0xfe,  0x0f,  0x05,  0xff,  0x38,  0x00,  0x00,  0xfe,  0x57,  0x24,
13419   0x00,  0xfe,  0x48,  0x00,  0x4f,  0xff,  0x04,  0x00,  0x00,  0x10,  0xff,  0x09,  0x00,  0x00,  0xff,  0x08,
13420   0x01,  0x01,  0xff,  0x08,  0xff,  0xff,  0xff,  0x27,  0x00,  0x00,  0xff,  0x10,  0xff,  0xff,  0xff,  0x0f,
13421   0x00,  0x00,  0xfe,  0x78,  0x56,  0xfe,  0x34,  0x12,  0xff,  0x21,  0x00,  0x00,  0xfe,  0x04,  0xf7,  0xcf,
13422   0x2a,  0x67,  0x0b,  0x01,  0xfe,  0xce,  0x0e,  0xfe,  0x04,  0xf7,  0xcf,  0x67,  0x0b,  0x3c,  0x2a,  0xfe,
13423   0x3d,  0xf0,  0xfe,  0x02,  0x02,  0xfe,  0x20,  0xf0,  0x9c,  0xfe,  0x91,  0xf0,  0xfe,  0xf0,  0x01,  0xfe,
13424   0x90,  0xf0,  0xfe,  0xf0,  0x01,  0xfe,  0x8f,  0xf0,  0x9c,  0x05,  0x51,  0x3b,  0x02,  0xfe,  0xd4,  0x0c,
13425   0x01,  0xfe,  0x44,  0x0d,  0xfe,  0xdd,  0x12,  0xfe,  0xfc,  0x10,  0xfe,  0x28,  0x1c,  0x05,  0xfe,  0xa6,
13426   0x00,  0xfe,  0xd3,  0x12,  0x47,  0x18,  0xfe,  0xa6,  0x00,  0xb5,  0xfe,  0x48,  0xf0,  0xfe,  0x86,  0x02,
13427   0xfe,  0x49,  0xf0,  0xfe,  0xa0,  0x02,  0xfe,  0x4a,  0xf0,  0xfe,  0xbe,  0x02,  0xfe,  0x46,  0xf0,  0xfe,
13428   0x50,  0x02,  0xfe,  0x47,  0xf0,  0xfe,  0x56,  0x02,  0xfe,  0x43,  0xf0,  0xfe,  0x44,  0x02,  0xfe,  0x44,
13429   0xf0,  0xfe,  0x48,  0x02,  0xfe,  0x45,  0xf0,  0xfe,  0x4c,  0x02,  0x17,  0x0b,  0xa0,  0x17,  0x06,  0x18,
13430   0x96,  0x02,  0x29,  0xfe,  0x00,  0x1c,  0xde,  0xfe,  0x02,  0x1c,  0xdd,  0xfe,  0x1e,  0x1c,  0xfe,  0xe9,
13431   0x10,  0x01,  0xfe,  0x20,  0x17,  0xfe,  0xe7,  0x10,  0xfe,  0x06,  0xfc,  0xc7,  0x0a,  0x6b,  0x01,  0x9e,
13432   0x02,  0x29,  0x14,  0x4d,  0x37,  0x97,  0x01,  0xfe,  0x64,  0x0f,  0x0a,  0x6b,  0x01,  0x82,  0xfe,  0xbd,
13433   0x10,  0x0a,  0x6b,  0x01,  0x82,  0xfe,  0xad,  0x10,  0xfe,  0x16,  0x1c,  0xfe,  0x58,  0x1c,  0x17,  0x06,
13434   0x18,  0x96,  0x2a,  0x25,  0x29,  0xfe,  0x3d,  0xf0,  0xfe,  0x02,  0x02,  0x21,  0xfe,  0x94,  0x02,  0xfe,
13435   0x5a,  0x1c,  0xea,  0xfe,  0x14,  0x1c,  0x14,  0xfe,  0x30,  0x00,  0x37,  0x97,  0x01,  0xfe,  0x54,  0x0f,
13436   0x17,  0x06,  0x18,  0x96,  0x02,  0xd0,  0x1e,  0x20,  0x07,  0x10,  0x34,  0xfe,  0x69,  0x10,  0x17,  0x06,
13437   0x18,  0x96,  0xfe,  0x04,  0xec,  0x20,  0x46,  0x3d,  0x12,  0x20,  0xfe,  0x05,  0xf6,  0xc7,  0x01,  0xfe,
13438   0x52,  0x16,  0x09,  0x4a,  0x4c,  0x35,  0x11,  0x2d,  0x3c,  0x8a,  0x01,  0xe6,  0x02,  0x29,  0x0a,  0x40,
13439   0x01,  0x0e,  0x07,  0x00,  0x5d,  0x01,  0x6f,  0xfe,  0x18,  0x10,  0xfe,  0x41,  0x58,  0x0a,  0x99,  0x01,
13440   0x0e,  0xfe,  0xc8,  0x54,  0x64,  0xfe,  0x0c,  0x03,  0x01,  0xe6,  0x02,  0x29,  0x2a,  0x46,  0xfe,  0x02,
13441   0xe8,  0x27,  0xf8,  0xfe,  0x9e,  0x43,  0xf7,  0xfe,  0x27,  0xf0,  0xfe,  0xdc,  0x01,  0xfe,  0x07,  0x4b,
13442   0xfe,  0x20,  0xf0,  0x9c,  0xfe,  0x40,  0x1c,  0x25,  0xd2,  0xfe,  0x26,  0xf0,  0xfe,  0x56,  0x03,  0xfe,
13443   0xa0,  0xf0,  0xfe,  0x44,  0x03,  0xfe,  0x11,  0xf0,  0x9c,  0xfe,  0xef,  0x10,  0xfe,  0x9f,  0xf0,  0xfe,
13444   0x64,  0x03,  0xeb,  0x0f,  0xfe,  0x11,  0x00,  0x02,  0x5a,  0x2a,  0xfe,  0x48,  0x1c,  0xeb,  0x09,  0x04,
13445   0x1d,  0xfe,  0x18,  0x13,  0x23,  0x1e,  0x98,  0xac,  0x12,  0x98,  0x0a,  0x40,  0x01,  0x0e,  0xac,  0x75,
13446   0x01,  0xfe,  0xbc,  0x15,  0x11,  0xca,  0x25,  0xd2,  0xfe,  0x01,  0xf0,  0xd2,  0xfe,  0x82,  0xf0,  0xfe,
13447   0x92,  0x03,  0xec,  0x11,  0xfe,  0xe4,  0x00,  0x65,  0xfe,  0xa4,  0x03,  0x25,  0x32,  0x1f,  0xfe,  0xb4,
13448   0x03,  0x01,  0x43,  0xfe,  0x06,  0xf0,  0xfe,  0xc4,  0x03,  0x8d,  0x81,  0xfe,  0x0a,  0xf0,  0xfe,  0x7a,
13449   0x06,  0x02,  0x22,  0x05,  0x6b,  0x28,  0x16,  0xfe,  0xf6,  0x04,  0x14,  0x2c,  0x01,  0x33,  0x8f,  0xfe,
13450   0x66,  0x02,  0x02,  0xd1,  0xeb,  0x2a,  0x67,  0x1a,  0xfe,  0x67,  0x1b,  0xf8,  0xf7,  0xfe,  0x48,  0x1c,
13451   0x70,  0x01,  0x6e,  0x87,  0x0a,  0x40,  0x01,  0x0e,  0x07,  0x00,  0x16,  0xd3,  0x0a,  0xca,  0x01,  0x0e,
13452   0x74,  0x60,  0x59,  0x76,  0x27,  0x05,  0x6b,  0x28,  0xfe,  0x10,  0x12,  0x14,  0x2c,  0x01,  0x33,  0x8f,
13453   0xfe,  0x66,  0x02,  0x02,  0xd1,  0xbc,  0x7d,  0xbd,  0x7f,  0x25,  0x22,  0x65,  0xfe,  0x3c,  0x04,  0x1f,
13454   0xfe,  0x38,  0x04,  0x68,  0xfe,  0xa0,  0x00,  0xfe,  0x9b,  0x57,  0xfe,  0x4e,  0x12,  0x2b,  0xff,  0x02,
13455   0x00,  0x10,  0x01,  0x08,  0x1f,  0xfe,  0xe0,  0x04,  0x2b,  0x01,  0x08,  0x1f,  0x22,  0x30,  0x2e,  0xd5,
13456   0xfe,  0x4c,  0x44,  0xfe,  0x4c,  0x12,  0x60,  0xfe,  0x44,  0x48,  0x13,  0x2c,  0xfe,  0x4c,  0x54,  0x64,
13457   0xd3,  0x46,  0x76,  0x27,  0xfa,  0xef,  0xfe,  0x62,  0x13,  0x09,  0x04,  0x1d,  0xfe,  0x2a,  0x13,  0x2f,
13458   0x07,  0x7e,  0xa5,  0xfe,  0x20,  0x10,  0x13,  0x2c,  0xfe,  0x4c,  0x54,  0x64,  0xd3,  0xfa,  0xef,  0x86,
13459   0x09,  0x04,  0x1d,  0xfe,  0x08,  0x13,  0x2f,  0x07,  0x7e,  0x6e,  0x09,  0x04,  0x1d,  0xfe,  0x1c,  0x12,
13460   0x14,  0x92,  0x09,  0x04,  0x06,  0x3b,  0x14,  0xc4,  0x01,  0x33,  0x8f,  0xfe,  0x70,  0x0c,  0x02,  0x22,
13461   0x2b,  0x11,  0xfe,  0xe6,  0x00,  0xfe,  0x1c,  0x90,  0xf9,  0x03,  0x14,  0x92,  0x01,  0x33,  0x02,  0x29,
13462   0xfe,  0x42,  0x5b,  0x67,  0x1a,  0xfe,  0x46,  0x59,  0xf8,  0xf7,  0xfe,  0x87,  0x80,  0xfe,  0x31,  0xe4,
13463   0x4f,  0x09,  0x04,  0x0b,  0xfe,  0x78,  0x13,  0xfe,  0x20,  0x80,  0x07,  0x1a,  0xfe,  0x70,  0x12,  0x49,
13464   0x04,  0x06,  0xfe,  0x60,  0x13,  0x05,  0xfe,  0xa2,  0x00,  0x28,  0x16,  0xfe,  0x80,  0x05,  0xfe,  0x31,
13465   0xe4,  0x6a,  0x49,  0x04,  0x0b,  0xfe,  0x4a,  0x13,  0x05,  0xfe,  0xa0,  0x00,  0x28,  0xfe,  0x42,  0x12,
13466   0x5e,  0x01,  0x08,  0x25,  0x32,  0xf1,  0x01,  0x08,  0x26,  0xfe,  0x98,  0x05,  0x11,  0xfe,  0xe3,  0x00,
13467   0x23,  0x49,  0xfe,  0x4a,  0xf0,  0xfe,  0x6a,  0x05,  0xfe,  0x49,  0xf0,  0xfe,  0x64,  0x05,  0x83,  0x24,
13468   0xfe,  0x21,  0x00,  0xa1,  0x24,  0xfe,  0x22,  0x00,  0xa0,  0x24,  0x4c,  0xfe,  0x09,  0x48,  0x01,  0x08,
13469   0x26,  0xfe,  0x98,  0x05,  0xfe,  0xe2,  0x08,  0x49,  0x04,  0xc5,  0x3b,  0x01,  0x86,  0x24,  0x06,  0x12,
13470   0xcc,  0x37,  0xfe,  0x27,  0x01,  0x09,  0x04,  0x1d,  0xfe,  0x22,  0x12,  0x47,  0x01,  0xa7,  0x14,  0x92,
13471   0x09,  0x04,  0x06,  0x3b,  0x14,  0xc4,  0x01,  0x33,  0x8f,  0xfe,  0x70,  0x0c,  0x02,  0x22,  0x05,  0xfe,
13472   0x9c,  0x00,  0x28,  0xfe,  0x3e,  0x12,  0x05,  0x50,  0x28,  0xfe,  0x36,  0x13,  0x47,  0x01,  0xa7,  0x26,
13473   0xfe,  0x08,  0x06,  0x0a,  0x06,  0x49,  0x04,  0x19,  0xfe,  0x02,  0x12,  0x5f,  0x01,  0xfe,  0xaa,  0x14,
13474   0x1f,  0xfe,  0xfe,  0x05,  0x11,  0x9a,  0x01,  0x43,  0x11,  0xfe,  0xe5,  0x00,  0x05,  0x50,  0xb4,  0x0c,
13475   0x50,  0x05,  0xc6,  0x28,  0xfe,  0x62,  0x12,  0x05,  0x3f,  0x28,  0xfe,  0x5a,  0x13,  0x01,  0xfe,  0x14,
13476   0x18,  0x01,  0xfe,  0x66,  0x18,  0xfe,  0x43,  0x48,  0xb7,  0x19,  0x13,  0x6c,  0xff,  0x02,  0x00,  0x57,
13477   0x48,  0x8b,  0x1c,  0x3d,  0x85,  0xb7,  0x69,  0x47,  0x01,  0xa7,  0x26,  0xfe,  0x72,  0x06,  0x49,  0x04,
13478   0x1b,  0xdf,  0x89,  0x0a,  0x4d,  0x01,  0xfe,  0xd8,  0x14,  0x1f,  0xfe,  0x68,  0x06,  0x11,  0x9a,  0x01,
13479   0x43,  0x11,  0xfe,  0xe5,  0x00,  0x05,  0x3f,  0xb4,  0x0c,  0x3f,  0x17,  0x06,  0x01,  0xa7,  0xec,  0x72,
13480   0x70,  0x01,  0x6e,  0x87,  0x11,  0xfe,  0xe2,  0x00,  0x01,  0x08,  0x25,  0x32,  0xfe,  0x0a,  0xf0,  0xfe,
13481   0xa6,  0x06,  0x8c,  0xfe,  0x5c,  0x07,  0xfe,  0x06,  0xf0,  0xfe,  0x64,  0x07,  0x8d,  0x81,  0x02,  0x22,
13482   0x09,  0x04,  0x0b,  0xfe,  0x2e,  0x12,  0x15,  0x1a,  0x01,  0x08,  0x15,  0x00,  0x01,  0x08,  0x15,  0x00,
13483   0x01,  0x08,  0x15,  0x00,  0x01,  0x08,  0xfe,  0x99,  0xa4,  0x01,  0x08,  0x15,  0x00,  0x02,  0xfe,  0x32,
13484   0x08,  0x61,  0x04,  0x1b,  0xfe,  0x38,  0x12,  0x09,  0x04,  0x1b,  0x6e,  0x15,  0xfe,  0x1b,  0x00,  0x01,
13485   0x08,  0x15,  0x00,  0x01,  0x08,  0x15,  0x00,  0x01,  0x08,  0x15,  0x00,  0x01,  0x08,  0x15,  0x06,  0x01,
13486   0x08,  0x15,  0x00,  0x02,  0xd9,  0x66,  0x4c,  0xfe,  0x3a,  0x55,  0x5f,  0xfe,  0x9a,  0x81,  0x4b,  0x1d,
13487   0xba,  0xfe,  0x32,  0x07,  0x0a,  0x1d,  0xfe,  0x09,  0x6f,  0xaf,  0xfe,  0xca,  0x45,  0xfe,  0x32,  0x12,
13488   0x62,  0x2c,  0x85,  0x66,  0x7b,  0x01,  0x08,  0x25,  0x32,  0xfe,  0x0a,  0xf0,  0xfe,  0x32,  0x07,  0x8d,
13489   0x81,  0x8c,  0xfe,  0x5c,  0x07,  0x02,  0x22,  0x01,  0x43,  0x02,  0xfe,  0x8a,  0x06,  0x15,  0x19,  0x02,
13490   0xfe,  0x8a,  0x06,  0xfe,  0x9c,  0xf7,  0xd4,  0xfe,  0x2c,  0x90,  0xfe,  0xae,  0x90,  0x77,  0xfe,  0xca,
13491   0x07,  0x0c,  0x54,  0x18,  0x55,  0x09,  0x4a,  0x6a,  0x35,  0x1e,  0x20,  0x07,  0x10,  0xfe,  0x0e,  0x12,
13492   0x74,  0xfe,  0x80,  0x80,  0x37,  0x20,  0x63,  0x27,  0xfe,  0x06,  0x10,  0xfe,  0x83,  0xe7,  0xc4,  0xa1,
13493   0xfe,  0x03,  0x40,  0x09,  0x4a,  0x4f,  0x35,  0x01,  0xa8,  0xad,  0xfe,  0x1f,  0x40,  0x12,  0x58,  0x01,
13494   0xa5,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0xfe,  0x44,  0x51,  0xfe,  0xc6,  0x51,  0x83,  0xfb,  0xfe,
13495   0x8a,  0x90,  0x0c,  0x52,  0x18,  0x53,  0xfe,  0x0c,  0x90,  0xfe,  0x8e,  0x90,  0xfe,  0x40,  0x50,  0xfe,
13496   0xc2,  0x50,  0x0c,  0x39,  0x18,  0x3a,  0xfe,  0x4a,  0x10,  0x09,  0x04,  0x6a,  0xfe,  0x2a,  0x12,  0xfe,
13497   0x2c,  0x90,  0xfe,  0xae,  0x90,  0x0c,  0x54,  0x18,  0x55,  0x09,  0x04,  0x4f,  0x85,  0x01,  0xa8,  0xfe,
13498   0x1f,  0x80,  0x12,  0x58,  0xfe,  0x44,  0x90,  0xfe,  0xc6,  0x90,  0x0c,  0x56,  0x18,  0x57,  0xfb,  0xfe,
13499   0x8a,  0x90,  0x0c,  0x52,  0x18,  0x53,  0xfe,  0x40,  0x90,  0xfe,  0xc2,  0x90,  0x0c,  0x39,  0x18,  0x3a,
13500   0x0c,  0x38,  0x18,  0x4e,  0x09,  0x4a,  0x19,  0x35,  0x2a,  0x13,  0xfe,  0x4e,  0x11,  0x65,  0xfe,  0x48,
13501   0x08,  0xfe,  0x9e,  0xf0,  0xfe,  0x5c,  0x08,  0xb1,  0x16,  0x32,  0x2a,  0x73,  0xdd,  0xb8,  0xfe,  0x80,
13502   0x08,  0xb9,  0xfe,  0x9e,  0x08,  0x8c,  0xfe,  0x74,  0x08,  0xfe,  0x06,  0xf0,  0xfe,  0x7a,  0x08,  0x8d,
13503   0x81,  0x02,  0x22,  0x01,  0x43,  0xfe,  0xc9,  0x10,  0x15,  0x19,  0xfe,  0xc9,  0x10,  0x61,  0x04,  0x06,
13504   0xfe,  0x10,  0x12,  0x61,  0x04,  0x0b,  0x45,  0x09,  0x04,  0x0b,  0xfe,  0x68,  0x12,  0xfe,  0x2e,  0x1c,
13505   0x02,  0xfe,  0x24,  0x0a,  0x61,  0x04,  0x06,  0x45,  0x61,  0x04,  0x0b,  0xfe,  0x52,  0x12,  0xfe,  0x2c,
13506   0x1c,  0xfe,  0xaa,  0xf0,  0xfe,  0x1e,  0x09,  0xfe,  0xac,  0xf0,  0xfe,  0xbe,  0x08,  0xfe,  0x8a,  0x10,
13507   0xaa,  0xfe,  0xf3,  0x10,  0xfe,  0xad,  0xf0,  0xfe,  0xca,  0x08,  0x02,  0xfe,  0x24,  0x0a,  0xab,  0xfe,
13508   0xe7,  0x10,  0xfe,  0x2b,  0xf0,  0x9d,  0xe9,  0x1c,  0xfe,  0x00,  0xfe,  0xfe,  0x1c,  0x12,  0xb5,  0xfe,
13509   0xd2,  0xf0,  0x9d,  0xfe,  0x76,  0x18,  0x1c,  0x1a,  0x16,  0x9d,  0x05,  0xcb,  0x1c,  0x06,  0x16,  0x9d,
13510   0xb8,  0x6d,  0xb9,  0x6d,  0xaa,  0xab,  0xfe,  0xb1,  0x10,  0x70,  0x5e,  0x2b,  0x14,  0x92,  0x01,  0x33,
13511   0x0f,  0xfe,  0x35,  0x00,  0xfe,  0x01,  0xf0,  0x5a,  0x0f,  0x7c,  0x02,  0x5a,  0xfe,  0x74,  0x18,  0x1c,
13512   0xfe,  0x00,  0xf8,  0x16,  0x6d,  0x67,  0x1b,  0x01,  0xfe,  0x44,  0x0d,  0x3b,  0x01,  0xe6,  0x1e,  0x27,
13513   0x74,  0x67,  0x1a,  0x02,  0x6d,  0x09,  0x04,  0x0b,  0x21,  0xfe,  0x06,  0x0a,  0x09,  0x04,  0x6a,  0xfe,
13514   0x82,  0x12,  0x09,  0x04,  0x19,  0xfe,  0x66,  0x13,  0x1e,  0x58,  0xac,  0xfc,  0xfe,  0x83,  0x80,  0xfe,
13515   0xc8,  0x44,  0xfe,  0x2e,  0x13,  0xfe,  0x04,  0x91,  0xfe,  0x86,  0x91,  0x63,  0x27,  0xfe,  0x40,  0x59,
13516   0xfe,  0xc1,  0x59,  0x77,  0xd7,  0x05,  0x54,  0x31,  0x55,  0x0c,  0x7b,  0x18,  0x7c,  0xbe,  0x54,  0xbf,
13517   0x55,  0x01,  0xa8,  0xad,  0x63,  0x27,  0x12,  0x58,  0xc0,  0x38,  0xc1,  0x4e,  0x79,  0x56,  0x68,  0x57,
13518   0xf4,  0xf5,  0xfe,  0x04,  0xfa,  0x38,  0xfe,  0x05,  0xfa,  0x4e,  0x01,  0xa5,  0xa2,  0x23,  0x0c,  0x7b,
13519   0x0c,  0x7c,  0x79,  0x56,  0x68,  0x57,  0xfe,  0x12,  0x10,  0x09,  0x04,  0x19,  0x16,  0xd7,  0x79,  0x39,
13520   0x68,  0x3a,  0x09,  0x04,  0xfe,  0xf7,  0x00,  0x35,  0x05,  0x52,  0x31,  0x53,  0xfe,  0x10,  0x58,  0xfe,
13521   0x91,  0x58,  0xfe,  0x14,  0x59,  0xfe,  0x95,  0x59,  0x02,  0x6d,  0x09,  0x04,  0x19,  0x16,  0xd7,  0x09,
13522   0x04,  0xfe,  0xf7,  0x00,  0x35,  0xfe,  0x3a,  0x55,  0xfe,  0x19,  0x81,  0x5f,  0xfe,  0x10,  0x90,  0xfe,
13523   0x92,  0x90,  0xfe,  0xd7,  0x10,  0x2f,  0x07,  0x9b,  0x16,  0xfe,  0xc6,  0x08,  0x11,  0x9b,  0x09,  0x04,
13524   0x0b,  0xfe,  0x14,  0x13,  0x05,  0x39,  0x31,  0x3a,  0x77,  0xfe,  0xc6,  0x08,  0xfe,  0x0c,  0x58,  0xfe,
13525   0x8d,  0x58,  0x02,  0x6d,  0x23,  0x47,  0xfe,  0x19,  0x80,  0xde,  0x09,  0x04,  0x0b,  0xfe,  0x1a,  0x12,
13526   0xfe,  0x6c,  0x19,  0xfe,  0x19,  0x41,  0xe9,  0xb5,  0xfe,  0xd1,  0xf0,  0xd9,  0x14,  0x7a,  0x01,  0x33,
13527   0x0f,  0xfe,  0x44,  0x00,  0xfe,  0x8e,  0x10,  0xfe,  0x6c,  0x19,  0xbe,  0x39,  0xfe,  0xed,  0x19,  0xbf,
13528   0x3a,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0xe9,  0x1c,  0xfe,  0x00,  0xff,  0x34,  0xfe,  0x74,  0x10,
13529   0xb5,  0xfe,  0xd2,  0xf0,  0xfe,  0xb2,  0x0a,  0xfe,  0x76,  0x18,  0x1c,  0x1a,  0x84,  0x05,  0xcb,  0x1c,
13530   0x06,  0xfe,  0x08,  0x13,  0x0f,  0xfe,  0x16,  0x00,  0x02,  0x5a,  0xfe,  0xd1,  0xf0,  0xfe,  0xc4,  0x0a,
13531   0x14,  0x7a,  0x01,  0x33,  0x0f,  0xfe,  0x17,  0x00,  0xfe,  0x42,  0x10,  0xfe,  0xce,  0xf0,  0xfe,  0xca,
13532   0x0a,  0xfe,  0x3c,  0x10,  0xfe,  0xcd,  0xf0,  0xfe,  0xd6,  0x0a,  0x0f,  0xfe,  0x22,  0x00,  0x02,  0x5a,
13533   0xfe,  0xcb,  0xf0,  0xfe,  0xe2,  0x0a,  0x0f,  0xfe,  0x24,  0x00,  0x02,  0x5a,  0xfe,  0xd0,  0xf0,  0xfe,
13534   0xec,  0x0a,  0x0f,  0x93,  0xdc,  0xfe,  0xcf,  0xf0,  0xfe,  0xf6,  0x0a,  0x0f,  0x4c,  0xfe,  0x10,  0x10,
13535   0xfe,  0xcc,  0xf0,  0xd9,  0x61,  0x04,  0x19,  0x3b,  0x0f,  0xfe,  0x12,  0x00,  0x2a,  0x13,  0xfe,  0x4e,
13536   0x11,  0x65,  0xfe,  0x0c,  0x0b,  0xfe,  0x9e,  0xf0,  0xfe,  0x20,  0x0b,  0xb1,  0x16,  0x32,  0x2a,  0x73,
13537   0xdd,  0xb8,  0x22,  0xb9,  0x22,  0x2a,  0xec,  0x65,  0xfe,  0x2c,  0x0b,  0x25,  0x32,  0x8c,  0xfe,  0x48,
13538   0x0b,  0x8d,  0x81,  0xb8,  0xd4,  0xb9,  0xd4,  0x02,  0x22,  0x01,  0x43,  0xfe,  0xdb,  0x10,  0x11,  0xfe,
13539   0xe8,  0x00,  0xaa,  0xab,  0x70,  0xbc,  0x7d,  0xbd,  0x7f,  0xfe,  0x89,  0xf0,  0x22,  0x30,  0x2e,  0xd8,
13540   0xbc,  0x7d,  0xbd,  0x7f,  0x01,  0x08,  0x1f,  0x22,  0x30,  0x2e,  0xd6,  0xb1,  0x45,  0x0f,  0xfe,  0x42,
13541   0x00,  0x02,  0x5a,  0x78,  0x06,  0xfe,  0x81,  0x49,  0x16,  0xfe,  0x38,  0x0c,  0x09,  0x04,  0x0b,  0xfe,
13542   0x44,  0x13,  0x0f,  0x00,  0x4b,  0x0b,  0xfe,  0x54,  0x12,  0x4b,  0xfe,  0x28,  0x00,  0x21,  0xfe,  0xa6,
13543   0x0c,  0x0a,  0x40,  0x01,  0x0e,  0x07,  0x00,  0x5d,  0x3e,  0xfe,  0x28,  0x00,  0xfe,  0xe2,  0x10,  0x01,
13544   0xe7,  0x01,  0xe8,  0x0a,  0x99,  0x01,  0xfe,  0x32,  0x0e,  0x59,  0x11,  0x2d,  0x01,  0x6f,  0x02,  0x29,
13545   0x0f,  0xfe,  0x44,  0x00,  0x4b,  0x0b,  0xdf,  0x3e,  0x0b,  0xfe,  0xb4,  0x10,  0x01,  0x86,  0x3e,  0x0b,
13546   0xfe,  0xaa,  0x10,  0x01,  0x86,  0xfe,  0x19,  0x82,  0xfe,  0x34,  0x46,  0xa3,  0x3e,  0x0b,  0x0f,  0xfe,
13547   0x43,  0x00,  0xfe,  0x96,  0x10,  0x09,  0x4a,  0x0b,  0x35,  0x01,  0xe7,  0x01,  0xe8,  0x59,  0x11,  0x2d,
13548   0x01,  0x6f,  0x67,  0x0b,  0x59,  0x3c,  0x8a,  0x02,  0xfe,  0x2a,  0x03,  0x09,  0x04,  0x0b,  0x84,  0x3e,
13549   0x0b,  0x0f,  0x00,  0xfe,  0x5c,  0x10,  0x61,  0x04,  0x1b,  0xfe,  0x58,  0x12,  0x09,  0x04,  0x1b,  0xfe,
13550   0x50,  0x13,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x5c,  0x0c,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,
13551   0xf0,  0xfe,  0x62,  0x0c,  0x09,  0x4a,  0x1b,  0x35,  0xfe,  0xa9,  0x10,  0x0f,  0xfe,  0x15,  0x00,  0xfe,
13552   0x04,  0xe6,  0x0b,  0x5f,  0x5c,  0x0f,  0xfe,  0x13,  0x00,  0xfe,  0x10,  0x10,  0x0f,  0xfe,  0x47,  0x00,
13553   0xa1,  0x0f,  0xfe,  0x41,  0x00,  0xa0,  0x0f,  0xfe,  0x24,  0x00,  0x87,  0xaa,  0xab,  0x70,  0x05,  0x6b,
13554   0x28,  0x21,  0xd1,  0x5f,  0xfe,  0x04,  0xe6,  0x1b,  0xfe,  0x9d,  0x41,  0xfe,  0x1c,  0x42,  0x59,  0x01,
13555   0xda,  0x02,  0x29,  0xea,  0x14,  0x0b,  0x37,  0x95,  0xa9,  0x14,  0xfe,  0x31,  0x00,  0x37,  0x97,  0x01,
13556   0xfe,  0x54,  0x0f,  0x02,  0xd0,  0x3c,  0xfe,  0x06,  0xec,  0xc9,  0xee,  0x3e,  0x1d,  0xfe,  0xce,  0x45,
13557   0x34,  0x3c,  0xfe,  0x06,  0xea,  0xc9,  0xfe,  0x47,  0x4b,  0x89,  0xfe,  0x75,  0x57,  0x05,  0x51,  0xfe,
13558   0x98,  0x56,  0xfe,  0x38,  0x12,  0x0a,  0x42,  0x01,  0x0e,  0xfe,  0x44,  0x48,  0x46,  0x09,  0x04,  0x1d,
13559   0xfe,  0x1a,  0x13,  0x0a,  0x40,  0x01,  0x0e,  0x47,  0xfe,  0x41,  0x58,  0x0a,  0x99,  0x01,  0x0e,  0xfe,
13560   0x49,  0x54,  0x8e,  0xfe,  0x2a,  0x0d,  0x02,  0xfe,  0x2a,  0x03,  0x0a,  0x51,  0xfe,  0xee,  0x14,  0xee,
13561   0x3e,  0x1d,  0xfe,  0xce,  0x45,  0x34,  0x3c,  0xfe,  0xce,  0x47,  0xfe,  0xad,  0x13,  0x02,  0x29,  0x1e,
13562   0x20,  0x07,  0x10,  0xfe,  0x9e,  0x12,  0x23,  0x12,  0x4d,  0x12,  0x94,  0x12,  0xce,  0x1e,  0x2d,  0x47,
13563   0x37,  0x2d,  0xb1,  0xe0,  0xfe,  0xbc,  0xf0,  0xfe,  0xec,  0x0d,  0x13,  0x06,  0x12,  0x4d,  0x01,  0xfe,
13564   0xe2,  0x15,  0x05,  0xfe,  0x38,  0x01,  0x31,  0xfe,  0x3a,  0x01,  0x77,  0xfe,  0xf0,  0x0d,  0xfe,  0x02,
13565   0xec,  0xce,  0x62,  0x00,  0x5d,  0xfe,  0x04,  0xec,  0x20,  0x46,  0xfe,  0x05,  0xf6,  0xfe,  0x34,  0x01,
13566   0x01,  0xfe,  0x52,  0x16,  0xfb,  0xfe,  0x48,  0xf4,  0x0d,  0xfe,  0x18,  0x13,  0xaf,  0xfe,  0x02,  0xea,
13567   0xce,  0x62,  0x7a,  0xfe,  0xc5,  0x13,  0x14,  0x1b,  0x37,  0x95,  0xa9,  0x5c,  0x05,  0xfe,  0x38,  0x01,
13568   0x1c,  0xfe,  0xf0,  0xff,  0x0c,  0xfe,  0x60,  0x01,  0x05,  0xfe,  0x3a,  0x01,  0x0c,  0xfe,  0x62,  0x01,
13569   0x3d,  0x12,  0x20,  0x24,  0x06,  0x12,  0x2d,  0x11,  0x2d,  0x8a,  0x13,  0x06,  0x03,  0x23,  0x03,  0x1e,
13570   0x4d,  0xfe,  0xf7,  0x12,  0x1e,  0x94,  0xac,  0x12,  0x94,  0x07,  0x7a,  0xfe,  0x71,  0x13,  0xfe,  0x24,
13571   0x1c,  0x14,  0x1a,  0x37,  0x95,  0xa9,  0xfe,  0xd9,  0x10,  0xb6,  0xfe,  0x03,  0xdc,  0xfe,  0x73,  0x57,
13572   0xfe,  0x80,  0x5d,  0x03,  0xb6,  0xfe,  0x03,  0xdc,  0xfe,  0x5b,  0x57,  0xfe,  0x80,  0x5d,  0x03,  0xfe,
13573   0x03,  0x57,  0xb6,  0x23,  0xfe,  0x00,  0xcc,  0x03,  0xfe,  0x03,  0x57,  0xb6,  0x75,  0x03,  0x09,  0x04,
13574   0x4c,  0xfe,  0x22,  0x13,  0xfe,  0x1c,  0x80,  0x07,  0x06,  0xfe,  0x1a,  0x13,  0xfe,  0x1e,  0x80,  0xe1,
13575   0xfe,  0x1d,  0x80,  0xa4,  0xfe,  0x0c,  0x90,  0xfe,  0x0e,  0x13,  0xfe,  0x0e,  0x90,  0xa3,  0xfe,  0x3c,
13576   0x90,  0xfe,  0x30,  0xf4,  0x0b,  0xfe,  0x3c,  0x50,  0xa0,  0x01,  0xfe,  0x82,  0x16,  0x2f,  0x07,  0x2d,
13577   0xe0,  0x01,  0xfe,  0xbc,  0x15,  0x09,  0x04,  0x1d,  0x45,  0x01,  0xe7,  0x01,  0xe8,  0x11,  0xfe,  0xe9,
13578   0x00,  0x09,  0x04,  0x4c,  0xfe,  0x2c,  0x13,  0x01,  0xfe,  0x14,  0x16,  0xfe,  0x1e,  0x1c,  0xfe,  0x14,
13579   0x90,  0xfe,  0x96,  0x90,  0x0c,  0xfe,  0x64,  0x01,  0x18,  0xfe,  0x66,  0x01,  0x09,  0x04,  0x4f,  0xfe,
13580   0x12,  0x12,  0xfe,  0x03,  0x80,  0x74,  0xfe,  0x01,  0xec,  0x20,  0xfe,  0x80,  0x40,  0x12,  0x20,  0x63,
13581   0x27,  0x11,  0xc8,  0x59,  0x1e,  0x20,  0xed,  0x76,  0x20,  0x03,  0xfe,  0x08,  0x1c,  0x05,  0xfe,  0xac,
13582   0x00,  0xfe,  0x06,  0x58,  0x05,  0xfe,  0xae,  0x00,  0xfe,  0x07,  0x58,  0x05,  0xfe,  0xb0,  0x00,  0xfe,
13583   0x08,  0x58,  0x05,  0xfe,  0xb2,  0x00,  0xfe,  0x09,  0x58,  0xfe,  0x0a,  0x1c,  0x24,  0x69,  0x12,  0xc9,
13584   0x23,  0x0c,  0x50,  0x0c,  0x3f,  0x13,  0x40,  0x48,  0x5f,  0x17,  0x1d,  0xfe,  0x90,  0x4d,  0xfe,  0x91,
13585   0x54,  0x21,  0xfe,  0x08,  0x0f,  0x3e,  0x10,  0x13,  0x42,  0x48,  0x17,  0x4c,  0xfe,  0x90,  0x4d,  0xfe,
13586   0x91,  0x54,  0x21,  0xfe,  0x1e,  0x0f,  0x24,  0x10,  0x12,  0x20,  0x78,  0x2c,  0x46,  0x1e,  0x20,  0xed,
13587   0x76,  0x20,  0x11,  0xc8,  0xf6,  0xfe,  0xd6,  0xf0,  0xfe,  0x32,  0x0f,  0xea,  0x70,  0xfe,  0x14,  0x1c,
13588   0xfe,  0x10,  0x1c,  0xfe,  0x18,  0x1c,  0x03,  0x3c,  0xfe,  0x0c,  0x14,  0xee,  0xfe,  0x07,  0xe6,  0x1d,
13589   0xfe,  0xce,  0x47,  0xfe,  0xf5,  0x13,  0x03,  0x01,  0x86,  0x78,  0x2c,  0x46,  0xfa,  0xef,  0xfe,  0x42,
13590   0x13,  0x2f,  0x07,  0x2d,  0xfe,  0x34,  0x13,  0x0a,  0x42,  0x01,  0x0e,  0xb0,  0xfe,  0x36,  0x12,  0xf0,
13591   0xfe,  0x45,  0x48,  0x01,  0xe3,  0xfe,  0x00,  0xcc,  0xb0,  0xfe,  0xf3,  0x13,  0x3d,  0x75,  0x07,  0x10,
13592   0xa3,  0x0a,  0x80,  0x01,  0x0e,  0xfe,  0x80,  0x5c,  0x01,  0x6f,  0xfe,  0x0e,  0x10,  0x07,  0x7e,  0x45,
13593   0xf6,  0xfe,  0xd6,  0xf0,  0xfe,  0x6c,  0x0f,  0x03,  0xfe,  0x44,  0x58,  0x74,  0xfe,  0x01,  0xec,  0x97,
13594   0xfe,  0x9e,  0x40,  0xfe,  0x9d,  0xe7,  0x00,  0xfe,  0x9c,  0xe7,  0x1b,  0x76,  0x27,  0x01,  0xda,  0xfe,
13595   0xdd,  0x10,  0x2a,  0xbc,  0x7d,  0xbd,  0x7f,  0x30,  0x2e,  0xd5,  0x07,  0x1b,  0xfe,  0x48,  0x12,  0x07,
13596   0x0b,  0xfe,  0x56,  0x12,  0x07,  0x1a,  0xfe,  0x30,  0x12,  0x07,  0xc2,  0x16,  0xfe,  0x3e,  0x11,  0x07,
13597   0xfe,  0x23,  0x00,  0x16,  0xfe,  0x4a,  0x11,  0x07,  0x06,  0x16,  0xfe,  0xa8,  0x11,  0x07,  0x19,  0xfe,
13598   0x12,  0x12,  0x07,  0x00,  0x16,  0x22,  0x14,  0xc2,  0x01,  0x33,  0x9f,  0x2b,  0x01,  0x08,  0x8c,  0x43,
13599   0x03,  0x2b,  0xfe,  0x62,  0x08,  0x0a,  0xca,  0x01,  0xfe,  0x32,  0x0e,  0x11,  0x7e,  0x02,  0x29,  0x2b,
13600   0x2f,  0x07,  0x9b,  0xfe,  0xd9,  0x13,  0x79,  0x39,  0x68,  0x3a,  0x77,  0xfe,  0xfc,  0x10,  0x09,  0x04,
13601   0x6a,  0xfe,  0x72,  0x12,  0xc0,  0x38,  0xc1,  0x4e,  0xf4,  0xf5,  0x8e,  0xfe,  0xc6,  0x10,  0x1e,  0x58,
13602   0xfe,  0x26,  0x13,  0x05,  0x7b,  0x31,  0x7c,  0x77,  0xfe,  0x82,  0x0c,  0x0c,  0x54,  0x18,  0x55,  0x23,
13603   0x0c,  0x7b,  0x0c,  0x7c,  0x01,  0xa8,  0x24,  0x69,  0x73,  0x12,  0x58,  0x01,  0xa5,  0xc0,  0x38,  0xc1,
13604   0x4e,  0xfe,  0x04,  0x55,  0xfe,  0xa5,  0x55,  0xfe,  0x04,  0xfa,  0x38,  0xfe,  0x05,  0xfa,  0x4e,  0xfe,
13605   0x91,  0x10,  0x05,  0x56,  0x31,  0x57,  0xfe,  0x40,  0x56,  0xfe,  0xe1,  0x56,  0x0c,  0x56,  0x18,  0x57,
13606   0x83,  0xc0,  0x38,  0xc1,  0x4e,  0xf4,  0xf5,  0x05,  0x52,  0x31,  0x53,  0xfe,  0x00,  0x56,  0xfe,  0xa1,
13607   0x56,  0x0c,  0x52,  0x18,  0x53,  0x09,  0x04,  0x6a,  0xfe,  0x1e,  0x12,  0x1e,  0x58,  0xfe,  0x1f,  0x40,
13608   0x05,  0x54,  0x31,  0x55,  0xfe,  0x2c,  0x50,  0xfe,  0xae,  0x50,  0x05,  0x56,  0x31,  0x57,  0xfe,  0x44,
13609   0x50,  0xfe,  0xc6,  0x50,  0x05,  0x52,  0x31,  0x53,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0x05,  0x39,
13610   0x31,  0x3a,  0xfe,  0x40,  0x50,  0xfe,  0xc2,  0x50,  0x02,  0x5c,  0x24,  0x06,  0x12,  0xcd,  0x02,  0x5b,
13611   0x2b,  0x01,  0x08,  0x1f,  0x44,  0x30,  0x2e,  0xd5,  0x07,  0x06,  0x21,  0x44,  0x2f,  0x07,  0x9b,  0x21,
13612   0x5b,  0x01,  0x6e,  0x1c,  0x3d,  0x16,  0x44,  0x09,  0x04,  0x0b,  0xe2,  0x79,  0x39,  0x68,  0x3a,  0xfe,
13613   0x0a,  0x55,  0x34,  0xfe,  0x8b,  0x55,  0xbe,  0x39,  0xbf,  0x3a,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,
13614   0x02,  0x5b,  0xfe,  0x19,  0x81,  0xaf,  0xfe,  0x19,  0x41,  0x02,  0x5b,  0x2b,  0x01,  0x08,  0x25,  0x32,
13615   0x1f,  0xa2,  0x30,  0x2e,  0xd8,  0x4b,  0x1a,  0xfe,  0xa6,  0x12,  0x4b,  0x0b,  0x3b,  0x02,  0x44,  0x01,
13616   0x08,  0x25,  0x32,  0x1f,  0xa2,  0x30,  0x2e,  0xd6,  0x07,  0x1a,  0x21,  0x44,  0x01,  0x08,  0x1f,  0xa2,
13617   0x30,  0x2e,  0xfe,  0xe8,  0x09,  0xfe,  0xc2,  0x49,  0x60,  0x05,  0xfe,  0x9c,  0x00,  0x28,  0x84,  0x49,
13618   0x04,  0x19,  0x34,  0x9f,  0xfe,  0xbb,  0x45,  0x4b,  0x00,  0x45,  0x3e,  0x06,  0x78,  0x3d,  0xfe,  0xda,
13619   0x14,  0x01,  0x6e,  0x87,  0xfe,  0x4b,  0x45,  0xe2,  0x2f,  0x07,  0x9a,  0xe1,  0x05,  0xc6,  0x28,  0x84,
13620   0x05,  0x3f,  0x28,  0x34,  0x5e,  0x02,  0x5b,  0xfe,  0xc0,  0x5d,  0xfe,  0xf8,  0x14,  0xfe,  0x03,  0x17,
13621   0x05,  0x50,  0xb4,  0x0c,  0x50,  0x5e,  0x2b,  0x01,  0x08,  0x26,  0x5c,  0x01,  0xfe,  0xaa,  0x14,  0x02,
13622   0x5c,  0x01,  0x08,  0x25,  0x32,  0x1f,  0x44,  0x30,  0x2e,  0xd6,  0x07,  0x06,  0x21,  0x44,  0x01,  0xfe,
13623   0x8e,  0x13,  0xfe,  0x42,  0x58,  0xfe,  0x82,  0x14,  0xfe,  0xa4,  0x14,  0x87,  0xfe,  0x4a,  0xf4,  0x0b,
13624   0x16,  0x44,  0xfe,  0x4a,  0xf4,  0x06,  0xfe,  0x0c,  0x12,  0x2f,  0x07,  0x9a,  0x85,  0x02,  0x5b,  0x05,
13625   0x3f,  0xb4,  0x0c,  0x3f,  0x5e,  0x2b,  0x01,  0x08,  0x26,  0x5c,  0x01,  0xfe,  0xd8,  0x14,  0x02,  0x5c,
13626   0x13,  0x06,  0x65,  0xfe,  0xca,  0x12,  0x26,  0xfe,  0xe0,  0x12,  0x72,  0xf1,  0x01,  0x08,  0x23,  0x72,
13627   0x03,  0x8f,  0xfe,  0xdc,  0x12,  0x25,  0xfe,  0xdc,  0x12,  0x1f,  0xfe,  0xca,  0x12,  0x5e,  0x2b,  0x01,
13628   0x08,  0xfe,  0xd5,  0x10,  0x13,  0x6c,  0xff,  0x02,  0x00,  0x57,  0x48,  0x8b,  0x1c,  0xfe,  0xff,  0x7f,
13629   0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x03,  0x13,  0x6c,  0xff,  0x02,  0x00,  0x57,  0x48,  0x8b,  0x1c,
13630   0x3d,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x03,  0x13,  0x6c,  0xff,  0x02,  0x00,  0x57,  0x48,  0x8b,
13631   0x03,  0x13,  0x6c,  0xff,  0x02,  0x00,  0x57,  0x48,  0x8b,  0xfe,  0x0b,  0x58,  0x03,  0x0a,  0x50,  0x01,
13632   0x82,  0x0a,  0x3f,  0x01,  0x82,  0x03,  0xfc,  0x1c,  0x10,  0xff,  0x03,  0x00,  0x54,  0xfe,  0x00,  0xf4,
13633   0x19,  0x48,  0xfe,  0x00,  0x7d,  0xfe,  0x01,  0x7d,  0xfe,  0x02,  0x7d,  0xfe,  0x03,  0x7c,  0x63,  0x27,
13634   0x0c,  0x52,  0x18,  0x53,  0xbe,  0x56,  0xbf,  0x57,  0x03,  0xfe,  0x62,  0x08,  0xfe,  0x82,  0x4a,  0xfe,
13635   0xe1,  0x1a,  0xfe,  0x83,  0x5a,  0x74,  0x03,  0x01,  0xfe,  0x14,  0x18,  0xfe,  0x42,  0x48,  0x5f,  0x60,
13636   0x89,  0x01,  0x08,  0x1f,  0xfe,  0xa2,  0x14,  0x30,  0x2e,  0xd8,  0x01,  0x08,  0x1f,  0xfe,  0xa2,  0x14,
13637   0x30,  0x2e,  0xfe,  0xe8,  0x0a,  0xfe,  0xc1,  0x59,  0x05,  0xc6,  0x28,  0xfe,  0xcc,  0x12,  0x49,  0x04,
13638   0x1b,  0xfe,  0xc4,  0x13,  0x23,  0x62,  0x1b,  0xe2,  0x4b,  0xc3,  0x64,  0xfe,  0xe8,  0x13,  0x3b,  0x13,
13639   0x06,  0x17,  0xc3,  0x78,  0xdb,  0xfe,  0x78,  0x10,  0xff,  0x02,  0x83,  0x55,  0xa1,  0xff,  0x02,  0x83,
13640   0x55,  0x62,  0x1a,  0xa4,  0xbb,  0xfe,  0x30,  0x00,  0x8e,  0xe4,  0x17,  0x2c,  0x13,  0x06,  0xfe,  0x56,
13641   0x10,  0x62,  0x0b,  0xe1,  0xbb,  0xfe,  0x64,  0x00,  0x8e,  0xe4,  0x0a,  0xfe,  0x64,  0x00,  0x17,  0x93,
13642   0x13,  0x06,  0xfe,  0x28,  0x10,  0x62,  0x06,  0xfe,  0x60,  0x13,  0xbb,  0xfe,  0xc8,  0x00,  0x8e,  0xe4,
13643   0x0a,  0xfe,  0xc8,  0x00,  0x17,  0x4d,  0x13,  0x06,  0x83,  0xbb,  0xfe,  0x90,  0x01,  0xba,  0xfe,  0x4e,
13644   0x14,  0x89,  0xfe,  0x12,  0x10,  0xfe,  0x43,  0xf4,  0x94,  0xfe,  0x56,  0xf0,  0xfe,  0x60,  0x14,  0xfe,
13645   0x04,  0xf4,  0x6c,  0xfe,  0x43,  0xf4,  0x93,  0xfe,  0xf3,  0x10,  0xf9,  0x01,  0xfe,  0x22,  0x13,  0x1c,
13646   0x3d,  0xfe,  0x10,  0x13,  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,  0x69,  0xba,  0xfe,  0x9c,  0x14,  0xb7,
13647   0x69,  0xfe,  0x1c,  0x10,  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,  0x19,  0xba,  0xfe,  0x9c,  0x14,  0xb7,
13648   0x19,  0x83,  0x60,  0x23,  0xfe,  0x4d,  0xf4,  0x00,  0xdf,  0x89,  0x13,  0x06,  0xfe,  0xb4,  0x56,  0xfe,
13649   0xc3,  0x58,  0x03,  0x60,  0x13,  0x0b,  0x03,  0x15,  0x06,  0x01,  0x08,  0x26,  0xe5,  0x15,  0x0b,  0x01,
13650   0x08,  0x26,  0xe5,  0x15,  0x1a,  0x01,  0x08,  0x26,  0xe5,  0x72,  0xfe,  0x89,  0x49,  0x01,  0x08,  0x03,
13651   0x15,  0x06,  0x01,  0x08,  0x26,  0xa6,  0x15,  0x1a,  0x01,  0x08,  0x26,  0xa6,  0x15,  0x06,  0x01,  0x08,
13652   0x26,  0xa6,  0xfe,  0x89,  0x49,  0x01,  0x08,  0x26,  0xa6,  0x72,  0xfe,  0x89,  0x4a,  0x01,  0x08,  0x03,
13653   0x60,  0x03,  0x1e,  0xcc,  0x07,  0x06,  0xfe,  0x44,  0x13,  0xad,  0x12,  0xcc,  0xfe,  0x49,  0xf4,  0x00,
13654   0x3b,  0x72,  0x9f,  0x5e,  0xfe,  0x01,  0xec,  0xfe,  0x27,  0x01,  0xf1,  0x01,  0x08,  0x2f,  0x07,  0xfe,
13655   0xe3,  0x00,  0xfe,  0x20,  0x13,  0x1f,  0xfe,  0x5a,  0x15,  0x23,  0x12,  0xcd,  0x01,  0x43,  0x1e,  0xcd,
13656   0x07,  0x06,  0x45,  0x09,  0x4a,  0x06,  0x35,  0x03,  0x0a,  0x42,  0x01,  0x0e,  0xed,  0x88,  0x07,  0x10,
13657   0xa4,  0x0a,  0x80,  0x01,  0x0e,  0x88,  0x0a,  0x51,  0x01,  0x9e,  0x03,  0x0a,  0x80,  0x01,  0x0e,  0x88,
13658   0xfe,  0x80,  0xe7,  0x10,  0x07,  0x10,  0x84,  0xfe,  0x45,  0x58,  0x01,  0xe3,  0x88,  0x03,  0x0a,  0x42,
13659   0x01,  0x0e,  0x88,  0x0a,  0x51,  0x01,  0x9e,  0x03,  0x0a,  0x42,  0x01,  0x0e,  0xfe,  0x80,  0x80,  0xf2,
13660   0xfe,  0x49,  0xe4,  0x10,  0xa4,  0x0a,  0x80,  0x01,  0x0e,  0xf2,  0x0a,  0x51,  0x01,  0x82,  0x03,  0x17,
13661   0x10,  0x71,  0x66,  0xfe,  0x60,  0x01,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x24,  0x1c,  0xfe,
13662   0x1d,  0xf7,  0x1d,  0x90,  0xfe,  0xf6,  0x15,  0x01,  0xfe,  0xfc,  0x16,  0xe0,  0x91,  0x1d,  0x66,  0xfe,
13663   0x2c,  0x01,  0xfe,  0x2f,  0x19,  0x03,  0xae,  0x21,  0xfe,  0xe6,  0x15,  0xfe,  0xda,  0x10,  0x17,  0x10,
13664   0x71,  0x05,  0xfe,  0x64,  0x01,  0xfe,  0x00,  0xf4,  0x19,  0xfe,  0x18,  0x58,  0x05,  0xfe,  0x66,  0x01,
13665   0xfe,  0x19,  0x58,  0x91,  0x19,  0xfe,  0x3c,  0x90,  0xfe,  0x30,  0xf4,  0x06,  0xfe,  0x3c,  0x50,  0x66,
13666   0xfe,  0x38,  0x00,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0x19,  0x90,  0xfe,  0x40,  0x16,  0xfe,  0xb6,
13667   0x14,  0x34,  0x03,  0xae,  0x21,  0xfe,  0x18,  0x16,  0xfe,  0x9c,  0x10,  0x17,  0x10,  0x71,  0xfe,  0x83,
13668   0x5a,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x1d,  0xf7,  0x38,  0x90,  0xfe,  0x62,  0x16,  0xfe,
13669   0x94,  0x14,  0xfe,  0x10,  0x13,  0x91,  0x38,  0x66,  0x1b,  0xfe,  0xaf,  0x19,  0xfe,  0x98,  0xe7,  0x00,
13670   0x03,  0xae,  0x21,  0xfe,  0x56,  0x16,  0xfe,  0x6c,  0x10,  0x17,  0x10,  0x71,  0xfe,  0x30,  0xbc,  0xfe,
13671   0xb2,  0xbc,  0x91,  0xc5,  0x66,  0x1b,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0xc5,  0x90,  0xfe,  0x9a,
13672   0x16,  0xfe,  0x5c,  0x14,  0x34,  0x03,  0xae,  0x21,  0xfe,  0x86,  0x16,  0xfe,  0x42,  0x10,  0xfe,  0x02,
13673   0xf6,  0x10,  0x71,  0xfe,  0x18,  0xfe,  0x54,  0xfe,  0x19,  0xfe,  0x55,  0xfc,  0xfe,  0x1d,  0xf7,  0x4f,
13674   0x90,  0xfe,  0xc0,  0x16,  0xfe,  0x36,  0x14,  0xfe,  0x1c,  0x13,  0x91,  0x4f,  0x47,  0xfe,  0x83,  0x58,
13675   0xfe,  0xaf,  0x19,  0xfe,  0x80,  0xe7,  0x10,  0xfe,  0x81,  0xe7,  0x10,  0x11,  0xfe,  0xdd,  0x00,  0x63,
13676   0x27,  0x03,  0x63,  0x27,  0xfe,  0x12,  0x45,  0x21,  0xfe,  0xb0,  0x16,  0x14,  0x06,  0x37,  0x95,  0xa9,
13677   0x02,  0x29,  0xfe,  0x39,  0xf0,  0xfe,  0x04,  0x17,  0x23,  0x03,  0xfe,  0x7e,  0x18,  0x1c,  0x1a,  0x5d,
13678   0x13,  0x0d,  0x03,  0x71,  0x05,  0xcb,  0x1c,  0x06,  0xfe,  0xef,  0x12,  0xfe,  0xe1,  0x10,  0x78,  0x2c,
13679   0x46,  0x2f,  0x07,  0x2d,  0xfe,  0x3c,  0x13,  0xfe,  0x82,  0x14,  0xfe,  0x42,  0x13,  0x3c,  0x8a,  0x0a,
13680   0x42,  0x01,  0x0e,  0xb0,  0xfe,  0x3e,  0x12,  0xf0,  0xfe,  0x45,  0x48,  0x01,  0xe3,  0xfe,  0x00,  0xcc,
13681   0xb0,  0xfe,  0xf3,  0x13,  0x3d,  0x75,  0x07,  0x10,  0xa3,  0x0a,  0x80,  0x01,  0x0e,  0xf2,  0x01,  0x6f,
13682   0xfe,  0x16,  0x10,  0x07,  0x7e,  0x85,  0xfe,  0x40,  0x14,  0xfe,  0x24,  0x12,  0xf6,  0xfe,  0xd6,  0xf0,
13683   0xfe,  0x24,  0x17,  0x17,  0x0b,  0x03,  0xfe,  0x9c,  0xe7,  0x0b,  0x0f,  0xfe,  0x15,  0x00,  0x59,  0x76,
13684   0x27,  0x01,  0xda,  0x17,  0x06,  0x03,  0x3c,  0x8a,  0x09,  0x4a,  0x1d,  0x35,  0x11,  0x2d,  0x01,  0x6f,
13685   0x17,  0x06,  0x03,  0xfe,  0x38,  0x90,  0xfe,  0xba,  0x90,  0x79,  0xc7,  0x68,  0xc8,  0xfe,  0x48,  0x55,
13686   0x34,  0xfe,  0xc9,  0x55,  0x03,  0x1e,  0x98,  0x73,  0x12,  0x98,  0x03,  0x0a,  0x99,  0x01,  0x0e,  0xf0,
13687   0x0a,  0x40,  0x01,  0x0e,  0xfe,  0x49,  0x44,  0x16,  0xfe,  0xf0,  0x17,  0x73,  0x75,  0x03,  0x0a,  0x42,
13688   0x01,  0x0e,  0x07,  0x10,  0x45,  0x0a,  0x51,  0x01,  0x9e,  0x0a,  0x40,  0x01,  0x0e,  0x73,  0x75,  0x03,
13689   0xfe,  0x4e,  0xe4,  0x1a,  0x64,  0xfe,  0x24,  0x18,  0x05,  0xfe,  0x90,  0x00,  0xfe,  0x3a,  0x45,  0x5b,
13690   0xfe,  0x4e,  0xe4,  0xc2,  0x64,  0xfe,  0x36,  0x18,  0x05,  0xfe,  0x92,  0x00,  0xfe,  0x02,  0xe6,  0x1b,
13691   0xdc,  0xfe,  0x4e,  0xe4,  0xfe,  0x0b,  0x00,  0x64,  0xfe,  0x48,  0x18,  0x05,  0xfe,  0x94,  0x00,  0xfe,
13692   0x02,  0xe6,  0x19,  0xfe,  0x08,  0x10,  0x05,  0xfe,  0x96,  0x00,  0xfe,  0x02,  0xe6,  0x2c,  0xfe,  0x4e,
13693   0x45,  0xfe,  0x0c,  0x12,  0xaf,  0xff,  0x04,  0x68,  0x54,  0xde,  0x1c,  0x69,  0x03,  0x07,  0x7a,  0xfe,
13694   0x5a,  0xf0,  0xfe,  0x74,  0x18,  0x24,  0xfe,  0x09,  0x00,  0xfe,  0x34,  0x10,  0x07,  0x1b,  0xfe,  0x5a,
13695   0xf0,  0xfe,  0x82,  0x18,  0x24,  0xc3,  0xfe,  0x26,  0x10,  0x07,  0x1a,  0x5d,  0x24,  0x2c,  0xdc,  0x07,
13696   0x0b,  0x5d,  0x24,  0x93,  0xfe,  0x0e,  0x10,  0x07,  0x06,  0x5d,  0x24,  0x4d,  0x9f,  0xad,  0x03,  0x14,
13697   0xfe,  0x09,  0x00,  0x01,  0x33,  0xfe,  0x04,  0xfe,  0x7d,  0x05,  0x7f,  0xf9,  0x03,  0x25,  0xfe,  0xca,
13698   0x18,  0xfe,  0x14,  0xf0,  0x08,  0x65,  0xfe,  0xc6,  0x18,  0x03,  0xff,  0x1a,  0x00,  0x00,
13699 };
13700
13701 STATIC unsigned short _adv_asc3550_size =
13702         sizeof(_adv_asc3550_buf); /* 0x13AD */
13703 STATIC ADV_DCNT _adv_asc3550_chksum =
13704         0x04D52DDDUL; /* Expanded little-endian checksum. */
13705
13706 /* Microcode buffer is kept after initialization for error recovery. */
13707 STATIC unsigned char _adv_asc38C0800_buf[] = {
13708   0x00,  0x00,  0x00,  0xf2,  0x00,  0xf0,  0x00,  0xfc,  0x00,  0x16,  0x18,  0xe4,  0x01,  0x00,  0x48,  0xe4,
13709   0x18,  0x80,  0x03,  0xf6,  0x02,  0x00,  0xce,  0x19,  0x00,  0xfa,  0xff,  0xff,  0x1c,  0x0f,  0x00,  0xf6,
13710   0x9e,  0xe7,  0xff,  0x00,  0x82,  0xe7,  0x00,  0xea,  0x01,  0xfa,  0x01,  0xe6,  0x09,  0xe7,  0x55,  0xf0,
13711   0x01,  0xf6,  0x03,  0x00,  0x04,  0x00,  0x10,  0x00,  0x1e,  0xf0,  0x85,  0xf0,  0x18,  0xf4,  0x08,  0x00,
13712   0xbc,  0x00,  0x38,  0x54,  0x00,  0xec,  0xd5,  0xf0,  0x82,  0x0d,  0x00,  0xe6,  0x86,  0xf0,  0xb1,  0xf0,
13713   0x98,  0x57,  0x01,  0xfc,  0xb4,  0x00,  0xd4,  0x01,  0x0c,  0x1c,  0x3e,  0x1c,  0x3c,  0x00,  0xbb,  0x00,
13714   0x00,  0x10,  0xba,  0x19,  0x02,  0x80,  0x32,  0xf0,  0x7c,  0x0d,  0x02,  0x13,  0xba,  0x13,  0x18,  0x40,
13715   0x00,  0x57,  0x01,  0xea,  0x02,  0xfc,  0x03,  0xfc,  0x3e,  0x00,  0x6c,  0x01,  0x6e,  0x01,  0x74,  0x01,
13716   0x76,  0x01,  0xb9,  0x54,  0x3e,  0x57,  0x00,  0x80,  0x03,  0xe6,  0xb6,  0x00,  0xc0,  0x00,  0x01,  0x01,
13717   0x3e,  0x01,  0x7a,  0x01,  0xca,  0x08,  0xce,  0x10,  0x16,  0x11,  0x04,  0x12,  0x08,  0x12,  0x02,  0x4a,
13718   0xbb,  0x55,  0x3c,  0x56,  0x03,  0x58,  0x1b,  0x80,  0x30,  0xe4,  0x4b,  0xe4,  0x5d,  0xf0,  0x02,  0xfa,
13719   0x20,  0x00,  0x32,  0x00,  0x40,  0x00,  0x80,  0x00,  0x24,  0x01,  0x3c,  0x01,  0x68,  0x01,  0x6a,  0x01,
13720   0x70,  0x01,  0x72,  0x01,  0x78,  0x01,  0x7c,  0x01,  0x62,  0x0a,  0x86,  0x0d,  0x06,  0x13,  0x4c,  0x1c,
13721   0x04,  0x80,  0x4a,  0xe4,  0x02,  0xee,  0x5b,  0xf0,  0x03,  0xf7,  0x0c,  0x00,  0x0f,  0x00,  0x47,  0x00,
13722   0xbe,  0x00,  0x00,  0x01,  0x20,  0x11,  0x5c,  0x16,  0x32,  0x1c,  0x38,  0x1c,  0x4e,  0x1c,  0x10,  0x44,
13723   0x00,  0x4c,  0x04,  0xea,  0x5c,  0xf0,  0xa7,  0xf0,  0x04,  0xf6,  0x03,  0xfa,  0x05,  0x00,  0x34,  0x00,
13724   0x36,  0x00,  0x98,  0x00,  0xcc,  0x00,  0x20,  0x01,  0x4e,  0x01,  0x4a,  0x0b,  0x42,  0x0c,  0x12,  0x0f,
13725   0x0c,  0x10,  0x22,  0x11,  0x0a,  0x12,  0x04,  0x13,  0x30,  0x1c,  0x02,  0x48,  0x00,  0x4e,  0x42,  0x54,
13726   0x44,  0x55,  0xbd,  0x56,  0x06,  0x83,  0x00,  0xdc,  0x05,  0xf0,  0x09,  0xf0,  0x59,  0xf0,  0xb8,  0xf0,
13727   0x4b,  0xf4,  0x06,  0xf7,  0x0e,  0xf7,  0x04,  0xfc,  0x05,  0xfc,  0x06,  0x00,  0x19,  0x00,  0x33,  0x00,
13728   0x9b,  0x00,  0xa4,  0x00,  0xb5,  0x00,  0xba,  0x00,  0xd0,  0x00,  0xe1,  0x00,  0xe7,  0x00,  0xe2,  0x03,
13729   0x08,  0x0f,  0x02,  0x10,  0x04,  0x10,  0x0a,  0x10,  0x0a,  0x13,  0x0c,  0x13,  0x12,  0x13,  0x24,  0x14,
13730   0x34,  0x14,  0x04,  0x16,  0x08,  0x16,  0xa4,  0x17,  0x20,  0x1c,  0x34,  0x1c,  0x36,  0x1c,  0x08,  0x44,
13731   0x38,  0x44,  0x91,  0x44,  0x0a,  0x45,  0x48,  0x46,  0x01,  0x48,  0x68,  0x54,  0x3a,  0x55,  0x83,  0x55,
13732   0xe5,  0x55,  0xb0,  0x57,  0x01,  0x58,  0x83,  0x59,  0x05,  0xe6,  0x0b,  0xf0,  0x0c,  0xf0,  0x04,  0xf8,
13733   0x05,  0xf8,  0x07,  0x00,  0x0a,  0x00,  0x1c,  0x00,  0x1e,  0x00,  0x9e,  0x00,  0xa8,  0x00,  0xaa,  0x00,
13734   0xb9,  0x00,  0xe0,  0x00,  0x22,  0x01,  0x26,  0x01,  0x79,  0x01,  0x7e,  0x01,  0xc4,  0x01,  0xc6,  0x01,
13735   0x80,  0x02,  0x5e,  0x03,  0xee,  0x04,  0x9a,  0x06,  0xf8,  0x07,  0x62,  0x08,  0x68,  0x08,  0x69,  0x08,
13736   0xd6,  0x08,  0xe9,  0x09,  0xfa,  0x0b,  0x2e,  0x0f,  0x12,  0x10,  0x1a,  0x10,  0xed,  0x10,  0xf1,  0x10,
13737   0x2a,  0x11,  0x06,  0x12,  0x0c,  0x12,  0x3e,  0x12,  0x10,  0x13,  0x16,  0x13,  0x1e,  0x13,  0x46,  0x14,
13738   0x76,  0x14,  0x82,  0x14,  0x36,  0x15,  0xca,  0x15,  0x6b,  0x18,  0xbe,  0x18,  0xca,  0x18,  0xe6,  0x19,
13739   0x12,  0x1c,  0x46,  0x1c,  0x9c,  0x32,  0x00,  0x40,  0x0e,  0x47,  0xfe,  0x9c,  0xf0,  0x2b,  0x02,  0xfe,
13740   0xac,  0x0d,  0xff,  0x10,  0x00,  0x00,  0xd7,  0xfe,  0xe8,  0x19,  0x00,  0xd6,  0xfe,  0x84,  0x01,  0xff,
13741   0x03,  0x00,  0x00,  0xfe,  0x93,  0x15,  0xfe,  0x0f,  0x05,  0xff,  0x38,  0x00,  0x00,  0xfe,  0x57,  0x24,
13742   0x00,  0xfe,  0x4c,  0x00,  0x5b,  0xff,  0x04,  0x00,  0x00,  0x11,  0xff,  0x09,  0x00,  0x00,  0xff,  0x08,
13743   0x01,  0x01,  0xff,  0x08,  0xff,  0xff,  0xff,  0x27,  0x00,  0x00,  0xff,  0x10,  0xff,  0xff,  0xff,  0x11,
13744   0x00,  0x00,  0xfe,  0x78,  0x56,  0xfe,  0x34,  0x12,  0xff,  0x21,  0x00,  0x00,  0xfe,  0x04,  0xf7,  0xd6,
13745   0x2c,  0x99,  0x0a,  0x01,  0xfe,  0xc2,  0x0f,  0xfe,  0x04,  0xf7,  0xd6,  0x99,  0x0a,  0x42,  0x2c,  0xfe,
13746   0x3d,  0xf0,  0xfe,  0x06,  0x02,  0xfe,  0x20,  0xf0,  0xa7,  0xfe,  0x91,  0xf0,  0xfe,  0xf4,  0x01,  0xfe,
13747   0x90,  0xf0,  0xfe,  0xf4,  0x01,  0xfe,  0x8f,  0xf0,  0xa7,  0x03,  0x5d,  0x4d,  0x02,  0xfe,  0xc8,  0x0d,
13748   0x01,  0xfe,  0x38,  0x0e,  0xfe,  0xdd,  0x12,  0xfe,  0xfc,  0x10,  0xfe,  0x28,  0x1c,  0x03,  0xfe,  0xa6,
13749   0x00,  0xfe,  0xd3,  0x12,  0x41,  0x14,  0xfe,  0xa6,  0x00,  0xc2,  0xfe,  0x48,  0xf0,  0xfe,  0x8a,  0x02,
13750   0xfe,  0x49,  0xf0,  0xfe,  0xa4,  0x02,  0xfe,  0x4a,  0xf0,  0xfe,  0xc2,  0x02,  0xfe,  0x46,  0xf0,  0xfe,
13751   0x54,  0x02,  0xfe,  0x47,  0xf0,  0xfe,  0x5a,  0x02,  0xfe,  0x43,  0xf0,  0xfe,  0x48,  0x02,  0xfe,  0x44,
13752   0xf0,  0xfe,  0x4c,  0x02,  0xfe,  0x45,  0xf0,  0xfe,  0x50,  0x02,  0x18,  0x0a,  0xaa,  0x18,  0x06,  0x14,
13753   0xa1,  0x02,  0x2b,  0xfe,  0x00,  0x1c,  0xe7,  0xfe,  0x02,  0x1c,  0xe6,  0xfe,  0x1e,  0x1c,  0xfe,  0xe9,
13754   0x10,  0x01,  0xfe,  0x18,  0x18,  0xfe,  0xe7,  0x10,  0xfe,  0x06,  0xfc,  0xce,  0x09,  0x70,  0x01,  0xa8,
13755   0x02,  0x2b,  0x15,  0x59,  0x39,  0xa2,  0x01,  0xfe,  0x58,  0x10,  0x09,  0x70,  0x01,  0x87,  0xfe,  0xbd,
13756   0x10,  0x09,  0x70,  0x01,  0x87,  0xfe,  0xad,  0x10,  0xfe,  0x16,  0x1c,  0xfe,  0x58,  0x1c,  0x18,  0x06,
13757   0x14,  0xa1,  0x2c,  0x1c,  0x2b,  0xfe,  0x3d,  0xf0,  0xfe,  0x06,  0x02,  0x23,  0xfe,  0x98,  0x02,  0xfe,
13758   0x5a,  0x1c,  0xf8,  0xfe,  0x14,  0x1c,  0x15,  0xfe,  0x30,  0x00,  0x39,  0xa2,  0x01,  0xfe,  0x48,  0x10,
13759   0x18,  0x06,  0x14,  0xa1,  0x02,  0xd7,  0x22,  0x20,  0x07,  0x11,  0x35,  0xfe,  0x69,  0x10,  0x18,  0x06,
13760   0x14,  0xa1,  0xfe,  0x04,  0xec,  0x20,  0x4f,  0x43,  0x13,  0x20,  0xfe,  0x05,  0xf6,  0xce,  0x01,  0xfe,
13761   0x4a,  0x17,  0x08,  0x54,  0x58,  0x37,  0x12,  0x2f,  0x42,  0x92,  0x01,  0xfe,  0x82,  0x16,  0x02,  0x2b,
13762   0x09,  0x46,  0x01,  0x0e,  0x07,  0x00,  0x66,  0x01,  0x73,  0xfe,  0x18,  0x10,  0xfe,  0x41,  0x58,  0x09,
13763   0xa4,  0x01,  0x0e,  0xfe,  0xc8,  0x54,  0x6b,  0xfe,  0x10,  0x03,  0x01,  0xfe,  0x82,  0x16,  0x02,  0x2b,
13764   0x2c,  0x4f,  0xfe,  0x02,  0xe8,  0x2a,  0xfe,  0xbf,  0x57,  0xfe,  0x9e,  0x43,  0xfe,  0x77,  0x57,  0xfe,
13765   0x27,  0xf0,  0xfe,  0xe0,  0x01,  0xfe,  0x07,  0x4b,  0xfe,  0x20,  0xf0,  0xa7,  0xfe,  0x40,  0x1c,  0x1c,
13766   0xd9,  0xfe,  0x26,  0xf0,  0xfe,  0x5a,  0x03,  0xfe,  0xa0,  0xf0,  0xfe,  0x48,  0x03,  0xfe,  0x11,  0xf0,
13767   0xa7,  0xfe,  0xef,  0x10,  0xfe,  0x9f,  0xf0,  0xfe,  0x68,  0x03,  0xf9,  0x10,  0xfe,  0x11,  0x00,  0x02,
13768   0x65,  0x2c,  0xfe,  0x48,  0x1c,  0xf9,  0x08,  0x05,  0x1b,  0xfe,  0x18,  0x13,  0x21,  0x22,  0xa3,  0xb7,
13769   0x13,  0xa3,  0x09,  0x46,  0x01,  0x0e,  0xb7,  0x78,  0x01,  0xfe,  0xb4,  0x16,  0x12,  0xd1,  0x1c,  0xd9,
13770   0xfe,  0x01,  0xf0,  0xd9,  0xfe,  0x82,  0xf0,  0xfe,  0x96,  0x03,  0xfa,  0x12,  0xfe,  0xe4,  0x00,  0x27,
13771   0xfe,  0xa8,  0x03,  0x1c,  0x34,  0x1d,  0xfe,  0xb8,  0x03,  0x01,  0x4b,  0xfe,  0x06,  0xf0,  0xfe,  0xc8,
13772   0x03,  0x95,  0x86,  0xfe,  0x0a,  0xf0,  0xfe,  0x8a,  0x06,  0x02,  0x24,  0x03,  0x70,  0x28,  0x17,  0xfe,
13773   0xfa,  0x04,  0x15,  0x6d,  0x01,  0x36,  0x7b,  0xfe,  0x6a,  0x02,  0x02,  0xd8,  0xf9,  0x2c,  0x99,  0x19,
13774   0xfe,  0x67,  0x1b,  0xfe,  0xbf,  0x57,  0xfe,  0x77,  0x57,  0xfe,  0x48,  0x1c,  0x74,  0x01,  0xaf,  0x8c,
13775   0x09,  0x46,  0x01,  0x0e,  0x07,  0x00,  0x17,  0xda,  0x09,  0xd1,  0x01,  0x0e,  0x8d,  0x51,  0x64,  0x79,
13776   0x2a,  0x03,  0x70,  0x28,  0xfe,  0x10,  0x12,  0x15,  0x6d,  0x01,  0x36,  0x7b,  0xfe,  0x6a,  0x02,  0x02,
13777   0xd8,  0xc7,  0x81,  0xc8,  0x83,  0x1c,  0x24,  0x27,  0xfe,  0x40,  0x04,  0x1d,  0xfe,  0x3c,  0x04,  0x3b,
13778   0xfe,  0xa0,  0x00,  0xfe,  0x9b,  0x57,  0xfe,  0x4e,  0x12,  0x2d,  0xff,  0x02,  0x00,  0x10,  0x01,  0x0b,
13779   0x1d,  0xfe,  0xe4,  0x04,  0x2d,  0x01,  0x0b,  0x1d,  0x24,  0x33,  0x31,  0xde,  0xfe,  0x4c,  0x44,  0xfe,
13780   0x4c,  0x12,  0x51,  0xfe,  0x44,  0x48,  0x0f,  0x6f,  0xfe,  0x4c,  0x54,  0x6b,  0xda,  0x4f,  0x79,  0x2a,
13781   0xfe,  0x06,  0x80,  0xfe,  0x48,  0x47,  0xfe,  0x62,  0x13,  0x08,  0x05,  0x1b,  0xfe,  0x2a,  0x13,  0x32,
13782   0x07,  0x82,  0xfe,  0x52,  0x13,  0xfe,  0x20,  0x10,  0x0f,  0x6f,  0xfe,  0x4c,  0x54,  0x6b,  0xda,  0xfe,
13783   0x06,  0x80,  0xfe,  0x48,  0x47,  0xfe,  0x40,  0x13,  0x08,  0x05,  0x1b,  0xfe,  0x08,  0x13,  0x32,  0x07,
13784   0x82,  0xfe,  0x30,  0x13,  0x08,  0x05,  0x1b,  0xfe,  0x1c,  0x12,  0x15,  0x9d,  0x08,  0x05,  0x06,  0x4d,
13785   0x15,  0xfe,  0x0d,  0x00,  0x01,  0x36,  0x7b,  0xfe,  0x64,  0x0d,  0x02,  0x24,  0x2d,  0x12,  0xfe,  0xe6,
13786   0x00,  0xfe,  0x1c,  0x90,  0xfe,  0x40,  0x5c,  0x04,  0x15,  0x9d,  0x01,  0x36,  0x02,  0x2b,  0xfe,  0x42,
13787   0x5b,  0x99,  0x19,  0xfe,  0x46,  0x59,  0xfe,  0xbf,  0x57,  0xfe,  0x77,  0x57,  0xfe,  0x87,  0x80,  0xfe,
13788   0x31,  0xe4,  0x5b,  0x08,  0x05,  0x0a,  0xfe,  0x84,  0x13,  0xfe,  0x20,  0x80,  0x07,  0x19,  0xfe,  0x7c,
13789   0x12,  0x53,  0x05,  0x06,  0xfe,  0x6c,  0x13,  0x03,  0xfe,  0xa2,  0x00,  0x28,  0x17,  0xfe,  0x90,  0x05,
13790   0xfe,  0x31,  0xe4,  0x5a,  0x53,  0x05,  0x0a,  0xfe,  0x56,  0x13,  0x03,  0xfe,  0xa0,  0x00,  0x28,  0xfe,
13791   0x4e,  0x12,  0x67,  0xff,  0x02,  0x00,  0x10,  0x27,  0xfe,  0x48,  0x05,  0x1c,  0x34,  0xfe,  0x89,  0x48,
13792   0xff,  0x02,  0x00,  0x10,  0x27,  0xfe,  0x56,  0x05,  0x26,  0xfe,  0xa8,  0x05,  0x12,  0xfe,  0xe3,  0x00,
13793   0x21,  0x53,  0xfe,  0x4a,  0xf0,  0xfe,  0x76,  0x05,  0xfe,  0x49,  0xf0,  0xfe,  0x70,  0x05,  0x88,  0x25,
13794   0xfe,  0x21,  0x00,  0xab,  0x25,  0xfe,  0x22,  0x00,  0xaa,  0x25,  0x58,  0xfe,  0x09,  0x48,  0xff,  0x02,
13795   0x00,  0x10,  0x27,  0xfe,  0x86,  0x05,  0x26,  0xfe,  0xa8,  0x05,  0xfe,  0xe2,  0x08,  0x53,  0x05,  0xcb,
13796   0x4d,  0x01,  0xb0,  0x25,  0x06,  0x13,  0xd3,  0x39,  0xfe,  0x27,  0x01,  0x08,  0x05,  0x1b,  0xfe,  0x22,
13797   0x12,  0x41,  0x01,  0xb2,  0x15,  0x9d,  0x08,  0x05,  0x06,  0x4d,  0x15,  0xfe,  0x0d,  0x00,  0x01,  0x36,
13798   0x7b,  0xfe,  0x64,  0x0d,  0x02,  0x24,  0x03,  0xfe,  0x9c,  0x00,  0x28,  0xeb,  0x03,  0x5c,  0x28,  0xfe,
13799   0x36,  0x13,  0x41,  0x01,  0xb2,  0x26,  0xfe,  0x18,  0x06,  0x09,  0x06,  0x53,  0x05,  0x1f,  0xfe,  0x02,
13800   0x12,  0x50,  0x01,  0xfe,  0x9e,  0x15,  0x1d,  0xfe,  0x0e,  0x06,  0x12,  0xa5,  0x01,  0x4b,  0x12,  0xfe,
13801   0xe5,  0x00,  0x03,  0x5c,  0xc1,  0x0c,  0x5c,  0x03,  0xcd,  0x28,  0xfe,  0x62,  0x12,  0x03,  0x45,  0x28,
13802   0xfe,  0x5a,  0x13,  0x01,  0xfe,  0x0c,  0x19,  0x01,  0xfe,  0x76,  0x19,  0xfe,  0x43,  0x48,  0xc4,  0xcc,
13803   0x0f,  0x71,  0xff,  0x02,  0x00,  0x57,  0x52,  0x93,  0x1e,  0x43,  0x8b,  0xc4,  0x6e,  0x41,  0x01,  0xb2,
13804   0x26,  0xfe,  0x82,  0x06,  0x53,  0x05,  0x1a,  0xe9,  0x91,  0x09,  0x59,  0x01,  0xfe,  0xcc,  0x15,  0x1d,
13805   0xfe,  0x78,  0x06,  0x12,  0xa5,  0x01,  0x4b,  0x12,  0xfe,  0xe5,  0x00,  0x03,  0x45,  0xc1,  0x0c,  0x45,
13806   0x18,  0x06,  0x01,  0xb2,  0xfa,  0x76,  0x74,  0x01,  0xaf,  0x8c,  0x12,  0xfe,  0xe2,  0x00,  0x27,  0xdb,
13807   0x1c,  0x34,  0xfe,  0x0a,  0xf0,  0xfe,  0xb6,  0x06,  0x94,  0xfe,  0x6c,  0x07,  0xfe,  0x06,  0xf0,  0xfe,
13808   0x74,  0x07,  0x95,  0x86,  0x02,  0x24,  0x08,  0x05,  0x0a,  0xfe,  0x2e,  0x12,  0x16,  0x19,  0x01,  0x0b,
13809   0x16,  0x00,  0x01,  0x0b,  0x16,  0x00,  0x01,  0x0b,  0x16,  0x00,  0x01,  0x0b,  0xfe,  0x99,  0xa4,  0x01,
13810   0x0b,  0x16,  0x00,  0x02,  0xfe,  0x42,  0x08,  0x68,  0x05,  0x1a,  0xfe,  0x38,  0x12,  0x08,  0x05,  0x1a,
13811   0xfe,  0x30,  0x13,  0x16,  0xfe,  0x1b,  0x00,  0x01,  0x0b,  0x16,  0x00,  0x01,  0x0b,  0x16,  0x00,  0x01,
13812   0x0b,  0x16,  0x00,  0x01,  0x0b,  0x16,  0x06,  0x01,  0x0b,  0x16,  0x00,  0x02,  0xe2,  0x6c,  0x58,  0xbe,
13813   0x50,  0xfe,  0x9a,  0x81,  0x55,  0x1b,  0x7a,  0xfe,  0x42,  0x07,  0x09,  0x1b,  0xfe,  0x09,  0x6f,  0xba,
13814   0xfe,  0xca,  0x45,  0xfe,  0x32,  0x12,  0x69,  0x6d,  0x8b,  0x6c,  0x7f,  0x27,  0xfe,  0x54,  0x07,  0x1c,
13815   0x34,  0xfe,  0x0a,  0xf0,  0xfe,  0x42,  0x07,  0x95,  0x86,  0x94,  0xfe,  0x6c,  0x07,  0x02,  0x24,  0x01,
13816   0x4b,  0x02,  0xdb,  0x16,  0x1f,  0x02,  0xdb,  0xfe,  0x9c,  0xf7,  0xdc,  0xfe,  0x2c,  0x90,  0xfe,  0xae,
13817   0x90,  0x56,  0xfe,  0xda,  0x07,  0x0c,  0x60,  0x14,  0x61,  0x08,  0x54,  0x5a,  0x37,  0x22,  0x20,  0x07,
13818   0x11,  0xfe,  0x0e,  0x12,  0x8d,  0xfe,  0x80,  0x80,  0x39,  0x20,  0x6a,  0x2a,  0xfe,  0x06,  0x10,  0xfe,
13819   0x83,  0xe7,  0xfe,  0x48,  0x00,  0xab,  0xfe,  0x03,  0x40,  0x08,  0x54,  0x5b,  0x37,  0x01,  0xb3,  0xb8,
13820   0xfe,  0x1f,  0x40,  0x13,  0x62,  0x01,  0xef,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0xfe,  0x44,  0x51,
13821   0xfe,  0xc6,  0x51,  0x88,  0xfe,  0x08,  0x90,  0xfe,  0x8a,  0x90,  0x0c,  0x5e,  0x14,  0x5f,  0xfe,  0x0c,
13822   0x90,  0xfe,  0x8e,  0x90,  0xfe,  0x40,  0x50,  0xfe,  0xc2,  0x50,  0x0c,  0x3d,  0x14,  0x3e,  0xfe,  0x4a,
13823   0x10,  0x08,  0x05,  0x5a,  0xfe,  0x2a,  0x12,  0xfe,  0x2c,  0x90,  0xfe,  0xae,  0x90,  0x0c,  0x60,  0x14,
13824   0x61,  0x08,  0x05,  0x5b,  0x8b,  0x01,  0xb3,  0xfe,  0x1f,  0x80,  0x13,  0x62,  0xfe,  0x44,  0x90,  0xfe,
13825   0xc6,  0x90,  0x0c,  0x3f,  0x14,  0x40,  0xfe,  0x08,  0x90,  0xfe,  0x8a,  0x90,  0x0c,  0x5e,  0x14,  0x5f,
13826   0xfe,  0x40,  0x90,  0xfe,  0xc2,  0x90,  0x0c,  0x3d,  0x14,  0x3e,  0x0c,  0x2e,  0x14,  0x3c,  0x21,  0x0c,
13827   0x49,  0x0c,  0x63,  0x08,  0x54,  0x1f,  0x37,  0x2c,  0x0f,  0xfe,  0x4e,  0x11,  0x27,  0xdd,  0xfe,  0x9e,
13828   0xf0,  0xfe,  0x76,  0x08,  0xbc,  0x17,  0x34,  0x2c,  0x77,  0xe6,  0xc5,  0xfe,  0x9a,  0x08,  0xc6,  0xfe,
13829   0xb8,  0x08,  0x94,  0xfe,  0x8e,  0x08,  0xfe,  0x06,  0xf0,  0xfe,  0x94,  0x08,  0x95,  0x86,  0x02,  0x24,
13830   0x01,  0x4b,  0xfe,  0xc9,  0x10,  0x16,  0x1f,  0xfe,  0xc9,  0x10,  0x68,  0x05,  0x06,  0xfe,  0x10,  0x12,
13831   0x68,  0x05,  0x0a,  0x4e,  0x08,  0x05,  0x0a,  0xfe,  0x90,  0x12,  0xfe,  0x2e,  0x1c,  0x02,  0xfe,  0x18,
13832   0x0b,  0x68,  0x05,  0x06,  0x4e,  0x68,  0x05,  0x0a,  0xfe,  0x7a,  0x12,  0xfe,  0x2c,  0x1c,  0xfe,  0xaa,
13833   0xf0,  0xfe,  0xd2,  0x09,  0xfe,  0xac,  0xf0,  0xfe,  0x00,  0x09,  0x02,  0xfe,  0xde,  0x09,  0xfe,  0xb7,
13834   0xf0,  0xfe,  0xfc,  0x08,  0xfe,  0x02,  0xf6,  0x1a,  0x50,  0xfe,  0x70,  0x18,  0xfe,  0xf1,  0x18,  0xfe,
13835   0x40,  0x55,  0xfe,  0xe1,  0x55,  0xfe,  0x10,  0x58,  0xfe,  0x91,  0x58,  0xfe,  0x14,  0x59,  0xfe,  0x95,
13836   0x59,  0x1c,  0x85,  0xfe,  0x8c,  0xf0,  0xfe,  0xfc,  0x08,  0xfe,  0xac,  0xf0,  0xfe,  0xf0,  0x08,  0xb5,
13837   0xfe,  0xcb,  0x10,  0xfe,  0xad,  0xf0,  0xfe,  0x0c,  0x09,  0x02,  0xfe,  0x18,  0x0b,  0xb6,  0xfe,  0xbf,
13838   0x10,  0xfe,  0x2b,  0xf0,  0x85,  0xf4,  0x1e,  0xfe,  0x00,  0xfe,  0xfe,  0x1c,  0x12,  0xc2,  0xfe,  0xd2,
13839   0xf0,  0x85,  0xfe,  0x76,  0x18,  0x1e,  0x19,  0x17,  0x85,  0x03,  0xd2,  0x1e,  0x06,  0x17,  0x85,  0xc5,
13840   0x4a,  0xc6,  0x4a,  0xb5,  0xb6,  0xfe,  0x89,  0x10,  0x74,  0x67,  0x2d,  0x15,  0x9d,  0x01,  0x36,  0x10,
13841   0xfe,  0x35,  0x00,  0xfe,  0x01,  0xf0,  0x65,  0x10,  0x80,  0x02,  0x65,  0xfe,  0x98,  0x80,  0xfe,  0x19,
13842   0xe4,  0x0a,  0xfe,  0x1a,  0x12,  0x51,  0xfe,  0x19,  0x82,  0xfe,  0x6c,  0x18,  0xfe,  0x44,  0x54,  0xbe,
13843   0xfe,  0x19,  0x81,  0xfe,  0x74,  0x18,  0x8f,  0x90,  0x17,  0xfe,  0xce,  0x08,  0x02,  0x4a,  0x08,  0x05,
13844   0x5a,  0xec,  0x03,  0x2e,  0x29,  0x3c,  0x0c,  0x3f,  0x14,  0x40,  0x9b,  0x2e,  0x9c,  0x3c,  0xfe,  0x6c,
13845   0x18,  0xfe,  0xed,  0x18,  0xfe,  0x44,  0x54,  0xfe,  0xe5,  0x54,  0x3a,  0x3f,  0x3b,  0x40,  0x03,  0x49,
13846   0x29,  0x63,  0x8f,  0xfe,  0xe3,  0x54,  0xfe,  0x74,  0x18,  0xfe,  0xf5,  0x18,  0x8f,  0xfe,  0xe3,  0x54,
13847   0x90,  0xc0,  0x56,  0xfe,  0xce,  0x08,  0x02,  0x4a,  0xfe,  0x37,  0xf0,  0xfe,  0xda,  0x09,  0xfe,  0x8b,
13848   0xf0,  0xfe,  0x60,  0x09,  0x02,  0x4a,  0x08,  0x05,  0x0a,  0x23,  0xfe,  0xfa,  0x0a,  0x3a,  0x49,  0x3b,
13849   0x63,  0x56,  0xfe,  0x3e,  0x0a,  0x0f,  0xfe,  0xc0,  0x07,  0x41,  0x98,  0x00,  0xad,  0xfe,  0x01,  0x59,
13850   0xfe,  0x52,  0xf0,  0xfe,  0x0c,  0x0a,  0x8f,  0x7a,  0xfe,  0x24,  0x0a,  0x3a,  0x49,  0x8f,  0xfe,  0xe3,
13851   0x54,  0x57,  0x49,  0x7d,  0x63,  0xfe,  0x14,  0x58,  0xfe,  0x95,  0x58,  0x02,  0x4a,  0x3a,  0x49,  0x3b,
13852   0x63,  0xfe,  0x14,  0x59,  0xfe,  0x95,  0x59,  0xbe,  0x57,  0x49,  0x57,  0x63,  0x02,  0x4a,  0x08,  0x05,
13853   0x5a,  0xfe,  0x82,  0x12,  0x08,  0x05,  0x1f,  0xfe,  0x66,  0x13,  0x22,  0x62,  0xb7,  0xfe,  0x03,  0xa1,
13854   0xfe,  0x83,  0x80,  0xfe,  0xc8,  0x44,  0xfe,  0x2e,  0x13,  0xfe,  0x04,  0x91,  0xfe,  0x86,  0x91,  0x6a,
13855   0x2a,  0xfe,  0x40,  0x59,  0xfe,  0xc1,  0x59,  0x56,  0xe0,  0x03,  0x60,  0x29,  0x61,  0x0c,  0x7f,  0x14,
13856   0x80,  0x57,  0x60,  0x7d,  0x61,  0x01,  0xb3,  0xb8,  0x6a,  0x2a,  0x13,  0x62,  0x9b,  0x2e,  0x9c,  0x3c,
13857   0x3a,  0x3f,  0x3b,  0x40,  0x90,  0xc0,  0xfe,  0x04,  0xfa,  0x2e,  0xfe,  0x05,  0xfa,  0x3c,  0x01,  0xef,
13858   0xfe,  0x36,  0x10,  0x21,  0x0c,  0x7f,  0x0c,  0x80,  0x3a,  0x3f,  0x3b,  0x40,  0xe4,  0x08,  0x05,  0x1f,
13859   0x17,  0xe0,  0x3a,  0x3d,  0x3b,  0x3e,  0x08,  0x05,  0xfe,  0xf7,  0x00,  0x37,  0x03,  0x5e,  0x29,  0x5f,
13860   0xfe,  0x10,  0x58,  0xfe,  0x91,  0x58,  0x57,  0x49,  0x7d,  0x63,  0x02,  0xfe,  0xf4,  0x09,  0x08,  0x05,
13861   0x1f,  0x17,  0xe0,  0x08,  0x05,  0xfe,  0xf7,  0x00,  0x37,  0xbe,  0xfe,  0x19,  0x81,  0x50,  0xfe,  0x10,
13862   0x90,  0xfe,  0x92,  0x90,  0xfe,  0xd3,  0x10,  0x32,  0x07,  0xa6,  0x17,  0xfe,  0x08,  0x09,  0x12,  0xa6,
13863   0x08,  0x05,  0x0a,  0xfe,  0x14,  0x13,  0x03,  0x3d,  0x29,  0x3e,  0x56,  0xfe,  0x08,  0x09,  0xfe,  0x0c,
13864   0x58,  0xfe,  0x8d,  0x58,  0x02,  0x4a,  0x21,  0x41,  0xfe,  0x19,  0x80,  0xe7,  0x08,  0x05,  0x0a,  0xfe,
13865   0x1a,  0x12,  0xfe,  0x6c,  0x19,  0xfe,  0x19,  0x41,  0xf4,  0xc2,  0xfe,  0xd1,  0xf0,  0xe2,  0x15,  0x7e,
13866   0x01,  0x36,  0x10,  0xfe,  0x44,  0x00,  0xfe,  0x8e,  0x10,  0xfe,  0x6c,  0x19,  0x57,  0x3d,  0xfe,  0xed,
13867   0x19,  0x7d,  0x3e,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0xf4,  0x1e,  0xfe,  0x00,  0xff,  0x35,  0xfe,
13868   0x74,  0x10,  0xc2,  0xfe,  0xd2,  0xf0,  0xfe,  0xa6,  0x0b,  0xfe,  0x76,  0x18,  0x1e,  0x19,  0x8a,  0x03,
13869   0xd2,  0x1e,  0x06,  0xfe,  0x08,  0x13,  0x10,  0xfe,  0x16,  0x00,  0x02,  0x65,  0xfe,  0xd1,  0xf0,  0xfe,
13870   0xb8,  0x0b,  0x15,  0x7e,  0x01,  0x36,  0x10,  0xfe,  0x17,  0x00,  0xfe,  0x42,  0x10,  0xfe,  0xce,  0xf0,
13871   0xfe,  0xbe,  0x0b,  0xfe,  0x3c,  0x10,  0xfe,  0xcd,  0xf0,  0xfe,  0xca,  0x0b,  0x10,  0xfe,  0x22,  0x00,
13872   0x02,  0x65,  0xfe,  0xcb,  0xf0,  0xfe,  0xd6,  0x0b,  0x10,  0xfe,  0x24,  0x00,  0x02,  0x65,  0xfe,  0xd0,
13873   0xf0,  0xfe,  0xe0,  0x0b,  0x10,  0x9e,  0xe5,  0xfe,  0xcf,  0xf0,  0xfe,  0xea,  0x0b,  0x10,  0x58,  0xfe,
13874   0x10,  0x10,  0xfe,  0xcc,  0xf0,  0xe2,  0x68,  0x05,  0x1f,  0x4d,  0x10,  0xfe,  0x12,  0x00,  0x2c,  0x0f,
13875   0xfe,  0x4e,  0x11,  0x27,  0xfe,  0x00,  0x0c,  0xfe,  0x9e,  0xf0,  0xfe,  0x14,  0x0c,  0xbc,  0x17,  0x34,
13876   0x2c,  0x77,  0xe6,  0xc5,  0x24,  0xc6,  0x24,  0x2c,  0xfa,  0x27,  0xfe,  0x20,  0x0c,  0x1c,  0x34,  0x94,
13877   0xfe,  0x3c,  0x0c,  0x95,  0x86,  0xc5,  0xdc,  0xc6,  0xdc,  0x02,  0x24,  0x01,  0x4b,  0xfe,  0xdb,  0x10,
13878   0x12,  0xfe,  0xe8,  0x00,  0xb5,  0xb6,  0x74,  0xc7,  0x81,  0xc8,  0x83,  0xfe,  0x89,  0xf0,  0x24,  0x33,
13879   0x31,  0xe1,  0xc7,  0x81,  0xc8,  0x83,  0x27,  0xfe,  0x66,  0x0c,  0x1d,  0x24,  0x33,  0x31,  0xdf,  0xbc,
13880   0x4e,  0x10,  0xfe,  0x42,  0x00,  0x02,  0x65,  0x7c,  0x06,  0xfe,  0x81,  0x49,  0x17,  0xfe,  0x2c,  0x0d,
13881   0x08,  0x05,  0x0a,  0xfe,  0x44,  0x13,  0x10,  0x00,  0x55,  0x0a,  0xfe,  0x54,  0x12,  0x55,  0xfe,  0x28,
13882   0x00,  0x23,  0xfe,  0x9a,  0x0d,  0x09,  0x46,  0x01,  0x0e,  0x07,  0x00,  0x66,  0x44,  0xfe,  0x28,  0x00,
13883   0xfe,  0xe2,  0x10,  0x01,  0xf5,  0x01,  0xf6,  0x09,  0xa4,  0x01,  0xfe,  0x26,  0x0f,  0x64,  0x12,  0x2f,
13884   0x01,  0x73,  0x02,  0x2b,  0x10,  0xfe,  0x44,  0x00,  0x55,  0x0a,  0xe9,  0x44,  0x0a,  0xfe,  0xb4,  0x10,
13885   0x01,  0xb0,  0x44,  0x0a,  0xfe,  0xaa,  0x10,  0x01,  0xb0,  0xfe,  0x19,  0x82,  0xfe,  0x34,  0x46,  0xac,
13886   0x44,  0x0a,  0x10,  0xfe,  0x43,  0x00,  0xfe,  0x96,  0x10,  0x08,  0x54,  0x0a,  0x37,  0x01,  0xf5,  0x01,
13887   0xf6,  0x64,  0x12,  0x2f,  0x01,  0x73,  0x99,  0x0a,  0x64,  0x42,  0x92,  0x02,  0xfe,  0x2e,  0x03,  0x08,
13888   0x05,  0x0a,  0x8a,  0x44,  0x0a,  0x10,  0x00,  0xfe,  0x5c,  0x10,  0x68,  0x05,  0x1a,  0xfe,  0x58,  0x12,
13889   0x08,  0x05,  0x1a,  0xfe,  0x50,  0x13,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x50,  0x0d,  0xfe,
13890   0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x56,  0x0d,  0x08,  0x54,  0x1a,  0x37,  0xfe,  0xa9,  0x10,  0x10,
13891   0xfe,  0x15,  0x00,  0xfe,  0x04,  0xe6,  0x0a,  0x50,  0xfe,  0x2e,  0x10,  0x10,  0xfe,  0x13,  0x00,  0xfe,
13892   0x10,  0x10,  0x10,  0x6f,  0xab,  0x10,  0xfe,  0x41,  0x00,  0xaa,  0x10,  0xfe,  0x24,  0x00,  0x8c,  0xb5,
13893   0xb6,  0x74,  0x03,  0x70,  0x28,  0x23,  0xd8,  0x50,  0xfe,  0x04,  0xe6,  0x1a,  0xfe,  0x9d,  0x41,  0xfe,
13894   0x1c,  0x42,  0x64,  0x01,  0xe3,  0x02,  0x2b,  0xf8,  0x15,  0x0a,  0x39,  0xa0,  0xb4,  0x15,  0xfe,  0x31,
13895   0x00,  0x39,  0xa2,  0x01,  0xfe,  0x48,  0x10,  0x02,  0xd7,  0x42,  0xfe,  0x06,  0xec,  0xd0,  0xfc,  0x44,
13896   0x1b,  0xfe,  0xce,  0x45,  0x35,  0x42,  0xfe,  0x06,  0xea,  0xd0,  0xfe,  0x47,  0x4b,  0x91,  0xfe,  0x75,
13897   0x57,  0x03,  0x5d,  0xfe,  0x98,  0x56,  0xfe,  0x38,  0x12,  0x09,  0x48,  0x01,  0x0e,  0xfe,  0x44,  0x48,
13898   0x4f,  0x08,  0x05,  0x1b,  0xfe,  0x1a,  0x13,  0x09,  0x46,  0x01,  0x0e,  0x41,  0xfe,  0x41,  0x58,  0x09,
13899   0xa4,  0x01,  0x0e,  0xfe,  0x49,  0x54,  0x96,  0xfe,  0x1e,  0x0e,  0x02,  0xfe,  0x2e,  0x03,  0x09,  0x5d,
13900   0xfe,  0xee,  0x14,  0xfc,  0x44,  0x1b,  0xfe,  0xce,  0x45,  0x35,  0x42,  0xfe,  0xce,  0x47,  0xfe,  0xad,
13901   0x13,  0x02,  0x2b,  0x22,  0x20,  0x07,  0x11,  0xfe,  0x9e,  0x12,  0x21,  0x13,  0x59,  0x13,  0x9f,  0x13,
13902   0xd5,  0x22,  0x2f,  0x41,  0x39,  0x2f,  0xbc,  0xad,  0xfe,  0xbc,  0xf0,  0xfe,  0xe0,  0x0e,  0x0f,  0x06,
13903   0x13,  0x59,  0x01,  0xfe,  0xda,  0x16,  0x03,  0xfe,  0x38,  0x01,  0x29,  0xfe,  0x3a,  0x01,  0x56,  0xfe,
13904   0xe4,  0x0e,  0xfe,  0x02,  0xec,  0xd5,  0x69,  0x00,  0x66,  0xfe,  0x04,  0xec,  0x20,  0x4f,  0xfe,  0x05,
13905   0xf6,  0xfe,  0x34,  0x01,  0x01,  0xfe,  0x4a,  0x17,  0xfe,  0x08,  0x90,  0xfe,  0x48,  0xf4,  0x0d,  0xfe,
13906   0x18,  0x13,  0xba,  0xfe,  0x02,  0xea,  0xd5,  0x69,  0x7e,  0xfe,  0xc5,  0x13,  0x15,  0x1a,  0x39,  0xa0,
13907   0xb4,  0xfe,  0x2e,  0x10,  0x03,  0xfe,  0x38,  0x01,  0x1e,  0xfe,  0xf0,  0xff,  0x0c,  0xfe,  0x60,  0x01,
13908   0x03,  0xfe,  0x3a,  0x01,  0x0c,  0xfe,  0x62,  0x01,  0x43,  0x13,  0x20,  0x25,  0x06,  0x13,  0x2f,  0x12,
13909   0x2f,  0x92,  0x0f,  0x06,  0x04,  0x21,  0x04,  0x22,  0x59,  0xfe,  0xf7,  0x12,  0x22,  0x9f,  0xb7,  0x13,
13910   0x9f,  0x07,  0x7e,  0xfe,  0x71,  0x13,  0xfe,  0x24,  0x1c,  0x15,  0x19,  0x39,  0xa0,  0xb4,  0xfe,  0xd9,
13911   0x10,  0xc3,  0xfe,  0x03,  0xdc,  0xfe,  0x73,  0x57,  0xfe,  0x80,  0x5d,  0x04,  0xc3,  0xfe,  0x03,  0xdc,
13912   0xfe,  0x5b,  0x57,  0xfe,  0x80,  0x5d,  0x04,  0xfe,  0x03,  0x57,  0xc3,  0x21,  0xfe,  0x00,  0xcc,  0x04,
13913   0xfe,  0x03,  0x57,  0xc3,  0x78,  0x04,  0x08,  0x05,  0x58,  0xfe,  0x22,  0x13,  0xfe,  0x1c,  0x80,  0x07,
13914   0x06,  0xfe,  0x1a,  0x13,  0xfe,  0x1e,  0x80,  0xed,  0xfe,  0x1d,  0x80,  0xae,  0xfe,  0x0c,  0x90,  0xfe,
13915   0x0e,  0x13,  0xfe,  0x0e,  0x90,  0xac,  0xfe,  0x3c,  0x90,  0xfe,  0x30,  0xf4,  0x0a,  0xfe,  0x3c,  0x50,
13916   0xaa,  0x01,  0xfe,  0x7a,  0x17,  0x32,  0x07,  0x2f,  0xad,  0x01,  0xfe,  0xb4,  0x16,  0x08,  0x05,  0x1b,
13917   0x4e,  0x01,  0xf5,  0x01,  0xf6,  0x12,  0xfe,  0xe9,  0x00,  0x08,  0x05,  0x58,  0xfe,  0x2c,  0x13,  0x01,
13918   0xfe,  0x0c,  0x17,  0xfe,  0x1e,  0x1c,  0xfe,  0x14,  0x90,  0xfe,  0x96,  0x90,  0x0c,  0xfe,  0x64,  0x01,
13919   0x14,  0xfe,  0x66,  0x01,  0x08,  0x05,  0x5b,  0xfe,  0x12,  0x12,  0xfe,  0x03,  0x80,  0x8d,  0xfe,  0x01,
13920   0xec,  0x20,  0xfe,  0x80,  0x40,  0x13,  0x20,  0x6a,  0x2a,  0x12,  0xcf,  0x64,  0x22,  0x20,  0xfb,  0x79,
13921   0x20,  0x04,  0xfe,  0x08,  0x1c,  0x03,  0xfe,  0xac,  0x00,  0xfe,  0x06,  0x58,  0x03,  0xfe,  0xae,  0x00,
13922
13923   0xfe,  0x07,  0x58,  0x03,  0xfe,  0xb0,  0x00,  0xfe,  0x08,  0x58,  0x03,  0xfe,  0xb2,  0x00,  0xfe,  0x09,
13924   0x58,  0xfe,  0x0a,  0x1c,  0x25,  0x6e,  0x13,  0xd0,  0x21,  0x0c,  0x5c,  0x0c,  0x45,  0x0f,  0x46,  0x52,
13925   0x50,  0x18,  0x1b,  0xfe,  0x90,  0x4d,  0xfe,  0x91,  0x54,  0x23,  0xfe,  0xfc,  0x0f,  0x44,  0x11,  0x0f,
13926   0x48,  0x52,  0x18,  0x58,  0xfe,  0x90,  0x4d,  0xfe,  0x91,  0x54,  0x23,  0xe4,  0x25,  0x11,  0x13,  0x20,
13927   0x7c,  0x6f,  0x4f,  0x22,  0x20,  0xfb,  0x79,  0x20,  0x12,  0xcf,  0xfe,  0x14,  0x56,  0xfe,  0xd6,  0xf0,
13928   0xfe,  0x26,  0x10,  0xf8,  0x74,  0xfe,  0x14,  0x1c,  0xfe,  0x10,  0x1c,  0xfe,  0x18,  0x1c,  0x04,  0x42,
13929   0xfe,  0x0c,  0x14,  0xfc,  0xfe,  0x07,  0xe6,  0x1b,  0xfe,  0xce,  0x47,  0xfe,  0xf5,  0x13,  0x04,  0x01,
13930   0xb0,  0x7c,  0x6f,  0x4f,  0xfe,  0x06,  0x80,  0xfe,  0x48,  0x47,  0xfe,  0x42,  0x13,  0x32,  0x07,  0x2f,
13931   0xfe,  0x34,  0x13,  0x09,  0x48,  0x01,  0x0e,  0xbb,  0xfe,  0x36,  0x12,  0xfe,  0x41,  0x48,  0xfe,  0x45,
13932   0x48,  0x01,  0xf0,  0xfe,  0x00,  0xcc,  0xbb,  0xfe,  0xf3,  0x13,  0x43,  0x78,  0x07,  0x11,  0xac,  0x09,
13933   0x84,  0x01,  0x0e,  0xfe,  0x80,  0x5c,  0x01,  0x73,  0xfe,  0x0e,  0x10,  0x07,  0x82,  0x4e,  0xfe,  0x14,
13934   0x56,  0xfe,  0xd6,  0xf0,  0xfe,  0x60,  0x10,  0x04,  0xfe,  0x44,  0x58,  0x8d,  0xfe,  0x01,  0xec,  0xa2,
13935   0xfe,  0x9e,  0x40,  0xfe,  0x9d,  0xe7,  0x00,  0xfe,  0x9c,  0xe7,  0x1a,  0x79,  0x2a,  0x01,  0xe3,  0xfe,
13936   0xdd,  0x10,  0x2c,  0xc7,  0x81,  0xc8,  0x83,  0x33,  0x31,  0xde,  0x07,  0x1a,  0xfe,  0x48,  0x12,  0x07,
13937   0x0a,  0xfe,  0x56,  0x12,  0x07,  0x19,  0xfe,  0x30,  0x12,  0x07,  0xc9,  0x17,  0xfe,  0x32,  0x12,  0x07,
13938   0xfe,  0x23,  0x00,  0x17,  0xeb,  0x07,  0x06,  0x17,  0xfe,  0x9c,  0x12,  0x07,  0x1f,  0xfe,  0x12,  0x12,
13939   0x07,  0x00,  0x17,  0x24,  0x15,  0xc9,  0x01,  0x36,  0xa9,  0x2d,  0x01,  0x0b,  0x94,  0x4b,  0x04,  0x2d,
13940   0xdd,  0x09,  0xd1,  0x01,  0xfe,  0x26,  0x0f,  0x12,  0x82,  0x02,  0x2b,  0x2d,  0x32,  0x07,  0xa6,  0xfe,
13941   0xd9,  0x13,  0x3a,  0x3d,  0x3b,  0x3e,  0x56,  0xfe,  0xf0,  0x11,  0x08,  0x05,  0x5a,  0xfe,  0x72,  0x12,
13942   0x9b,  0x2e,  0x9c,  0x3c,  0x90,  0xc0,  0x96,  0xfe,  0xba,  0x11,  0x22,  0x62,  0xfe,  0x26,  0x13,  0x03,
13943   0x7f,  0x29,  0x80,  0x56,  0xfe,  0x76,  0x0d,  0x0c,  0x60,  0x14,  0x61,  0x21,  0x0c,  0x7f,  0x0c,  0x80,
13944   0x01,  0xb3,  0x25,  0x6e,  0x77,  0x13,  0x62,  0x01,  0xef,  0x9b,  0x2e,  0x9c,  0x3c,  0xfe,  0x04,  0x55,
13945   0xfe,  0xa5,  0x55,  0xfe,  0x04,  0xfa,  0x2e,  0xfe,  0x05,  0xfa,  0x3c,  0xfe,  0x91,  0x10,  0x03,  0x3f,
13946   0x29,  0x40,  0xfe,  0x40,  0x56,  0xfe,  0xe1,  0x56,  0x0c,  0x3f,  0x14,  0x40,  0x88,  0x9b,  0x2e,  0x9c,
13947   0x3c,  0x90,  0xc0,  0x03,  0x5e,  0x29,  0x5f,  0xfe,  0x00,  0x56,  0xfe,  0xa1,  0x56,  0x0c,  0x5e,  0x14,
13948   0x5f,  0x08,  0x05,  0x5a,  0xfe,  0x1e,  0x12,  0x22,  0x62,  0xfe,  0x1f,  0x40,  0x03,  0x60,  0x29,  0x61,
13949   0xfe,  0x2c,  0x50,  0xfe,  0xae,  0x50,  0x03,  0x3f,  0x29,  0x40,  0xfe,  0x44,  0x50,  0xfe,  0xc6,  0x50,
13950   0x03,  0x5e,  0x29,  0x5f,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0x03,  0x3d,  0x29,  0x3e,  0xfe,  0x40,
13951   0x50,  0xfe,  0xc2,  0x50,  0x02,  0x89,  0x25,  0x06,  0x13,  0xd4,  0x02,  0x72,  0x2d,  0x01,  0x0b,  0x1d,
13952   0x4c,  0x33,  0x31,  0xde,  0x07,  0x06,  0x23,  0x4c,  0x32,  0x07,  0xa6,  0x23,  0x72,  0x01,  0xaf,  0x1e,
13953   0x43,  0x17,  0x4c,  0x08,  0x05,  0x0a,  0xee,  0x3a,  0x3d,  0x3b,  0x3e,  0xfe,  0x0a,  0x55,  0x35,  0xfe,
13954   0x8b,  0x55,  0x57,  0x3d,  0x7d,  0x3e,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0x02,  0x72,  0xfe,  0x19,
13955   0x81,  0xba,  0xfe,  0x19,  0x41,  0x02,  0x72,  0x2d,  0x01,  0x0b,  0x1c,  0x34,  0x1d,  0xe8,  0x33,  0x31,
13956   0xe1,  0x55,  0x19,  0xfe,  0xa6,  0x12,  0x55,  0x0a,  0x4d,  0x02,  0x4c,  0x01,  0x0b,  0x1c,  0x34,  0x1d,
13957   0xe8,  0x33,  0x31,  0xdf,  0x07,  0x19,  0x23,  0x4c,  0x01,  0x0b,  0x1d,  0xe8,  0x33,  0x31,  0xfe,  0xe8,
13958   0x09,  0xfe,  0xc2,  0x49,  0x51,  0x03,  0xfe,  0x9c,  0x00,  0x28,  0x8a,  0x53,  0x05,  0x1f,  0x35,  0xa9,
13959   0xfe,  0xbb,  0x45,  0x55,  0x00,  0x4e,  0x44,  0x06,  0x7c,  0x43,  0xfe,  0xda,  0x14,  0x01,  0xaf,  0x8c,
13960   0xfe,  0x4b,  0x45,  0xee,  0x32,  0x07,  0xa5,  0xed,  0x03,  0xcd,  0x28,  0x8a,  0x03,  0x45,  0x28,  0x35,
13961   0x67,  0x02,  0x72,  0xfe,  0xc0,  0x5d,  0xfe,  0xf8,  0x14,  0xfe,  0x03,  0x17,  0x03,  0x5c,  0xc1,  0x0c,
13962   0x5c,  0x67,  0x2d,  0x01,  0x0b,  0x26,  0x89,  0x01,  0xfe,  0x9e,  0x15,  0x02,  0x89,  0x01,  0x0b,  0x1c,
13963   0x34,  0x1d,  0x4c,  0x33,  0x31,  0xdf,  0x07,  0x06,  0x23,  0x4c,  0x01,  0xf1,  0xfe,  0x42,  0x58,  0xf1,
13964   0xfe,  0xa4,  0x14,  0x8c,  0xfe,  0x4a,  0xf4,  0x0a,  0x17,  0x4c,  0xfe,  0x4a,  0xf4,  0x06,  0xea,  0x32,
13965   0x07,  0xa5,  0x8b,  0x02,  0x72,  0x03,  0x45,  0xc1,  0x0c,  0x45,  0x67,  0x2d,  0x01,  0x0b,  0x26,  0x89,
13966   0x01,  0xfe,  0xcc,  0x15,  0x02,  0x89,  0x0f,  0x06,  0x27,  0xfe,  0xbe,  0x13,  0x26,  0xfe,  0xd4,  0x13,
13967   0x76,  0xfe,  0x89,  0x48,  0x01,  0x0b,  0x21,  0x76,  0x04,  0x7b,  0xfe,  0xd0,  0x13,  0x1c,  0xfe,  0xd0,
13968   0x13,  0x1d,  0xfe,  0xbe,  0x13,  0x67,  0x2d,  0x01,  0x0b,  0xfe,  0xd5,  0x10,  0x0f,  0x71,  0xff,  0x02,
13969   0x00,  0x57,  0x52,  0x93,  0x1e,  0xfe,  0xff,  0x7f,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x04,  0x0f,
13970   0x71,  0xff,  0x02,  0x00,  0x57,  0x52,  0x93,  0x1e,  0x43,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x04,
13971   0x0f,  0x71,  0xff,  0x02,  0x00,  0x57,  0x52,  0x93,  0x04,  0x0f,  0x71,  0xff,  0x02,  0x00,  0x57,  0x52,
13972   0x93,  0xfe,  0x0b,  0x58,  0x04,  0x09,  0x5c,  0x01,  0x87,  0x09,  0x45,  0x01,  0x87,  0x04,  0xfe,  0x03,
13973   0xa1,  0x1e,  0x11,  0xff,  0x03,  0x00,  0x54,  0xfe,  0x00,  0xf4,  0x1f,  0x52,  0xfe,  0x00,  0x7d,  0xfe,
13974   0x01,  0x7d,  0xfe,  0x02,  0x7d,  0xfe,  0x03,  0x7c,  0x6a,  0x2a,  0x0c,  0x5e,  0x14,  0x5f,  0x57,  0x3f,
13975   0x7d,  0x40,  0x04,  0xdd,  0xfe,  0x82,  0x4a,  0xfe,  0xe1,  0x1a,  0xfe,  0x83,  0x5a,  0x8d,  0x04,  0x01,
13976   0xfe,  0x0c,  0x19,  0xfe,  0x42,  0x48,  0x50,  0x51,  0x91,  0x01,  0x0b,  0x1d,  0xfe,  0x96,  0x15,  0x33,
13977   0x31,  0xe1,  0x01,  0x0b,  0x1d,  0xfe,  0x96,  0x15,  0x33,  0x31,  0xfe,  0xe8,  0x0a,  0xfe,  0xc1,  0x59,
13978   0x03,  0xcd,  0x28,  0xfe,  0xcc,  0x12,  0x53,  0x05,  0x1a,  0xfe,  0xc4,  0x13,  0x21,  0x69,  0x1a,  0xee,
13979   0x55,  0xca,  0x6b,  0xfe,  0xdc,  0x14,  0x4d,  0x0f,  0x06,  0x18,  0xca,  0x7c,  0x30,  0xfe,  0x78,  0x10,
13980   0xff,  0x02,  0x83,  0x55,  0xab,  0xff,  0x02,  0x83,  0x55,  0x69,  0x19,  0xae,  0x98,  0xfe,  0x30,  0x00,
13981   0x96,  0xf2,  0x18,  0x6d,  0x0f,  0x06,  0xfe,  0x56,  0x10,  0x69,  0x0a,  0xed,  0x98,  0xfe,  0x64,  0x00,
13982   0x96,  0xf2,  0x09,  0xfe,  0x64,  0x00,  0x18,  0x9e,  0x0f,  0x06,  0xfe,  0x28,  0x10,  0x69,  0x06,  0xfe,
13983   0x60,  0x13,  0x98,  0xfe,  0xc8,  0x00,  0x96,  0xf2,  0x09,  0xfe,  0xc8,  0x00,  0x18,  0x59,  0x0f,  0x06,
13984   0x88,  0x98,  0xfe,  0x90,  0x01,  0x7a,  0xfe,  0x42,  0x15,  0x91,  0xe4,  0xfe,  0x43,  0xf4,  0x9f,  0xfe,
13985   0x56,  0xf0,  0xfe,  0x54,  0x15,  0xfe,  0x04,  0xf4,  0x71,  0xfe,  0x43,  0xf4,  0x9e,  0xfe,  0xf3,  0x10,
13986   0xfe,  0x40,  0x5c,  0x01,  0xfe,  0x16,  0x14,  0x1e,  0x43,  0xec,  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,
13987   0x6e,  0x7a,  0xfe,  0x90,  0x15,  0xc4,  0x6e,  0xfe,  0x1c,  0x10,  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,
13988   0xcc,  0x7a,  0xfe,  0x90,  0x15,  0xc4,  0xcc,  0x88,  0x51,  0x21,  0xfe,  0x4d,  0xf4,  0x00,  0xe9,  0x91,
13989   0x0f,  0x06,  0xfe,  0xb4,  0x56,  0xfe,  0xc3,  0x58,  0x04,  0x51,  0x0f,  0x0a,  0x04,  0x16,  0x06,  0x01,
13990   0x0b,  0x26,  0xf3,  0x16,  0x0a,  0x01,  0x0b,  0x26,  0xf3,  0x16,  0x19,  0x01,  0x0b,  0x26,  0xf3,  0x76,
13991   0xfe,  0x89,  0x49,  0x01,  0x0b,  0x04,  0x16,  0x06,  0x01,  0x0b,  0x26,  0xb1,  0x16,  0x19,  0x01,  0x0b,
13992   0x26,  0xb1,  0x16,  0x06,  0x01,  0x0b,  0x26,  0xb1,  0xfe,  0x89,  0x49,  0x01,  0x0b,  0x26,  0xb1,  0x76,
13993   0xfe,  0x89,  0x4a,  0x01,  0x0b,  0x04,  0x51,  0x04,  0x22,  0xd3,  0x07,  0x06,  0xfe,  0x48,  0x13,  0xb8,
13994   0x13,  0xd3,  0xfe,  0x49,  0xf4,  0x00,  0x4d,  0x76,  0xa9,  0x67,  0xfe,  0x01,  0xec,  0xfe,  0x27,  0x01,
13995   0xfe,  0x89,  0x48,  0xff,  0x02,  0x00,  0x10,  0x27,  0xfe,  0x2e,  0x16,  0x32,  0x07,  0xfe,  0xe3,  0x00,
13996   0xfe,  0x20,  0x13,  0x1d,  0xfe,  0x52,  0x16,  0x21,  0x13,  0xd4,  0x01,  0x4b,  0x22,  0xd4,  0x07,  0x06,
13997   0x4e,  0x08,  0x54,  0x06,  0x37,  0x04,  0x09,  0x48,  0x01,  0x0e,  0xfb,  0x8e,  0x07,  0x11,  0xae,  0x09,
13998   0x84,  0x01,  0x0e,  0x8e,  0x09,  0x5d,  0x01,  0xa8,  0x04,  0x09,  0x84,  0x01,  0x0e,  0x8e,  0xfe,  0x80,
13999   0xe7,  0x11,  0x07,  0x11,  0x8a,  0xfe,  0x45,  0x58,  0x01,  0xf0,  0x8e,  0x04,  0x09,  0x48,  0x01,  0x0e,
14000   0x8e,  0x09,  0x5d,  0x01,  0xa8,  0x04,  0x09,  0x48,  0x01,  0x0e,  0xfe,  0x80,  0x80,  0xfe,  0x80,  0x4c,
14001   0xfe,  0x49,  0xe4,  0x11,  0xae,  0x09,  0x84,  0x01,  0x0e,  0xfe,  0x80,  0x4c,  0x09,  0x5d,  0x01,  0x87,
14002   0x04,  0x18,  0x11,  0x75,  0x6c,  0xfe,  0x60,  0x01,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x24,
14003   0x1c,  0xfe,  0x1d,  0xf7,  0x1b,  0x97,  0xfe,  0xee,  0x16,  0x01,  0xfe,  0xf4,  0x17,  0xad,  0x9a,  0x1b,
14004   0x6c,  0xfe,  0x2c,  0x01,  0xfe,  0x2f,  0x19,  0x04,  0xb9,  0x23,  0xfe,  0xde,  0x16,  0xfe,  0xda,  0x10,
14005   0x18,  0x11,  0x75,  0x03,  0xfe,  0x64,  0x01,  0xfe,  0x00,  0xf4,  0x1f,  0xfe,  0x18,  0x58,  0x03,  0xfe,
14006   0x66,  0x01,  0xfe,  0x19,  0x58,  0x9a,  0x1f,  0xfe,  0x3c,  0x90,  0xfe,  0x30,  0xf4,  0x06,  0xfe,  0x3c,
14007   0x50,  0x6c,  0xfe,  0x38,  0x00,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0x1f,  0x97,  0xfe,  0x38,  0x17,
14008   0xfe,  0xb6,  0x14,  0x35,  0x04,  0xb9,  0x23,  0xfe,  0x10,  0x17,  0xfe,  0x9c,  0x10,  0x18,  0x11,  0x75,
14009   0xfe,  0x83,  0x5a,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x1d,  0xf7,  0x2e,  0x97,  0xfe,  0x5a,
14010   0x17,  0xfe,  0x94,  0x14,  0xec,  0x9a,  0x2e,  0x6c,  0x1a,  0xfe,  0xaf,  0x19,  0xfe,  0x98,  0xe7,  0x00,
14011   0x04,  0xb9,  0x23,  0xfe,  0x4e,  0x17,  0xfe,  0x6c,  0x10,  0x18,  0x11,  0x75,  0xfe,  0x30,  0xbc,  0xfe,
14012   0xb2,  0xbc,  0x9a,  0xcb,  0x6c,  0x1a,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0xcb,  0x97,  0xfe,  0x92,
14013   0x17,  0xfe,  0x5c,  0x14,  0x35,  0x04,  0xb9,  0x23,  0xfe,  0x7e,  0x17,  0xfe,  0x42,  0x10,  0xfe,  0x02,
14014   0xf6,  0x11,  0x75,  0xfe,  0x18,  0xfe,  0x60,  0xfe,  0x19,  0xfe,  0x61,  0xfe,  0x03,  0xa1,  0xfe,  0x1d,
14015   0xf7,  0x5b,  0x97,  0xfe,  0xb8,  0x17,  0xfe,  0x36,  0x14,  0xfe,  0x1c,  0x13,  0x9a,  0x5b,  0x41,  0xfe,
14016   0x83,  0x58,  0xfe,  0xaf,  0x19,  0xfe,  0x80,  0xe7,  0x11,  0xfe,  0x81,  0xe7,  0x11,  0x12,  0xfe,  0xdd,
14017   0x00,  0x6a,  0x2a,  0x04,  0x6a,  0x2a,  0xfe,  0x12,  0x45,  0x23,  0xfe,  0xa8,  0x17,  0x15,  0x06,  0x39,
14018   0xa0,  0xb4,  0x02,  0x2b,  0xfe,  0x39,  0xf0,  0xfe,  0xfc,  0x17,  0x21,  0x04,  0xfe,  0x7e,  0x18,  0x1e,
14019   0x19,  0x66,  0x0f,  0x0d,  0x04,  0x75,  0x03,  0xd2,  0x1e,  0x06,  0xfe,  0xef,  0x12,  0xfe,  0xe1,  0x10,
14020   0x7c,  0x6f,  0x4f,  0x32,  0x07,  0x2f,  0xfe,  0x3c,  0x13,  0xf1,  0xfe,  0x42,  0x13,  0x42,  0x92,  0x09,
14021   0x48,  0x01,  0x0e,  0xbb,  0xeb,  0xfe,  0x41,  0x48,  0xfe,  0x45,  0x48,  0x01,  0xf0,  0xfe,  0x00,  0xcc,
14022   0xbb,  0xfe,  0xf3,  0x13,  0x43,  0x78,  0x07,  0x11,  0xac,  0x09,  0x84,  0x01,  0x0e,  0xfe,  0x80,  0x4c,
14023   0x01,  0x73,  0xfe,  0x16,  0x10,  0x07,  0x82,  0x8b,  0xfe,  0x40,  0x14,  0xfe,  0x24,  0x12,  0xfe,  0x14,
14024   0x56,  0xfe,  0xd6,  0xf0,  0xfe,  0x1c,  0x18,  0x18,  0x0a,  0x04,  0xfe,  0x9c,  0xe7,  0x0a,  0x10,  0xfe,
14025   0x15,  0x00,  0x64,  0x79,  0x2a,  0x01,  0xe3,  0x18,  0x06,  0x04,  0x42,  0x92,  0x08,  0x54,  0x1b,  0x37,
14026   0x12,  0x2f,  0x01,  0x73,  0x18,  0x06,  0x04,  0xfe,  0x38,  0x90,  0xfe,  0xba,  0x90,  0x3a,  0xce,  0x3b,
14027   0xcf,  0xfe,  0x48,  0x55,  0x35,  0xfe,  0xc9,  0x55,  0x04,  0x22,  0xa3,  0x77,  0x13,  0xa3,  0x04,  0x09,
14028   0xa4,  0x01,  0x0e,  0xfe,  0x41,  0x48,  0x09,  0x46,  0x01,  0x0e,  0xfe,  0x49,  0x44,  0x17,  0xfe,  0xe8,
14029   0x18,  0x77,  0x78,  0x04,  0x09,  0x48,  0x01,  0x0e,  0x07,  0x11,  0x4e,  0x09,  0x5d,  0x01,  0xa8,  0x09,
14030   0x46,  0x01,  0x0e,  0x77,  0x78,  0x04,  0xfe,  0x4e,  0xe4,  0x19,  0x6b,  0xfe,  0x1c,  0x19,  0x03,  0xfe,
14031   0x90,  0x00,  0xfe,  0x3a,  0x45,  0xfe,  0x2c,  0x10,  0xfe,  0x4e,  0xe4,  0xc9,  0x6b,  0xfe,  0x2e,  0x19,
14032   0x03,  0xfe,  0x92,  0x00,  0xfe,  0x02,  0xe6,  0x1a,  0xe5,  0xfe,  0x4e,  0xe4,  0xfe,  0x0b,  0x00,  0x6b,
14033   0xfe,  0x40,  0x19,  0x03,  0xfe,  0x94,  0x00,  0xfe,  0x02,  0xe6,  0x1f,  0xfe,  0x08,  0x10,  0x03,  0xfe,
14034   0x96,  0x00,  0xfe,  0x02,  0xe6,  0x6d,  0xfe,  0x4e,  0x45,  0xea,  0xba,  0xff,  0x04,  0x68,  0x54,  0xe7,
14035   0x1e,  0x6e,  0xfe,  0x08,  0x1c,  0xfe,  0x67,  0x19,  0xfe,  0x0a,  0x1c,  0xfe,  0x1a,  0xf4,  0xfe,  0x00,
14036   0x04,  0xea,  0xfe,  0x48,  0xf4,  0x19,  0x7a,  0xfe,  0x74,  0x19,  0x0f,  0x19,  0x04,  0x07,  0x7e,  0xfe,
14037   0x5a,  0xf0,  0xfe,  0x84,  0x19,  0x25,  0xfe,  0x09,  0x00,  0xfe,  0x34,  0x10,  0x07,  0x1a,  0xfe,  0x5a,
14038   0xf0,  0xfe,  0x92,  0x19,  0x25,  0xca,  0xfe,  0x26,  0x10,  0x07,  0x19,  0x66,  0x25,  0x6d,  0xe5,  0x07,
14039   0x0a,  0x66,  0x25,  0x9e,  0xfe,  0x0e,  0x10,  0x07,  0x06,  0x66,  0x25,  0x59,  0xa9,  0xb8,  0x04,  0x15,
14040   0xfe,  0x09,  0x00,  0x01,  0x36,  0xfe,  0x04,  0xfe,  0x81,  0x03,  0x83,  0xfe,  0x40,  0x5c,  0x04,  0x1c,
14041   0xf7,  0xfe,  0x14,  0xf0,  0x0b,  0x27,  0xfe,  0xd6,  0x19,  0x1c,  0xf7,  0x7b,  0xf7,  0xfe,  0x82,  0xf0,
14042   0xfe,  0xda,  0x19,  0x04,  0xff,  0xcc,  0x00,  0x00,
14043 };
14044
14045 STATIC unsigned short _adv_asc38C0800_size =
14046         sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
14047 STATIC ADV_DCNT _adv_asc38C0800_chksum =
14048         0x050D3FD8UL; /* Expanded little-endian checksum. */
14049
14050 /* Microcode buffer is kept after initialization for error recovery. */
14051 STATIC unsigned char _adv_asc38C1600_buf[] = {
14052   0x00,  0x00,  0x00,  0xf2,  0x00,  0x16,  0x00,  0xfc,  0x00,  0x10,  0x00,  0xf0,  0x18,  0xe4,  0x01,  0x00,
14053   0x04,  0x1e,  0x48,  0xe4,  0x03,  0xf6,  0xf7,  0x13,  0x2e,  0x1e,  0x02,  0x00,  0x07,  0x17,  0xc0,  0x5f,
14054   0x00,  0xfa,  0xff,  0xff,  0x04,  0x00,  0x00,  0xf6,  0x09,  0xe7,  0x82,  0xe7,  0x85,  0xf0,  0x86,  0xf0,
14055   0x4e,  0x10,  0x9e,  0xe7,  0xff,  0x00,  0x55,  0xf0,  0x01,  0xf6,  0x03,  0x00,  0x98,  0x57,  0x01,  0xe6,
14056   0x00,  0xea,  0x00,  0xec,  0x01,  0xfa,  0x18,  0xf4,  0x08,  0x00,  0xf0,  0x1d,  0x38,  0x54,  0x32,  0xf0,
14057   0x10,  0x00,  0xc2,  0x0e,  0x1e,  0xf0,  0xd5,  0xf0,  0xbc,  0x00,  0x4b,  0xe4,  0x00,  0xe6,  0xb1,  0xf0,
14058   0xb4,  0x00,  0x02,  0x13,  0x3e,  0x1c,  0xc8,  0x47,  0x3e,  0x00,  0xd8,  0x01,  0x06,  0x13,  0x0c,  0x1c,
14059   0x5e,  0x1e,  0x00,  0x57,  0xc8,  0x57,  0x01,  0xfc,  0xbc,  0x0e,  0xa2,  0x12,  0xb9,  0x54,  0x00,  0x80,
14060   0x62,  0x0a,  0x5a,  0x12,  0xc8,  0x15,  0x3e,  0x1e,  0x18,  0x40,  0xbd,  0x56,  0x03,  0xe6,  0x01,  0xea,
14061   0x5c,  0xf0,  0x0f,  0x00,  0x20,  0x00,  0x6c,  0x01,  0x6e,  0x01,  0x04,  0x12,  0x04,  0x13,  0xbb,  0x55,
14062   0x3c,  0x56,  0x3e,  0x57,  0x03,  0x58,  0x4a,  0xe4,  0x40,  0x00,  0xb6,  0x00,  0xbb,  0x00,  0xc0,  0x00,
14063   0x00,  0x01,  0x01,  0x01,  0x3e,  0x01,  0x58,  0x0a,  0x44,  0x10,  0x0a,  0x12,  0x4c,  0x1c,  0x4e,  0x1c,
14064   0x02,  0x4a,  0x30,  0xe4,  0x05,  0xe6,  0x0c,  0x00,  0x3c,  0x00,  0x80,  0x00,  0x24,  0x01,  0x3c,  0x01,
14065   0x68,  0x01,  0x6a,  0x01,  0x70,  0x01,  0x72,  0x01,  0x74,  0x01,  0x76,  0x01,  0x78,  0x01,  0x7c,  0x01,
14066   0xc6,  0x0e,  0x0c,  0x10,  0xac,  0x12,  0xae,  0x12,  0x16,  0x1a,  0x32,  0x1c,  0x6e,  0x1e,  0x02,  0x48,
14067   0x3a,  0x55,  0xc9,  0x57,  0x02,  0xee,  0x5b,  0xf0,  0x03,  0xf7,  0x06,  0xf7,  0x03,  0xfc,  0x06,  0x00,
14068   0x1e,  0x00,  0xbe,  0x00,  0xe1,  0x00,  0x0c,  0x12,  0x18,  0x1a,  0x70,  0x1a,  0x30,  0x1c,  0x38,  0x1c,
14069   0x10,  0x44,  0x00,  0x4c,  0xb0,  0x57,  0x40,  0x5c,  0x4d,  0xe4,  0x04,  0xea,  0x5d,  0xf0,  0xa7,  0xf0,
14070   0x04,  0xf6,  0x02,  0xfc,  0x05,  0x00,  0x09,  0x00,  0x19,  0x00,  0x32,  0x00,  0x33,  0x00,  0x34,  0x00,
14071   0x36,  0x00,  0x98,  0x00,  0x9e,  0x00,  0xcc,  0x00,  0x20,  0x01,  0x4e,  0x01,  0x79,  0x01,  0x3c,  0x09,
14072   0x68,  0x0d,  0x02,  0x10,  0x04,  0x10,  0x3a,  0x10,  0x08,  0x12,  0x0a,  0x13,  0x40,  0x16,  0x50,  0x16,
14073   0x00,  0x17,  0x4a,  0x19,  0x00,  0x4e,  0x00,  0x54,  0x01,  0x58,  0x00,  0xdc,  0x05,  0xf0,  0x09,  0xf0,
14074   0x59,  0xf0,  0xb8,  0xf0,  0x48,  0xf4,  0x0e,  0xf7,  0x0a,  0x00,  0x9b,  0x00,  0x9c,  0x00,  0xa4,  0x00,
14075   0xb5,  0x00,  0xba,  0x00,  0xd0,  0x00,  0xe7,  0x00,  0xf0,  0x03,  0x69,  0x08,  0xe9,  0x09,  0x5c,  0x0c,
14076   0xb6,  0x12,  0xbc,  0x19,  0xd8,  0x1b,  0x20,  0x1c,  0x34,  0x1c,  0x36,  0x1c,  0x42,  0x1d,  0x08,  0x44,
14077   0x38,  0x44,  0x91,  0x44,  0x0a,  0x45,  0x48,  0x46,  0x89,  0x48,  0x68,  0x54,  0x83,  0x55,  0x83,  0x59,
14078   0x31,  0xe4,  0x02,  0xe6,  0x07,  0xf0,  0x08,  0xf0,  0x0b,  0xf0,  0x0c,  0xf0,  0x4b,  0xf4,  0x04,  0xf8,
14079   0x05,  0xf8,  0x02,  0xfa,  0x03,  0xfa,  0x04,  0xfc,  0x05,  0xfc,  0x07,  0x00,  0xa8,  0x00,  0xaa,  0x00,
14080   0xb9,  0x00,  0xe0,  0x00,  0xe5,  0x00,  0x22,  0x01,  0x26,  0x01,  0x60,  0x01,  0x7a,  0x01,  0x82,  0x01,
14081   0xc8,  0x01,  0xca,  0x01,  0x86,  0x02,  0x6a,  0x03,  0x18,  0x05,  0xb2,  0x07,  0x68,  0x08,  0x10,  0x0d,
14082   0x06,  0x10,  0x0a,  0x10,  0x0e,  0x10,  0x12,  0x10,  0x60,  0x10,  0xed,  0x10,  0xf3,  0x10,  0x06,  0x12,
14083   0x10,  0x12,  0x1e,  0x12,  0x0c,  0x13,  0x0e,  0x13,  0x10,  0x13,  0xfe,  0x9c,  0xf0,  0x35,  0x05,  0xfe,
14084   0xec,  0x0e,  0xff,  0x10,  0x00,  0x00,  0xe9,  0xfe,  0x34,  0x1f,  0x00,  0xe8,  0xfe,  0x88,  0x01,  0xff,
14085   0x03,  0x00,  0x00,  0xfe,  0x93,  0x15,  0xfe,  0x0f,  0x05,  0xff,  0x38,  0x00,  0x00,  0xfe,  0x57,  0x24,
14086   0x00,  0xfe,  0x4c,  0x00,  0x65,  0xff,  0x04,  0x00,  0x00,  0x1a,  0xff,  0x09,  0x00,  0x00,  0xff,  0x08,
14087   0x01,  0x01,  0xff,  0x08,  0xff,  0xff,  0xff,  0x27,  0x00,  0x00,  0xff,  0x10,  0xff,  0xff,  0xff,  0x13,
14088   0x00,  0x00,  0xfe,  0x78,  0x56,  0xfe,  0x34,  0x12,  0xff,  0x21,  0x00,  0x00,  0xfe,  0x04,  0xf7,  0xe8,
14089   0x37,  0x7d,  0x0d,  0x01,  0xfe,  0x4a,  0x11,  0xfe,  0x04,  0xf7,  0xe8,  0x7d,  0x0d,  0x51,  0x37,  0xfe,
14090   0x3d,  0xf0,  0xfe,  0x0c,  0x02,  0xfe,  0x20,  0xf0,  0xbc,  0xfe,  0x91,  0xf0,  0xfe,  0xf8,  0x01,  0xfe,
14091   0x90,  0xf0,  0xfe,  0xf8,  0x01,  0xfe,  0x8f,  0xf0,  0xbc,  0x03,  0x67,  0x4d,  0x05,  0xfe,  0x08,  0x0f,
14092   0x01,  0xfe,  0x78,  0x0f,  0xfe,  0xdd,  0x12,  0x05,  0xfe,  0x0e,  0x03,  0xfe,  0x28,  0x1c,  0x03,  0xfe,
14093   0xa6,  0x00,  0xfe,  0xd1,  0x12,  0x3e,  0x22,  0xfe,  0xa6,  0x00,  0xac,  0xfe,  0x48,  0xf0,  0xfe,  0x90,
14094   0x02,  0xfe,  0x49,  0xf0,  0xfe,  0xaa,  0x02,  0xfe,  0x4a,  0xf0,  0xfe,  0xc8,  0x02,  0xfe,  0x46,  0xf0,
14095   0xfe,  0x5a,  0x02,  0xfe,  0x47,  0xf0,  0xfe,  0x60,  0x02,  0xfe,  0x43,  0xf0,  0xfe,  0x4e,  0x02,  0xfe,
14096   0x44,  0xf0,  0xfe,  0x52,  0x02,  0xfe,  0x45,  0xf0,  0xfe,  0x56,  0x02,  0x1c,  0x0d,  0xa2,  0x1c,  0x07,
14097   0x22,  0xb7,  0x05,  0x35,  0xfe,  0x00,  0x1c,  0xfe,  0xf1,  0x10,  0xfe,  0x02,  0x1c,  0xf5,  0xfe,  0x1e,
14098   0x1c,  0xfe,  0xe9,  0x10,  0x01,  0x5f,  0xfe,  0xe7,  0x10,  0xfe,  0x06,  0xfc,  0xde,  0x0a,  0x81,  0x01,
14099   0xa3,  0x05,  0x35,  0x1f,  0x95,  0x47,  0xb8,  0x01,  0xfe,  0xe4,  0x11,  0x0a,  0x81,  0x01,  0x5c,  0xfe,
14100   0xbd,  0x10,  0x0a,  0x81,  0x01,  0x5c,  0xfe,  0xad,  0x10,  0xfe,  0x16,  0x1c,  0xfe,  0x58,  0x1c,  0x1c,
14101   0x07,  0x22,  0xb7,  0x37,  0x2a,  0x35,  0xfe,  0x3d,  0xf0,  0xfe,  0x0c,  0x02,  0x2b,  0xfe,  0x9e,  0x02,
14102   0xfe,  0x5a,  0x1c,  0xfe,  0x12,  0x1c,  0xfe,  0x14,  0x1c,  0x1f,  0xfe,  0x30,  0x00,  0x47,  0xb8,  0x01,
14103   0xfe,  0xd4,  0x11,  0x1c,  0x07,  0x22,  0xb7,  0x05,  0xe9,  0x21,  0x2c,  0x09,  0x1a,  0x31,  0xfe,  0x69,
14104   0x10,  0x1c,  0x07,  0x22,  0xb7,  0xfe,  0x04,  0xec,  0x2c,  0x60,  0x01,  0xfe,  0x1e,  0x1e,  0x20,  0x2c,
14105   0xfe,  0x05,  0xf6,  0xde,  0x01,  0xfe,  0x62,  0x1b,  0x01,  0x0c,  0x61,  0x4a,  0x44,  0x15,  0x56,  0x51,
14106   0x01,  0xfe,  0x9e,  0x1e,  0x01,  0xfe,  0x96,  0x1a,  0x05,  0x35,  0x0a,  0x57,  0x01,  0x18,  0x09,  0x00,
14107   0x36,  0x01,  0x85,  0xfe,  0x18,  0x10,  0xfe,  0x41,  0x58,  0x0a,  0xba,  0x01,  0x18,  0xfe,  0xc8,  0x54,
14108   0x7b,  0xfe,  0x1c,  0x03,  0x01,  0xfe,  0x96,  0x1a,  0x05,  0x35,  0x37,  0x60,  0xfe,  0x02,  0xe8,  0x30,
14109   0xfe,  0xbf,  0x57,  0xfe,  0x9e,  0x43,  0xfe,  0x77,  0x57,  0xfe,  0x27,  0xf0,  0xfe,  0xe4,  0x01,  0xfe,
14110   0x07,  0x4b,  0xfe,  0x20,  0xf0,  0xbc,  0xfe,  0x40,  0x1c,  0x2a,  0xeb,  0xfe,  0x26,  0xf0,  0xfe,  0x66,
14111   0x03,  0xfe,  0xa0,  0xf0,  0xfe,  0x54,  0x03,  0xfe,  0x11,  0xf0,  0xbc,  0xfe,  0xef,  0x10,  0xfe,  0x9f,
14112   0xf0,  0xfe,  0x74,  0x03,  0xfe,  0x46,  0x1c,  0x19,  0xfe,  0x11,  0x00,  0x05,  0x70,  0x37,  0xfe,  0x48,
14113   0x1c,  0xfe,  0x46,  0x1c,  0x01,  0x0c,  0x06,  0x28,  0xfe,  0x18,  0x13,  0x26,  0x21,  0xb9,  0xc7,  0x20,
14114   0xb9,  0x0a,  0x57,  0x01,  0x18,  0xc7,  0x89,  0x01,  0xfe,  0xc8,  0x1a,  0x15,  0xe1,  0x2a,  0xeb,  0xfe,
14115   0x01,  0xf0,  0xeb,  0xfe,  0x82,  0xf0,  0xfe,  0xa4,  0x03,  0xfe,  0x9c,  0x32,  0x15,  0xfe,  0xe4,  0x00,
14116   0x2f,  0xfe,  0xb6,  0x03,  0x2a,  0x3c,  0x16,  0xfe,  0xc6,  0x03,  0x01,  0x41,  0xfe,  0x06,  0xf0,  0xfe,
14117   0xd6,  0x03,  0xaf,  0xa0,  0xfe,  0x0a,  0xf0,  0xfe,  0xa2,  0x07,  0x05,  0x29,  0x03,  0x81,  0x1e,  0x1b,
14118   0xfe,  0x24,  0x05,  0x1f,  0x63,  0x01,  0x42,  0x8f,  0xfe,  0x70,  0x02,  0x05,  0xea,  0xfe,  0x46,  0x1c,
14119   0x37,  0x7d,  0x1d,  0xfe,  0x67,  0x1b,  0xfe,  0xbf,  0x57,  0xfe,  0x77,  0x57,  0xfe,  0x48,  0x1c,  0x75,
14120   0x01,  0xa6,  0x86,  0x0a,  0x57,  0x01,  0x18,  0x09,  0x00,  0x1b,  0xec,  0x0a,  0xe1,  0x01,  0x18,  0x77,
14121   0x50,  0x40,  0x8d,  0x30,  0x03,  0x81,  0x1e,  0xf8,  0x1f,  0x63,  0x01,  0x42,  0x8f,  0xfe,  0x70,  0x02,
14122   0x05,  0xea,  0xd7,  0x99,  0xd8,  0x9c,  0x2a,  0x29,  0x2f,  0xfe,  0x4e,  0x04,  0x16,  0xfe,  0x4a,  0x04,
14123   0x7e,  0xfe,  0xa0,  0x00,  0xfe,  0x9b,  0x57,  0xfe,  0x54,  0x12,  0x32,  0xff,  0x02,  0x00,  0x10,  0x01,
14124   0x08,  0x16,  0xfe,  0x02,  0x05,  0x32,  0x01,  0x08,  0x16,  0x29,  0x27,  0x25,  0xee,  0xfe,  0x4c,  0x44,
14125   0xfe,  0x58,  0x12,  0x50,  0xfe,  0x44,  0x48,  0x13,  0x34,  0xfe,  0x4c,  0x54,  0x7b,  0xec,  0x60,  0x8d,
14126   0x30,  0x01,  0xfe,  0x4e,  0x1e,  0xfe,  0x48,  0x47,  0xfe,  0x7c,  0x13,  0x01,  0x0c,  0x06,  0x28,  0xfe,
14127   0x32,  0x13,  0x01,  0x43,  0x09,  0x9b,  0xfe,  0x68,  0x13,  0xfe,  0x26,  0x10,  0x13,  0x34,  0xfe,  0x4c,
14128   0x54,  0x7b,  0xec,  0x01,  0xfe,  0x4e,  0x1e,  0xfe,  0x48,  0x47,  0xfe,  0x54,  0x13,  0x01,  0x0c,  0x06,
14129   0x28,  0xa5,  0x01,  0x43,  0x09,  0x9b,  0xfe,  0x40,  0x13,  0x01,  0x0c,  0x06,  0x28,  0xf9,  0x1f,  0x7f,
14130   0x01,  0x0c,  0x06,  0x07,  0x4d,  0x1f,  0xfe,  0x0d,  0x00,  0x01,  0x42,  0x8f,  0xfe,  0xa4,  0x0e,  0x05,
14131   0x29,  0x32,  0x15,  0xfe,  0xe6,  0x00,  0x0f,  0xfe,  0x1c,  0x90,  0x04,  0xfe,  0x9c,  0x93,  0x3a,  0x0b,
14132   0x0e,  0x8b,  0x02,  0x1f,  0x7f,  0x01,  0x42,  0x05,  0x35,  0xfe,  0x42,  0x5b,  0x7d,  0x1d,  0xfe,  0x46,
14133   0x59,  0xfe,  0xbf,  0x57,  0xfe,  0x77,  0x57,  0x0f,  0xfe,  0x87,  0x80,  0x04,  0xfe,  0x87,  0x83,  0xfe,
14134   0xc9,  0x47,  0x0b,  0x0e,  0xd0,  0x65,  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x98,  0x13,  0x0f,  0xfe,  0x20,
14135   0x80,  0x04,  0xfe,  0xa0,  0x83,  0x33,  0x0b,  0x0e,  0x09,  0x1d,  0xfe,  0x84,  0x12,  0x01,  0x38,  0x06,
14136   0x07,  0xfe,  0x70,  0x13,  0x03,  0xfe,  0xa2,  0x00,  0x1e,  0x1b,  0xfe,  0xda,  0x05,  0xd0,  0x54,  0x01,
14137   0x38,  0x06,  0x0d,  0xfe,  0x58,  0x13,  0x03,  0xfe,  0xa0,  0x00,  0x1e,  0xfe,  0x50,  0x12,  0x5e,  0xff,
14138   0x02,  0x00,  0x10,  0x2f,  0xfe,  0x90,  0x05,  0x2a,  0x3c,  0xcc,  0xff,  0x02,  0x00,  0x10,  0x2f,  0xfe,
14139   0x9e,  0x05,  0x17,  0xfe,  0xf4,  0x05,  0x15,  0xfe,  0xe3,  0x00,  0x26,  0x01,  0x38,  0xfe,  0x4a,  0xf0,
14140   0xfe,  0xc0,  0x05,  0xfe,  0x49,  0xf0,  0xfe,  0xba,  0x05,  0x71,  0x2e,  0xfe,  0x21,  0x00,  0xf1,  0x2e,
14141   0xfe,  0x22,  0x00,  0xa2,  0x2e,  0x4a,  0xfe,  0x09,  0x48,  0xff,  0x02,  0x00,  0x10,  0x2f,  0xfe,  0xd0,
14142   0x05,  0x17,  0xfe,  0xf4,  0x05,  0xfe,  0xe2,  0x08,  0x01,  0x38,  0x06,  0xfe,  0x1c,  0x00,  0x4d,  0x01,
14143   0xa7,  0x2e,  0x07,  0x20,  0xe4,  0x47,  0xfe,  0x27,  0x01,  0x01,  0x0c,  0x06,  0x28,  0xfe,  0x24,  0x12,
14144   0x3e,  0x01,  0x84,  0x1f,  0x7f,  0x01,  0x0c,  0x06,  0x07,  0x4d,  0x1f,  0xfe,  0x0d,  0x00,  0x01,  0x42,
14145   0x8f,  0xfe,  0xa4,  0x0e,  0x05,  0x29,  0x03,  0xe6,  0x1e,  0xfe,  0xca,  0x13,  0x03,  0xb6,  0x1e,  0xfe,
14146   0x40,  0x12,  0x03,  0x66,  0x1e,  0xfe,  0x38,  0x13,  0x3e,  0x01,  0x84,  0x17,  0xfe,  0x72,  0x06,  0x0a,
14147   0x07,  0x01,  0x38,  0x06,  0x24,  0xfe,  0x02,  0x12,  0x4f,  0x01,  0xfe,  0x56,  0x19,  0x16,  0xfe,  0x68,
14148   0x06,  0x15,  0x82,  0x01,  0x41,  0x15,  0xe2,  0x03,  0x66,  0x8a,  0x10,  0x66,  0x03,  0x9a,  0x1e,  0xfe,
14149   0x70,  0x12,  0x03,  0x55,  0x1e,  0xfe,  0x68,  0x13,  0x01,  0xc6,  0x09,  0x12,  0x48,  0xfe,  0x92,  0x06,
14150   0x2e,  0x12,  0x01,  0xfe,  0xac,  0x1d,  0xfe,  0x43,  0x48,  0x62,  0x80,  0x13,  0x58,  0xff,  0x02,  0x00,
14151   0x57,  0x52,  0xad,  0x23,  0x3f,  0x4e,  0x62,  0x49,  0x3e,  0x01,  0x84,  0x17,  0xfe,  0xea,  0x06,  0x01,
14152   0x38,  0x06,  0x12,  0xf7,  0x45,  0x0a,  0x95,  0x01,  0xfe,  0x84,  0x19,  0x16,  0xfe,  0xe0,  0x06,  0x15,
14153   0x82,  0x01,  0x41,  0x15,  0xe2,  0x03,  0x55,  0x8a,  0x10,  0x55,  0x1c,  0x07,  0x01,  0x84,  0xfe,  0xae,
14154   0x10,  0x03,  0x6f,  0x1e,  0xfe,  0x9e,  0x13,  0x3e,  0x01,  0x84,  0x03,  0x9a,  0x1e,  0xfe,  0x1a,  0x12,
14155   0x01,  0x38,  0x06,  0x12,  0xfc,  0x01,  0xc6,  0x01,  0xfe,  0xac,  0x1d,  0xfe,  0x43,  0x48,  0x62,  0x80,
14156   0xf0,  0x45,  0x0a,  0x95,  0x03,  0xb6,  0x1e,  0xf8,  0x01,  0x38,  0x06,  0x24,  0x36,  0xfe,  0x02,  0xf6,
14157   0x07,  0x71,  0x78,  0x8c,  0x00,  0x4d,  0x62,  0x49,  0x3e,  0x2d,  0x93,  0x4e,  0xd0,  0x0d,  0x17,  0xfe,
14158   0x9a,  0x07,  0x01,  0xfe,  0xc0,  0x19,  0x16,  0xfe,  0x90,  0x07,  0x26,  0x20,  0x9e,  0x15,  0x82,  0x01,
14159   0x41,  0x15,  0xe2,  0x21,  0x9e,  0x09,  0x07,  0xfb,  0x03,  0xe6,  0xfe,  0x58,  0x57,  0x10,  0xe6,  0x05,
14160   0xfe,  0x2a,  0x06,  0x03,  0x6f,  0x8a,  0x10,  0x6f,  0x1c,  0x07,  0x01,  0x84,  0xfe,  0x9c,  0x32,  0x5f,
14161   0x75,  0x01,  0xa6,  0x86,  0x15,  0xfe,  0xe2,  0x00,  0x2f,  0xed,  0x2a,  0x3c,  0xfe,  0x0a,  0xf0,  0xfe,
14162   0xce,  0x07,  0xae,  0xfe,  0x96,  0x08,  0xfe,  0x06,  0xf0,  0xfe,  0x9e,  0x08,  0xaf,  0xa0,  0x05,  0x29,
14163   0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x2e,  0x12,  0x14,  0x1d,  0x01,  0x08,  0x14,  0x00,  0x01,  0x08,  0x14,
14164   0x00,  0x01,  0x08,  0x14,  0x00,  0x01,  0x08,  0xfe,  0x99,  0xa4,  0x01,  0x08,  0x14,  0x00,  0x05,  0xfe,
14165   0xc6,  0x09,  0x01,  0x76,  0x06,  0x12,  0xfe,  0x3a,  0x12,  0x01,  0x0c,  0x06,  0x12,  0xfe,  0x30,  0x13,
14166   0x14,  0xfe,  0x1b,  0x00,  0x01,  0x08,  0x14,  0x00,  0x01,  0x08,  0x14,  0x00,  0x01,  0x08,  0x14,  0x00,
14167   0x01,  0x08,  0x14,  0x07,  0x01,  0x08,  0x14,  0x00,  0x05,  0xef,  0x7c,  0x4a,  0x78,  0x4f,  0x0f,  0xfe,
14168   0x9a,  0x81,  0x04,  0xfe,  0x9a,  0x83,  0xfe,  0xcb,  0x47,  0x0b,  0x0e,  0x2d,  0x28,  0x48,  0xfe,  0x6c,
14169   0x08,  0x0a,  0x28,  0xfe,  0x09,  0x6f,  0xca,  0xfe,  0xca,  0x45,  0xfe,  0x32,  0x12,  0x53,  0x63,  0x4e,
14170   0x7c,  0x97,  0x2f,  0xfe,  0x7e,  0x08,  0x2a,  0x3c,  0xfe,  0x0a,  0xf0,  0xfe,  0x6c,  0x08,  0xaf,  0xa0,
14171   0xae,  0xfe,  0x96,  0x08,  0x05,  0x29,  0x01,  0x41,  0x05,  0xed,  0x14,  0x24,  0x05,  0xed,  0xfe,  0x9c,
14172   0xf7,  0x9f,  0x01,  0xfe,  0xae,  0x1e,  0xfe,  0x18,  0x58,  0x01,  0xfe,  0xbe,  0x1e,  0xfe,  0x99,  0x58,
14173   0xfe,  0x78,  0x18,  0xfe,  0xf9,  0x18,  0x8e,  0xfe,  0x16,  0x09,  0x10,  0x6a,  0x22,  0x6b,  0x01,  0x0c,
14174   0x61,  0x54,  0x44,  0x21,  0x2c,  0x09,  0x1a,  0xf8,  0x77,  0x01,  0xfe,  0x7e,  0x1e,  0x47,  0x2c,  0x7a,
14175   0x30,  0xf0,  0xfe,  0x83,  0xe7,  0xfe,  0x3f,  0x00,  0x71,  0xfe,  0x03,  0x40,  0x01,  0x0c,  0x61,  0x65,
14176   0x44,  0x01,  0xc2,  0xc8,  0xfe,  0x1f,  0x40,  0x20,  0x6e,  0x01,  0xfe,  0x6a,  0x16,  0xfe,  0x08,  0x50,
14177   0xfe,  0x8a,  0x50,  0xfe,  0x44,  0x51,  0xfe,  0xc6,  0x51,  0xfe,  0x10,  0x10,  0x01,  0xfe,  0xce,  0x1e,
14178   0x01,  0xfe,  0xde,  0x1e,  0x10,  0x68,  0x22,  0x69,  0x01,  0xfe,  0xee,  0x1e,  0x01,  0xfe,  0xfe,  0x1e,
14179   0xfe,  0x40,  0x50,  0xfe,  0xc2,  0x50,  0x10,  0x4b,  0x22,  0x4c,  0xfe,  0x8a,  0x10,  0x01,  0x0c,  0x06,
14180   0x54,  0xfe,  0x50,  0x12,  0x01,  0xfe,  0xae,  0x1e,  0x01,  0xfe,  0xbe,  0x1e,  0x10,  0x6a,  0x22,  0x6b,
14181   0x01,  0x0c,  0x06,  0x65,  0x4e,  0x01,  0xc2,  0x0f,  0xfe,  0x1f,  0x80,  0x04,  0xfe,  0x9f,  0x83,  0x33,
14182   0x0b,  0x0e,  0x20,  0x6e,  0x0f,  0xfe,  0x44,  0x90,  0x04,  0xfe,  0xc4,  0x93,  0x3a,  0x0b,  0xfe,  0xc6,
14183   0x90,  0x04,  0xfe,  0xc6,  0x93,  0x79,  0x0b,  0x0e,  0x10,  0x6c,  0x22,  0x6d,  0x01,  0xfe,  0xce,  0x1e,
14184   0x01,  0xfe,  0xde,  0x1e,  0x10,  0x68,  0x22,  0x69,  0x0f,  0xfe,  0x40,  0x90,  0x04,  0xfe,  0xc0,  0x93,
14185   0x3a,  0x0b,  0xfe,  0xc2,  0x90,  0x04,  0xfe,  0xc2,  0x93,  0x79,  0x0b,  0x0e,  0x10,  0x4b,  0x22,  0x4c,
14186   0x10,  0x64,  0x22,  0x34,  0x01,  0x0c,  0x61,  0x24,  0x44,  0x37,  0x13,  0xfe,  0x4e,  0x11,  0x2f,  0xfe,
14187   0xde,  0x09,  0xfe,  0x9e,  0xf0,  0xfe,  0xf2,  0x09,  0xfe,  0x01,  0x48,  0x1b,  0x3c,  0x37,  0x88,  0xf5,
14188   0xd4,  0xfe,  0x1e,  0x0a,  0xd5,  0xfe,  0x42,  0x0a,  0xd2,  0xfe,  0x1e,  0x0a,  0xd3,  0xfe,  0x42,  0x0a,
14189   0xae,  0xfe,  0x12,  0x0a,  0xfe,  0x06,  0xf0,  0xfe,  0x18,  0x0a,  0xaf,  0xa0,  0x05,  0x29,  0x01,  0x41,
14190   0xfe,  0xc1,  0x10,  0x14,  0x24,  0xfe,  0xc1,  0x10,  0x01,  0x76,  0x06,  0x07,  0xfe,  0x14,  0x12,  0x01,
14191   0x76,  0x06,  0x0d,  0x5d,  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x74,  0x12,  0xfe,  0x2e,  0x1c,  0x05,  0xfe,
14192   0x1a,  0x0c,  0x01,  0x76,  0x06,  0x07,  0x5d,  0x01,  0x76,  0x06,  0x0d,  0x41,  0xfe,  0x2c,  0x1c,  0xfe,
14193   0xaa,  0xf0,  0xfe,  0xce,  0x0a,  0xfe,  0xac,  0xf0,  0xfe,  0x66,  0x0a,  0xfe,  0x92,  0x10,  0xc4,  0xf6,
14194   0xfe,  0xad,  0xf0,  0xfe,  0x72,  0x0a,  0x05,  0xfe,  0x1a,  0x0c,  0xc5,  0xfe,  0xe7,  0x10,  0xfe,  0x2b,
14195   0xf0,  0xbf,  0xfe,  0x6b,  0x18,  0x23,  0xfe,  0x00,  0xfe,  0xfe,  0x1c,  0x12,  0xac,  0xfe,  0xd2,  0xf0,
14196   0xbf,  0xfe,  0x76,  0x18,  0x23,  0x1d,  0x1b,  0xbf,  0x03,  0xe3,  0x23,  0x07,  0x1b,  0xbf,  0xd4,  0x5b,
14197   0xd5,  0x5b,  0xd2,  0x5b,  0xd3,  0x5b,  0xc4,  0xc5,  0xfe,  0xa9,  0x10,  0x75,  0x5e,  0x32,  0x1f,  0x7f,
14198   0x01,  0x42,  0x19,  0xfe,  0x35,  0x00,  0xfe,  0x01,  0xf0,  0x70,  0x19,  0x98,  0x05,  0x70,  0xfe,  0x74,
14199   0x18,  0x23,  0xfe,  0x00,  0xf8,  0x1b,  0x5b,  0x7d,  0x12,  0x01,  0xfe,  0x78,  0x0f,  0x4d,  0x01,  0xfe,
14200   0x96,  0x1a,  0x21,  0x30,  0x77,  0x7d,  0x1d,  0x05,  0x5b,  0x01,  0x0c,  0x06,  0x0d,  0x2b,  0xfe,  0xe2,
14201   0x0b,  0x01,  0x0c,  0x06,  0x54,  0xfe,  0xa6,  0x12,  0x01,  0x0c,  0x06,  0x24,  0xfe,  0x88,  0x13,  0x21,
14202   0x6e,  0xc7,  0x01,  0xfe,  0x1e,  0x1f,  0x0f,  0xfe,  0x83,  0x80,  0x04,  0xfe,  0x83,  0x83,  0xfe,  0xc9,
14203   0x47,  0x0b,  0x0e,  0xfe,  0xc8,  0x44,  0xfe,  0x42,  0x13,  0x0f,  0xfe,  0x04,  0x91,  0x04,  0xfe,  0x84,
14204   0x93,  0xfe,  0xca,  0x57,  0x0b,  0xfe,  0x86,  0x91,  0x04,  0xfe,  0x86,  0x93,  0xfe,  0xcb,  0x57,  0x0b,
14205   0x0e,  0x7a,  0x30,  0xfe,  0x40,  0x59,  0xfe,  0xc1,  0x59,  0x8e,  0x40,  0x03,  0x6a,  0x3b,  0x6b,  0x10,
14206   0x97,  0x22,  0x98,  0xd9,  0x6a,  0xda,  0x6b,  0x01,  0xc2,  0xc8,  0x7a,  0x30,  0x20,  0x6e,  0xdb,  0x64,
14207   0xdc,  0x34,  0x91,  0x6c,  0x7e,  0x6d,  0xfe,  0x44,  0x55,  0xfe,  0xe5,  0x55,  0xfe,  0x04,  0xfa,  0x64,
14208   0xfe,  0x05,  0xfa,  0x34,  0x01,  0xfe,  0x6a,  0x16,  0xa3,  0x26,  0x10,  0x97,  0x10,  0x98,  0x91,  0x6c,
14209   0x7e,  0x6d,  0xfe,  0x14,  0x10,  0x01,  0x0c,  0x06,  0x24,  0x1b,  0x40,  0x91,  0x4b,  0x7e,  0x4c,  0x01,
14210   0x0c,  0x06,  0xfe,  0xf7,  0x00,  0x44,  0x03,  0x68,  0x3b,  0x69,  0xfe,  0x10,  0x58,  0xfe,  0x91,  0x58,
14211   0xfe,  0x14,  0x59,  0xfe,  0x95,  0x59,  0x05,  0x5b,  0x01,  0x0c,  0x06,  0x24,  0x1b,  0x40,  0x01,  0x0c,
14212   0x06,  0xfe,  0xf7,  0x00,  0x44,  0x78,  0x01,  0xfe,  0x8e,  0x1e,  0x4f,  0x0f,  0xfe,  0x10,  0x90,  0x04,
14213   0xfe,  0x90,  0x93,  0x3a,  0x0b,  0xfe,  0x92,  0x90,  0x04,  0xfe,  0x92,  0x93,  0x79,  0x0b,  0x0e,  0xfe,
14214   0xbd,  0x10,  0x01,  0x43,  0x09,  0xbb,  0x1b,  0xfe,  0x6e,  0x0a,  0x15,  0xbb,  0x01,  0x0c,  0x06,  0x0d,
14215   0xfe,  0x14,  0x13,  0x03,  0x4b,  0x3b,  0x4c,  0x8e,  0xfe,  0x6e,  0x0a,  0xfe,  0x0c,  0x58,  0xfe,  0x8d,
14216   0x58,  0x05,  0x5b,  0x26,  0x3e,  0x0f,  0xfe,  0x19,  0x80,  0x04,  0xfe,  0x99,  0x83,  0x33,  0x0b,  0x0e,
14217   0xfe,  0xe5,  0x10,  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x1a,  0x12,  0xfe,  0x6c,  0x19,  0xfe,  0x19,  0x41,
14218   0xfe,  0x6b,  0x18,  0xac,  0xfe,  0xd1,  0xf0,  0xef,  0x1f,  0x92,  0x01,  0x42,  0x19,  0xfe,  0x44,  0x00,
14219   0xfe,  0x90,  0x10,  0xfe,  0x6c,  0x19,  0xd9,  0x4b,  0xfe,  0xed,  0x19,  0xda,  0x4c,  0xfe,  0x0c,  0x51,
14220   0xfe,  0x8e,  0x51,  0xfe,  0x6b,  0x18,  0x23,  0xfe,  0x00,  0xff,  0x31,  0xfe,  0x76,  0x10,  0xac,  0xfe,
14221   0xd2,  0xf0,  0xfe,  0xba,  0x0c,  0xfe,  0x76,  0x18,  0x23,  0x1d,  0x5d,  0x03,  0xe3,  0x23,  0x07,  0xfe,
14222   0x08,  0x13,  0x19,  0xfe,  0x16,  0x00,  0x05,  0x70,  0xfe,  0xd1,  0xf0,  0xfe,  0xcc,  0x0c,  0x1f,  0x92,
14223   0x01,  0x42,  0x19,  0xfe,  0x17,  0x00,  0x5c,  0xfe,  0xce,  0xf0,  0xfe,  0xd2,  0x0c,  0xfe,  0x3e,  0x10,
14224   0xfe,  0xcd,  0xf0,  0xfe,  0xde,  0x0c,  0x19,  0xfe,  0x22,  0x00,  0x05,  0x70,  0xfe,  0xcb,  0xf0,  0xfe,
14225   0xea,  0x0c,  0x19,  0xfe,  0x24,  0x00,  0x05,  0x70,  0xfe,  0xd0,  0xf0,  0xfe,  0xf4,  0x0c,  0x19,  0x94,
14226   0xfe,  0x1c,  0x10,  0xfe,  0xcf,  0xf0,  0xfe,  0xfe,  0x0c,  0x19,  0x4a,  0xf3,  0xfe,  0xcc,  0xf0,  0xef,
14227   0x01,  0x76,  0x06,  0x24,  0x4d,  0x19,  0xfe,  0x12,  0x00,  0x37,  0x13,  0xfe,  0x4e,  0x11,  0x2f,  0xfe,
14228   0x16,  0x0d,  0xfe,  0x9e,  0xf0,  0xfe,  0x2a,  0x0d,  0xfe,  0x01,  0x48,  0x1b,  0x3c,  0x37,  0x88,  0xf5,
14229   0xd4,  0x29,  0xd5,  0x29,  0xd2,  0x29,  0xd3,  0x29,  0x37,  0xfe,  0x9c,  0x32,  0x2f,  0xfe,  0x3e,  0x0d,
14230   0x2a,  0x3c,  0xae,  0xfe,  0x62,  0x0d,  0xaf,  0xa0,  0xd4,  0x9f,  0xd5,  0x9f,  0xd2,  0x9f,  0xd3,  0x9f,
14231   0x05,  0x29,  0x01,  0x41,  0xfe,  0xd3,  0x10,  0x15,  0xfe,  0xe8,  0x00,  0xc4,  0xc5,  0x75,  0xd7,  0x99,
14232   0xd8,  0x9c,  0xfe,  0x89,  0xf0,  0x29,  0x27,  0x25,  0xbe,  0xd7,  0x99,  0xd8,  0x9c,  0x2f,  0xfe,  0x8c,
14233   0x0d,  0x16,  0x29,  0x27,  0x25,  0xbd,  0xfe,  0x01,  0x48,  0xa4,  0x19,  0xfe,  0x42,  0x00,  0x05,  0x70,
14234   0x90,  0x07,  0xfe,  0x81,  0x49,  0x1b,  0xfe,  0x64,  0x0e,  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x44,  0x13,
14235   0x19,  0x00,  0x2d,  0x0d,  0xfe,  0x54,  0x12,  0x2d,  0xfe,  0x28,  0x00,  0x2b,  0xfe,  0xda,  0x0e,  0x0a,
14236   0x57,  0x01,  0x18,  0x09,  0x00,  0x36,  0x46,  0xfe,  0x28,  0x00,  0xfe,  0xfa,  0x10,  0x01,  0xfe,  0xf4,
14237   0x1c,  0x01,  0xfe,  0x00,  0x1d,  0x0a,  0xba,  0x01,  0xfe,  0x58,  0x10,  0x40,  0x15,  0x56,  0x01,  0x85,
14238   0x05,  0x35,  0x19,  0xfe,  0x44,  0x00,  0x2d,  0x0d,  0xf7,  0x46,  0x0d,  0xfe,  0xcc,  0x10,  0x01,  0xa7,
14239   0x46,  0x0d,  0xfe,  0xc2,  0x10,  0x01,  0xa7,  0x0f,  0xfe,  0x19,  0x82,  0x04,  0xfe,  0x99,  0x83,  0xfe,
14240   0xcc,  0x47,  0x0b,  0x0e,  0xfe,  0x34,  0x46,  0xa5,  0x46,  0x0d,  0x19,  0xfe,  0x43,  0x00,  0xfe,  0xa2,
14241   0x10,  0x01,  0x0c,  0x61,  0x0d,  0x44,  0x01,  0xfe,  0xf4,  0x1c,  0x01,  0xfe,  0x00,  0x1d,  0x40,  0x15,
14242   0x56,  0x01,  0x85,  0x7d,  0x0d,  0x40,  0x51,  0x01,  0xfe,  0x9e,  0x1e,  0x05,  0xfe,  0x3a,  0x03,  0x01,
14243   0x0c,  0x06,  0x0d,  0x5d,  0x46,  0x0d,  0x19,  0x00,  0xfe,  0x62,  0x10,  0x01,  0x76,  0x06,  0x12,  0xfe,
14244   0x5c,  0x12,  0x01,  0x0c,  0x06,  0x12,  0xfe,  0x52,  0x13,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,
14245   0x8e,  0x0e,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x94,  0x0e,  0x01,  0x0c,  0x61,  0x12,  0x44,
14246   0xfe,  0x9f,  0x10,  0x19,  0xfe,  0x15,  0x00,  0xfe,  0x04,  0xe6,  0x0d,  0x4f,  0xfe,  0x2e,  0x10,  0x19,
14247   0xfe,  0x13,  0x00,  0xfe,  0x10,  0x10,  0x19,  0xfe,  0x47,  0x00,  0xf1,  0x19,  0xfe,  0x41,  0x00,  0xa2,
14248   0x19,  0xfe,  0x24,  0x00,  0x86,  0xc4,  0xc5,  0x75,  0x03,  0x81,  0x1e,  0x2b,  0xea,  0x4f,  0xfe,  0x04,
14249   0xe6,  0x12,  0xfe,  0x9d,  0x41,  0xfe,  0x1c,  0x42,  0x40,  0x01,  0xf4,  0x05,  0x35,  0xfe,  0x12,  0x1c,
14250   0x1f,  0x0d,  0x47,  0xb5,  0xc3,  0x1f,  0xfe,  0x31,  0x00,  0x47,  0xb8,  0x01,  0xfe,  0xd4,  0x11,  0x05,
14251   0xe9,  0x51,  0xfe,  0x06,  0xec,  0xe0,  0xfe,  0x0e,  0x47,  0x46,  0x28,  0xfe,  0xce,  0x45,  0x31,  0x51,
14252   0xfe,  0x06,  0xea,  0xe0,  0xfe,  0x47,  0x4b,  0x45,  0xfe,  0x75,  0x57,  0x03,  0x67,  0xfe,  0x98,  0x56,
14253   0xfe,  0x38,  0x12,  0x0a,  0x5a,  0x01,  0x18,  0xfe,  0x44,  0x48,  0x60,  0x01,  0x0c,  0x06,  0x28,  0xfe,
14254   0x18,  0x13,  0x0a,  0x57,  0x01,  0x18,  0x3e,  0xfe,  0x41,  0x58,  0x0a,  0xba,  0xfe,  0xfa,  0x14,  0xfe,
14255   0x49,  0x54,  0xb0,  0xfe,  0x5e,  0x0f,  0x05,  0xfe,  0x3a,  0x03,  0x0a,  0x67,  0xfe,  0xe0,  0x14,  0xfe,
14256   0x0e,  0x47,  0x46,  0x28,  0xfe,  0xce,  0x45,  0x31,  0x51,  0xfe,  0xce,  0x47,  0xfe,  0xad,  0x13,  0x05,
14257   0x35,  0x21,  0x2c,  0x09,  0x1a,  0xfe,  0x98,  0x12,  0x26,  0x20,  0x96,  0x20,  0xe7,  0xfe,  0x08,  0x1c,
14258   0xfe,  0x7c,  0x19,  0xfe,  0xfd,  0x19,  0xfe,  0x0a,  0x1c,  0x03,  0xe5,  0xfe,  0x48,  0x55,  0xa5,  0x3b,
14259   0xfe,  0x62,  0x01,  0xfe,  0xc9,  0x55,  0x31,  0xfe,  0x74,  0x10,  0x01,  0xfe,  0xf0,  0x1a,  0x03,  0xfe,
14260   0x38,  0x01,  0x3b,  0xfe,  0x3a,  0x01,  0x8e,  0xfe,  0x1e,  0x10,  0xfe,  0x02,  0xec,  0xe7,  0x53,  0x00,
14261   0x36,  0xfe,  0x04,  0xec,  0x2c,  0x60,  0xfe,  0x05,  0xf6,  0xfe,  0x34,  0x01,  0x01,  0xfe,  0x62,  0x1b,
14262   0x01,  0xfe,  0xce,  0x1e,  0xb2,  0x11,  0xfe,  0x18,  0x13,  0xca,  0xfe,  0x02,  0xea,  0xe7,  0x53,  0x92,
14263   0xfe,  0xc3,  0x13,  0x1f,  0x12,  0x47,  0xb5,  0xc3,  0xfe,  0x2a,  0x10,  0x03,  0xfe,  0x38,  0x01,  0x23,
14264   0xfe,  0xf0,  0xff,  0x10,  0xe5,  0x03,  0xfe,  0x3a,  0x01,  0x10,  0xfe,  0x62,  0x01,  0x01,  0xfe,  0x1e,
14265   0x1e,  0x20,  0x2c,  0x15,  0x56,  0x01,  0xfe,  0x9e,  0x1e,  0x13,  0x07,  0x02,  0x26,  0x02,  0x21,  0x96,
14266   0xc7,  0x20,  0x96,  0x09,  0x92,  0xfe,  0x79,  0x13,  0x1f,  0x1d,  0x47,  0xb5,  0xc3,  0xfe,  0xe1,  0x10,
14267   0xcf,  0xfe,  0x03,  0xdc,  0xfe,  0x73,  0x57,  0xfe,  0x80,  0x5d,  0x02,  0xcf,  0xfe,  0x03,  0xdc,  0xfe,
14268   0x5b,  0x57,  0xfe,  0x80,  0x5d,  0x02,  0xfe,  0x03,  0x57,  0xcf,  0x26,  0xfe,  0x00,  0xcc,  0x02,  0xfe,
14269   0x03,  0x57,  0xcf,  0x89,  0x02,  0x01,  0x0c,  0x06,  0x4a,  0xfe,  0x4e,  0x13,  0x0f,  0xfe,  0x1c,  0x80,
14270   0x04,  0xfe,  0x9c,  0x83,  0x33,  0x0b,  0x0e,  0x09,  0x07,  0xfe,  0x3a,  0x13,  0x0f,  0xfe,  0x1e,  0x80,
14271   0x04,  0xfe,  0x9e,  0x83,  0x33,  0x0b,  0x0e,  0xfe,  0x2a,  0x13,  0x0f,  0xfe,  0x1d,  0x80,  0x04,  0xfe,
14272   0x9d,  0x83,  0xfe,  0xf9,  0x13,  0x0e,  0xfe,  0x1c,  0x13,  0x01,  0xfe,  0xee,  0x1e,  0xac,  0xfe,  0x14,
14273   0x13,  0x01,  0xfe,  0xfe,  0x1e,  0xfe,  0x81,  0x58,  0xfa,  0x01,  0xfe,  0x0e,  0x1f,  0xfe,  0x30,  0xf4,
14274   0x0d,  0xfe,  0x3c,  0x50,  0xa2,  0x01,  0xfe,  0x92,  0x1b,  0x01,  0x43,  0x09,  0x56,  0xfb,  0x01,  0xfe,
14275   0xc8,  0x1a,  0x01,  0x0c,  0x06,  0x28,  0xa4,  0x01,  0xfe,  0xf4,  0x1c,  0x01,  0xfe,  0x00,  0x1d,  0x15,
14276   0xfe,  0xe9,  0x00,  0x01,  0x0c,  0x06,  0x4a,  0xfe,  0x4e,  0x13,  0x01,  0xfe,  0x22,  0x1b,  0xfe,  0x1e,
14277   0x1c,  0x0f,  0xfe,  0x14,  0x90,  0x04,  0xfe,  0x94,  0x93,  0x3a,  0x0b,  0xfe,  0x96,  0x90,  0x04,  0xfe,
14278   0x96,  0x93,  0x79,  0x0b,  0x0e,  0x10,  0xfe,  0x64,  0x01,  0x22,  0xfe,  0x66,  0x01,  0x01,  0x0c,  0x06,
14279   0x65,  0xf9,  0x0f,  0xfe,  0x03,  0x80,  0x04,  0xfe,  0x83,  0x83,  0x33,  0x0b,  0x0e,  0x77,  0xfe,  0x01,
14280   0xec,  0x2c,  0xfe,  0x80,  0x40,  0x20,  0x2c,  0x7a,  0x30,  0x15,  0xdf,  0x40,  0x21,  0x2c,  0xfe,  0x00,
14281   0x40,  0x8d,  0x2c,  0x02,  0xfe,  0x08,  0x1c,  0x03,  0xfe,  0xac,  0x00,  0xfe,  0x06,  0x58,  0x03,  0xfe,
14282   0xae,  0x00,  0xfe,  0x07,  0x58,  0x03,  0xfe,  0xb0,  0x00,  0xfe,  0x08,  0x58,  0x03,  0xfe,  0xb2,  0x00,
14283   0xfe,  0x09,  0x58,  0xfe,  0x0a,  0x1c,  0x2e,  0x49,  0x20,  0xe0,  0x26,  0x10,  0x66,  0x10,  0x55,  0x10,
14284   0x6f,  0x13,  0x57,  0x52,  0x4f,  0x1c,  0x28,  0xfe,  0x90,  0x4d,  0xfe,  0x91,  0x54,  0x2b,  0xfe,  0x88,
14285   0x11,  0x46,  0x1a,  0x13,  0x5a,  0x52,  0x1c,  0x4a,  0xfe,  0x90,  0x4d,  0xfe,  0x91,  0x54,  0x2b,  0xfe,
14286   0x9e,  0x11,  0x2e,  0x1a,  0x20,  0x2c,  0x90,  0x34,  0x60,  0x21,  0x2c,  0xfe,  0x00,  0x40,  0x8d,  0x2c,
14287   0x15,  0xdf,  0xfe,  0x14,  0x56,  0xfe,  0xd6,  0xf0,  0xfe,  0xb2,  0x11,  0xfe,  0x12,  0x1c,  0x75,  0xfe,
14288   0x14,  0x1c,  0xfe,  0x10,  0x1c,  0xfe,  0x18,  0x1c,  0x02,  0x51,  0xfe,  0x0c,  0x14,  0xfe,  0x0e,  0x47,
14289   0xfe,  0x07,  0xe6,  0x28,  0xfe,  0xce,  0x47,  0xfe,  0xf5,  0x13,  0x02,  0x01,  0xa7,  0x90,  0x34,  0x60,
14290   0xfe,  0x06,  0x80,  0xfe,  0x48,  0x47,  0xfe,  0x42,  0x13,  0xfe,  0x02,  0x80,  0x09,  0x56,  0xfe,  0x34,
14291   0x13,  0x0a,  0x5a,  0x01,  0x18,  0xcb,  0xfe,  0x36,  0x12,  0xfe,  0x41,  0x48,  0xfe,  0x45,  0x48,  0x01,
14292   0xfe,  0xb2,  0x16,  0xfe,  0x00,  0xcc,  0xcb,  0xfe,  0xf3,  0x13,  0x3f,  0x89,  0x09,  0x1a,  0xa5,  0x0a,
14293   0x9d,  0x01,  0x18,  0xfe,  0x80,  0x5c,  0x01,  0x85,  0xf2,  0x09,  0x9b,  0xa4,  0xfe,  0x14,  0x56,  0xfe,
14294   0xd6,  0xf0,  0xfe,  0xec,  0x11,  0x02,  0xfe,  0x44,  0x58,  0x77,  0xfe,  0x01,  0xec,  0xb8,  0xfe,  0x9e,
14295   0x40,  0xfe,  0x9d,  0xe7,  0x00,  0xfe,  0x9c,  0xe7,  0x12,  0x8d,  0x30,  0x01,  0xf4,  0xfe,  0xdd,  0x10,
14296   0x37,  0xd7,  0x99,  0xd8,  0x9c,  0x27,  0x25,  0xee,  0x09,  0x12,  0xfe,  0x48,  0x12,  0x09,  0x0d,  0xfe,
14297   0x56,  0x12,  0x09,  0x1d,  0xfe,  0x30,  0x12,  0x09,  0xdd,  0x1b,  0xfe,  0xc4,  0x13,  0x09,  0xfe,  0x23,
14298   0x00,  0x1b,  0xfe,  0xd0,  0x13,  0x09,  0x07,  0x1b,  0xfe,  0x34,  0x14,  0x09,  0x24,  0xfe,  0x12,  0x12,
14299   0x09,  0x00,  0x1b,  0x29,  0x1f,  0xdd,  0x01,  0x42,  0xa1,  0x32,  0x01,  0x08,  0xae,  0x41,  0x02,  0x32,
14300   0xfe,  0x62,  0x08,  0x0a,  0xe1,  0x01,  0xfe,  0x58,  0x10,  0x15,  0x9b,  0x05,  0x35,  0x32,  0x01,  0x43,
14301   0x09,  0xbb,  0xfe,  0xd7,  0x13,  0x91,  0x4b,  0x7e,  0x4c,  0x8e,  0xfe,  0x80,  0x13,  0x01,  0x0c,  0x06,
14302   0x54,  0xfe,  0x72,  0x12,  0xdb,  0x64,  0xdc,  0x34,  0xfe,  0x44,  0x55,  0xfe,  0xe5,  0x55,  0xb0,  0xfe,
14303   0x4a,  0x13,  0x21,  0x6e,  0xfe,  0x26,  0x13,  0x03,  0x97,  0x3b,  0x98,  0x8e,  0xfe,  0xb6,  0x0e,  0x10,
14304   0x6a,  0x22,  0x6b,  0x26,  0x10,  0x97,  0x10,  0x98,  0x01,  0xc2,  0x2e,  0x49,  0x88,  0x20,  0x6e,  0x01,
14305   0xfe,  0x6a,  0x16,  0xdb,  0x64,  0xdc,  0x34,  0xfe,  0x04,  0x55,  0xfe,  0xa5,  0x55,  0xfe,  0x04,  0xfa,
14306   0x64,  0xfe,  0x05,  0xfa,  0x34,  0xfe,  0x8f,  0x10,  0x03,  0x6c,  0x3b,  0x6d,  0xfe,  0x40,  0x56,  0xfe,
14307   0xe1,  0x56,  0x10,  0x6c,  0x22,  0x6d,  0x71,  0xdb,  0x64,  0xdc,  0x34,  0xfe,  0x44,  0x55,  0xfe,  0xe5,
14308   0x55,  0x03,  0x68,  0x3b,  0x69,  0xfe,  0x00,  0x56,  0xfe,  0xa1,  0x56,  0x10,  0x68,  0x22,  0x69,  0x01,
14309   0x0c,  0x06,  0x54,  0xf9,  0x21,  0x6e,  0xfe,  0x1f,  0x40,  0x03,  0x6a,  0x3b,  0x6b,  0xfe,  0x2c,  0x50,
14310   0xfe,  0xae,  0x50,  0x03,  0x6c,  0x3b,  0x6d,  0xfe,  0x44,  0x50,  0xfe,  0xc6,  0x50,  0x03,  0x68,  0x3b,
14311   0x69,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0x03,  0x4b,  0x3b,  0x4c,  0xfe,  0x40,  0x50,  0xfe,  0xc2,
14312   0x50,  0x05,  0x73,  0x2e,  0x07,  0x20,  0x9e,  0x05,  0x72,  0x32,  0x01,  0x08,  0x16,  0x3d,  0x27,  0x25,
14313   0xee,  0x09,  0x07,  0x2b,  0x3d,  0x01,  0x43,  0x09,  0xbb,  0x2b,  0x72,  0x01,  0xa6,  0x23,  0x3f,  0x1b,
14314   0x3d,  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x1e,  0x13,  0x91,  0x4b,  0x7e,  0x4c,  0xfe,  0x0a,  0x55,  0x31,
14315   0xfe,  0x8b,  0x55,  0xd9,  0x4b,  0xda,  0x4c,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0x05,  0x72,  0x01,
14316   0xfe,  0x8e,  0x1e,  0xca,  0xfe,  0x19,  0x41,  0x05,  0x72,  0x32,  0x01,  0x08,  0x2a,  0x3c,  0x16,  0xc0,
14317   0x27,  0x25,  0xbe,  0x2d,  0x1d,  0xc0,  0x2d,  0x0d,  0x83,  0x2d,  0x7f,  0x1b,  0xfe,  0x66,  0x15,  0x05,
14318   0x3d,  0x01,  0x08,  0x2a,  0x3c,  0x16,  0xc0,  0x27,  0x25,  0xbd,  0x09,  0x1d,  0x2b,  0x3d,  0x01,  0x08,
14319   0x16,  0xc0,  0x27,  0x25,  0xfe,  0xe8,  0x09,  0xfe,  0xc2,  0x49,  0x50,  0x03,  0xb6,  0x1e,  0x83,  0x01,
14320   0x38,  0x06,  0x24,  0x31,  0xa1,  0xfe,  0xbb,  0x45,  0x2d,  0x00,  0xa4,  0x46,  0x07,  0x90,  0x3f,  0x01,
14321   0xfe,  0xf8,  0x15,  0x01,  0xa6,  0x86,  0xfe,  0x4b,  0x45,  0xfe,  0x20,  0x13,  0x01,  0x43,  0x09,  0x82,
14322   0xfe,  0x16,  0x13,  0x03,  0x9a,  0x1e,  0x5d,  0x03,  0x55,  0x1e,  0x31,  0x5e,  0x05,  0x72,  0xfe,  0xc0,
14323   0x5d,  0x01,  0xa7,  0xfe,  0x03,  0x17,  0x03,  0x66,  0x8a,  0x10,  0x66,  0x5e,  0x32,  0x01,  0x08,  0x17,
14324   0x73,  0x01,  0xfe,  0x56,  0x19,  0x05,  0x73,  0x01,  0x08,  0x2a,  0x3c,  0x16,  0x3d,  0x27,  0x25,  0xbd,
14325   0x09,  0x07,  0x2b,  0x3d,  0x01,  0xfe,  0xbe,  0x16,  0xfe,  0x42,  0x58,  0xfe,  0xe8,  0x14,  0x01,  0xa6,
14326   0x86,  0xfe,  0x4a,  0xf4,  0x0d,  0x1b,  0x3d,  0xfe,  0x4a,  0xf4,  0x07,  0xfe,  0x0e,  0x12,  0x01,  0x43,
14327   0x09,  0x82,  0x4e,  0x05,  0x72,  0x03,  0x55,  0x8a,  0x10,  0x55,  0x5e,  0x32,  0x01,  0x08,  0x17,  0x73,
14328   0x01,  0xfe,  0x84,  0x19,  0x05,  0x73,  0x01,  0x08,  0x2a,  0x3c,  0x16,  0x3d,  0x27,  0x25,  0xbd,  0x09,
14329   0x12,  0x2b,  0x3d,  0x01,  0xfe,  0xe8,  0x17,  0x8b,  0xfe,  0xaa,  0x14,  0xfe,  0xb6,  0x14,  0x86,  0xa8,
14330   0xb2,  0x0d,  0x1b,  0x3d,  0xb2,  0x07,  0xfe,  0x0e,  0x12,  0x01,  0x43,  0x09,  0x82,  0x4e,  0x05,  0x72,
14331   0x03,  0x6f,  0x8a,  0x10,  0x6f,  0x5e,  0x32,  0x01,  0x08,  0x17,  0x73,  0x01,  0xfe,  0xc0,  0x19,  0x05,
14332   0x73,  0x13,  0x07,  0x2f,  0xfe,  0xcc,  0x15,  0x17,  0xfe,  0xe2,  0x15,  0x5f,  0xcc,  0x01,  0x08,  0x26,
14333   0x5f,  0x02,  0x8f,  0xfe,  0xde,  0x15,  0x2a,  0xfe,  0xde,  0x15,  0x16,  0xfe,  0xcc,  0x15,  0x5e,  0x32,
14334   0x01,  0x08,  0xfe,  0xd5,  0x10,  0x13,  0x58,  0xff,  0x02,  0x00,  0x57,  0x52,  0xad,  0x23,  0xfe,  0xff,
14335   0x7f,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x02,  0x13,  0x58,  0xff,  0x02,  0x00,  0x57,  0x52,  0xad,
14336   0x23,  0x3f,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x02,  0x13,  0x58,  0xff,  0x02,  0x00,  0x57,  0x52,
14337   0xad,  0x02,  0x13,  0x58,  0xff,  0x02,  0x00,  0x57,  0x52,  0xfe,  0x00,  0x5e,  0x02,  0x13,  0x58,  0xff,
14338   0x02,  0x00,  0x57,  0x52,  0xad,  0xfe,  0x0b,  0x58,  0x02,  0x0a,  0x66,  0x01,  0x5c,  0x0a,  0x55,  0x01,
14339   0x5c,  0x0a,  0x6f,  0x01,  0x5c,  0x02,  0x01,  0xfe,  0x1e,  0x1f,  0x23,  0x1a,  0xff,  0x03,  0x00,  0x54,
14340   0xfe,  0x00,  0xf4,  0x24,  0x52,  0x0f,  0xfe,  0x00,  0x7c,  0x04,  0xfe,  0x07,  0x7c,  0x3a,  0x0b,  0x0e,
14341   0xfe,  0x00,  0x71,  0xfe,  0xf9,  0x18,  0xfe,  0x7a,  0x19,  0xfe,  0xfb,  0x19,  0xfe,  0x1a,  0xf7,  0x00,
14342   0xfe,  0x1b,  0xf7,  0x00,  0x7a,  0x30,  0x10,  0x68,  0x22,  0x69,  0xd9,  0x6c,  0xda,  0x6d,  0x02,  0xfe,
14343   0x62,  0x08,  0xfe,  0x82,  0x4a,  0xfe,  0xe1,  0x1a,  0xfe,  0x83,  0x5a,  0x77,  0x02,  0x01,  0xc6,  0xfe,
14344   0x42,  0x48,  0x4f,  0x50,  0x45,  0x01,  0x08,  0x16,  0xfe,  0xe0,  0x17,  0x27,  0x25,  0xbe,  0x01,  0x08,
14345   0x16,  0xfe,  0xe0,  0x17,  0x27,  0x25,  0xfe,  0xe8,  0x0a,  0xfe,  0xc1,  0x59,  0x03,  0x9a,  0x1e,  0xfe,
14346   0xda,  0x12,  0x01,  0x38,  0x06,  0x12,  0xfe,  0xd0,  0x13,  0x26,  0x53,  0x12,  0x48,  0xfe,  0x08,  0x17,
14347   0xd1,  0x12,  0x53,  0x12,  0xfe,  0x1e,  0x13,  0x2d,  0xb4,  0x7b,  0xfe,  0x26,  0x17,  0x4d,  0x13,  0x07,
14348   0x1c,  0xb4,  0x90,  0x04,  0xfe,  0x78,  0x10,  0xff,  0x02,  0x83,  0x55,  0xf1,  0xff,  0x02,  0x83,  0x55,
14349   0x53,  0x1d,  0xfe,  0x12,  0x13,  0xd6,  0xfe,  0x30,  0x00,  0xb0,  0xfe,  0x80,  0x17,  0x1c,  0x63,  0x13,
14350   0x07,  0xfe,  0x56,  0x10,  0x53,  0x0d,  0xfe,  0x16,  0x13,  0xd6,  0xfe,  0x64,  0x00,  0xb0,  0xfe,  0x80,
14351   0x17,  0x0a,  0xfe,  0x64,  0x00,  0x1c,  0x94,  0x13,  0x07,  0xfe,  0x28,  0x10,  0x53,  0x07,  0xfe,  0x60,
14352   0x13,  0xd6,  0xfe,  0xc8,  0x00,  0xb0,  0xfe,  0x80,  0x17,  0x0a,  0xfe,  0xc8,  0x00,  0x1c,  0x95,  0x13,
14353   0x07,  0x71,  0xd6,  0xfe,  0x90,  0x01,  0x48,  0xfe,  0x8c,  0x17,  0x45,  0xf3,  0xfe,  0x43,  0xf4,  0x96,
14354   0xfe,  0x56,  0xf0,  0xfe,  0x9e,  0x17,  0xfe,  0x04,  0xf4,  0x58,  0xfe,  0x43,  0xf4,  0x94,  0xf6,  0x8b,
14355   0x01,  0xfe,  0x24,  0x16,  0x23,  0x3f,  0xfc,  0xa8,  0x8c,  0x49,  0x48,  0xfe,  0xda,  0x17,  0x62,  0x49,
14356   0xfe,  0x1c,  0x10,  0xa8,  0x8c,  0x80,  0x48,  0xfe,  0xda,  0x17,  0x62,  0x80,  0x71,  0x50,  0x26,  0xfe,
14357   0x4d,  0xf4,  0x00,  0xf7,  0x45,  0x13,  0x07,  0xfe,  0xb4,  0x56,  0xfe,  0xc3,  0x58,  0x02,  0x50,  0x13,
14358   0x0d,  0x02,  0x50,  0x3e,  0x78,  0x4f,  0x45,  0x01,  0x08,  0x16,  0xa9,  0x27,  0x25,  0xbe,  0xfe,  0x03,
14359   0xea,  0xfe,  0x7e,  0x01,  0x01,  0x08,  0x16,  0xa9,  0x27,  0x25,  0xfe,  0xe9,  0x0a,  0x01,  0x08,  0x16,
14360   0xa9,  0x27,  0x25,  0xfe,  0xe9,  0x0a,  0xfe,  0x05,  0xea,  0xfe,  0x7f,  0x01,  0x01,  0x08,  0x16,  0xa9,
14361   0x27,  0x25,  0xfe,  0x69,  0x09,  0xfe,  0x02,  0xea,  0xfe,  0x80,  0x01,  0x01,  0x08,  0x16,  0xa9,  0x27,
14362   0x25,  0xfe,  0xe8,  0x08,  0x47,  0xfe,  0x81,  0x01,  0x03,  0xb6,  0x1e,  0x83,  0x01,  0x38,  0x06,  0x24,
14363   0x31,  0xa2,  0x78,  0xf2,  0x53,  0x07,  0x36,  0xfe,  0x34,  0xf4,  0x3f,  0xa1,  0x78,  0x03,  0x9a,  0x1e,
14364   0x83,  0x01,  0x38,  0x06,  0x12,  0x31,  0xf0,  0x4f,  0x45,  0xfe,  0x90,  0x10,  0xfe,  0x40,  0x5a,  0x23,
14365   0x3f,  0xfb,  0x8c,  0x49,  0x48,  0xfe,  0xaa,  0x18,  0x62,  0x49,  0x71,  0x8c,  0x80,  0x48,  0xfe,  0xaa,
14366   0x18,  0x62,  0x80,  0xfe,  0xb4,  0x56,  0xfe,  0x40,  0x5d,  0x01,  0xc6,  0x01,  0xfe,  0xac,  0x1d,  0xfe,
14367   0x02,  0x17,  0xfe,  0xc8,  0x45,  0xfe,  0x5a,  0xf0,  0xfe,  0xc0,  0x18,  0xfe,  0x43,  0x48,  0x2d,  0x93,
14368   0x36,  0xfe,  0x34,  0xf4,  0xfe,  0x00,  0x11,  0xfe,  0x40,  0x10,  0x2d,  0xb4,  0x36,  0xfe,  0x34,  0xf4,
14369   0x04,  0xfe,  0x34,  0x10,  0x2d,  0xfe,  0x0b,  0x00,  0x36,  0x46,  0x63,  0xfe,  0x28,  0x10,  0xfe,  0xc0,
14370   0x49,  0xff,  0x02,  0x00,  0x54,  0xb2,  0xfe,  0x90,  0x01,  0x48,  0xfe,  0xfa,  0x18,  0x45,  0xfe,  0x1c,
14371   0xf4,  0x3f,  0xf3,  0xfe,  0x40,  0xf4,  0x96,  0xfe,  0x56,  0xf0,  0xfe,  0x0c,  0x19,  0xfe,  0x04,  0xf4,
14372   0x58,  0xfe,  0x40,  0xf4,  0x94,  0xf6,  0x3e,  0x2d,  0x93,  0x4e,  0xd0,  0x0d,  0x21,  0xfe,  0x7f,  0x01,
14373   0xfe,  0xc8,  0x46,  0xfe,  0x24,  0x13,  0x8c,  0x00,  0x5d,  0x26,  0x21,  0xfe,  0x7e,  0x01,  0xfe,  0xc8,
14374   0x45,  0xfe,  0x14,  0x13,  0x21,  0xfe,  0x80,  0x01,  0xfe,  0x48,  0x45,  0xfa,  0x21,  0xfe,  0x81,  0x01,
14375   0xfe,  0xc8,  0x44,  0x4e,  0x26,  0x02,  0x13,  0x07,  0x02,  0x78,  0x45,  0x50,  0x13,  0x0d,  0x02,  0x14,
14376   0x07,  0x01,  0x08,  0x17,  0xfe,  0x82,  0x19,  0x14,  0x0d,  0x01,  0x08,  0x17,  0xfe,  0x82,  0x19,  0x14,
14377   0x1d,  0x01,  0x08,  0x17,  0xfe,  0x82,  0x19,  0x5f,  0xfe,  0x89,  0x49,  0x01,  0x08,  0x02,  0x14,  0x07,
14378   0x01,  0x08,  0x17,  0xc1,  0x14,  0x1d,  0x01,  0x08,  0x17,  0xc1,  0x14,  0x07,  0x01,  0x08,  0x17,  0xc1,
14379   0xfe,  0x89,  0x49,  0x01,  0x08,  0x17,  0xc1,  0x5f,  0xfe,  0x89,  0x4a,  0x01,  0x08,  0x02,  0x50,  0x02,
14380   0x14,  0x07,  0x01,  0x08,  0x17,  0x74,  0x14,  0x7f,  0x01,  0x08,  0x17,  0x74,  0x14,  0x12,  0x01,  0x08,
14381   0x17,  0x74,  0xfe,  0x89,  0x49,  0x01,  0x08,  0x17,  0x74,  0x14,  0x00,  0x01,  0x08,  0x17,  0x74,  0xfe,
14382   0x89,  0x4a,  0x01,  0x08,  0x17,  0x74,  0xfe,  0x09,  0x49,  0x01,  0x08,  0x17,  0x74,  0x5f,  0xcc,  0x01,
14383   0x08,  0x02,  0x21,  0xe4,  0x09,  0x07,  0xfe,  0x4c,  0x13,  0xc8,  0x20,  0xe4,  0xfe,  0x49,  0xf4,  0x00,
14384   0x4d,  0x5f,  0xa1,  0x5e,  0xfe,  0x01,  0xec,  0xfe,  0x27,  0x01,  0xcc,  0xff,  0x02,  0x00,  0x10,  0x2f,
14385   0xfe,  0x3e,  0x1a,  0x01,  0x43,  0x09,  0xfe,  0xe3,  0x00,  0xfe,  0x22,  0x13,  0x16,  0xfe,  0x64,  0x1a,
14386   0x26,  0x20,  0x9e,  0x01,  0x41,  0x21,  0x9e,  0x09,  0x07,  0x5d,  0x01,  0x0c,  0x61,  0x07,  0x44,  0x02,
14387   0x0a,  0x5a,  0x01,  0x18,  0xfe,  0x00,  0x40,  0xaa,  0x09,  0x1a,  0xfe,  0x12,  0x13,  0x0a,  0x9d,  0x01,
14388   0x18,  0xaa,  0x0a,  0x67,  0x01,  0xa3,  0x02,  0x0a,  0x9d,  0x01,  0x18,  0xaa,  0xfe,  0x80,  0xe7,  0x1a,
14389   0x09,  0x1a,  0x5d,  0xfe,  0x45,  0x58,  0x01,  0xfe,  0xb2,  0x16,  0xaa,  0x02,  0x0a,  0x5a,  0x01,  0x18,
14390   0xaa,  0x0a,  0x67,  0x01,  0xa3,  0x02,  0x0a,  0x5a,  0x01,  0x18,  0x01,  0xfe,  0x7e,  0x1e,  0xfe,  0x80,
14391   0x4c,  0xfe,  0x49,  0xe4,  0x1a,  0xfe,  0x12,  0x13,  0x0a,  0x9d,  0x01,  0x18,  0xfe,  0x80,  0x4c,  0x0a,
14392   0x67,  0x01,  0x5c,  0x02,  0x1c,  0x1a,  0x87,  0x7c,  0xe5,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,
14393   0x24,  0x1c,  0xfe,  0x1d,  0xf7,  0x28,  0xb1,  0xfe,  0x04,  0x1b,  0x01,  0xfe,  0x2a,  0x1c,  0xfa,  0xb3,
14394   0x28,  0x7c,  0xfe,  0x2c,  0x01,  0xfe,  0x2f,  0x19,  0x02,  0xc9,  0x2b,  0xfe,  0xf4,  0x1a,  0xfe,  0xfa,
14395   0x10,  0x1c,  0x1a,  0x87,  0x03,  0xfe,  0x64,  0x01,  0xfe,  0x00,  0xf4,  0x24,  0xfe,  0x18,  0x58,  0x03,
14396   0xfe,  0x66,  0x01,  0xfe,  0x19,  0x58,  0xb3,  0x24,  0x01,  0xfe,  0x0e,  0x1f,  0xfe,  0x30,  0xf4,  0x07,
14397   0xfe,  0x3c,  0x50,  0x7c,  0xfe,  0x38,  0x00,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0x24,  0xb1,  0xfe,
14398   0x50,  0x1b,  0xfe,  0xd4,  0x14,  0x31,  0x02,  0xc9,  0x2b,  0xfe,  0x26,  0x1b,  0xfe,  0xba,  0x10,  0x1c,
14399   0x1a,  0x87,  0xfe,  0x83,  0x5a,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x1d,  0xf7,  0x54,  0xb1,
14400   0xfe,  0x72,  0x1b,  0xfe,  0xb2,  0x14,  0xfc,  0xb3,  0x54,  0x7c,  0x12,  0xfe,  0xaf,  0x19,  0xfe,  0x98,
14401   0xe7,  0x00,  0x02,  0xc9,  0x2b,  0xfe,  0x66,  0x1b,  0xfe,  0x8a,  0x10,  0x1c,  0x1a,  0x87,  0x8b,  0x0f,
14402   0xfe,  0x30,  0x90,  0x04,  0xfe,  0xb0,  0x93,  0x3a,  0x0b,  0xfe,  0x18,  0x58,  0xfe,  0x32,  0x90,  0x04,
14403   0xfe,  0xb2,  0x93,  0x3a,  0x0b,  0xfe,  0x19,  0x58,  0x0e,  0xa8,  0xb3,  0x4a,  0x7c,  0x12,  0xfe,  0x0f,
14404   0x79,  0xfe,  0x1c,  0xf7,  0x4a,  0xb1,  0xfe,  0xc6,  0x1b,  0xfe,  0x5e,  0x14,  0x31,  0x02,  0xc9,  0x2b,
14405   0xfe,  0x96,  0x1b,  0x5c,  0xfe,  0x02,  0xf6,  0x1a,  0x87,  0xfe,  0x18,  0xfe,  0x6a,  0xfe,  0x19,  0xfe,
14406   0x6b,  0x01,  0xfe,  0x1e,  0x1f,  0xfe,  0x1d,  0xf7,  0x65,  0xb1,  0xfe,  0xee,  0x1b,  0xfe,  0x36,  0x14,
14407   0xfe,  0x1c,  0x13,  0xb3,  0x65,  0x3e,  0xfe,  0x83,  0x58,  0xfe,  0xaf,  0x19,  0xfe,  0x80,  0xe7,  0x1a,
14408   0xfe,  0x81,  0xe7,  0x1a,  0x15,  0xfe,  0xdd,  0x00,  0x7a,  0x30,  0x02,  0x7a,  0x30,  0xfe,  0x12,  0x45,
14409   0x2b,  0xfe,  0xdc,  0x1b,  0x1f,  0x07,  0x47,  0xb5,  0xc3,  0x05,  0x35,  0xfe,  0x39,  0xf0,  0x75,  0x26,
14410   0x02,  0xfe,  0x7e,  0x18,  0x23,  0x1d,  0x36,  0x13,  0x11,  0x02,  0x87,  0x03,  0xe3,  0x23,  0x07,  0xfe,
14411   0xef,  0x12,  0xfe,  0xe1,  0x10,  0x90,  0x34,  0x60,  0xfe,  0x02,  0x80,  0x09,  0x56,  0xfe,  0x3c,  0x13,
14412   0xfe,  0x82,  0x14,  0xfe,  0x42,  0x13,  0x51,  0xfe,  0x06,  0x83,  0x0a,  0x5a,  0x01,  0x18,  0xcb,  0xfe,
14413   0x3e,  0x12,  0xfe,  0x41,  0x48,  0xfe,  0x45,  0x48,  0x01,  0xfe,  0xb2,  0x16,  0xfe,  0x00,  0xcc,  0xcb,
14414   0xfe,  0xf3,  0x13,  0x3f,  0x89,  0x09,  0x1a,  0xa5,  0x0a,  0x9d,  0x01,  0x18,  0xfe,  0x80,  0x4c,  0x01,
14415   0x85,  0xfe,  0x16,  0x10,  0x09,  0x9b,  0x4e,  0xfe,  0x40,  0x14,  0xfe,  0x24,  0x12,  0xfe,  0x14,  0x56,
14416   0xfe,  0xd6,  0xf0,  0xfe,  0x52,  0x1c,  0x1c,  0x0d,  0x02,  0xfe,  0x9c,  0xe7,  0x0d,  0x19,  0xfe,  0x15,
14417   0x00,  0x40,  0x8d,  0x30,  0x01,  0xf4,  0x1c,  0x07,  0x02,  0x51,  0xfe,  0x06,  0x83,  0xfe,  0x18,  0x80,
14418   0x61,  0x28,  0x44,  0x15,  0x56,  0x01,  0x85,  0x1c,  0x07,  0x02,  0xfe,  0x38,  0x90,  0xfe,  0xba,  0x90,
14419   0x91,  0xde,  0x7e,  0xdf,  0xfe,  0x48,  0x55,  0x31,  0xfe,  0xc9,  0x55,  0x02,  0x21,  0xb9,  0x88,  0x20,
14420   0xb9,  0x02,  0x0a,  0xba,  0x01,  0x18,  0xfe,  0x41,  0x48,  0x0a,  0x57,  0x01,  0x18,  0xfe,  0x49,  0x44,
14421   0x1b,  0xfe,  0x1e,  0x1d,  0x88,  0x89,  0x02,  0x0a,  0x5a,  0x01,  0x18,  0x09,  0x1a,  0xa4,  0x0a,  0x67,
14422   0x01,  0xa3,  0x0a,  0x57,  0x01,  0x18,  0x88,  0x89,  0x02,  0xfe,  0x4e,  0xe4,  0x1d,  0x7b,  0xfe,  0x52,
14423   0x1d,  0x03,  0xfe,  0x90,  0x00,  0xfe,  0x3a,  0x45,  0xfe,  0x2c,  0x10,  0xfe,  0x4e,  0xe4,  0xdd,  0x7b,
14424   0xfe,  0x64,  0x1d,  0x03,  0xfe,  0x92,  0x00,  0xd1,  0x12,  0xfe,  0x1a,  0x10,  0xfe,  0x4e,  0xe4,  0xfe,
14425   0x0b,  0x00,  0x7b,  0xfe,  0x76,  0x1d,  0x03,  0xfe,  0x94,  0x00,  0xd1,  0x24,  0xfe,  0x08,  0x10,  0x03,
14426   0xfe,  0x96,  0x00,  0xd1,  0x63,  0xfe,  0x4e,  0x45,  0x83,  0xca,  0xff,  0x04,  0x68,  0x54,  0xfe,  0xf1,
14427   0x10,  0x23,  0x49,  0xfe,  0x08,  0x1c,  0xfe,  0x67,  0x19,  0xfe,  0x0a,  0x1c,  0xfe,  0x1a,  0xf4,  0xfe,
14428   0x00,  0x04,  0x83,  0xb2,  0x1d,  0x48,  0xfe,  0xaa,  0x1d,  0x13,  0x1d,  0x02,  0x09,  0x92,  0xfe,  0x5a,
14429   0xf0,  0xfe,  0xba,  0x1d,  0x2e,  0x93,  0xfe,  0x34,  0x10,  0x09,  0x12,  0xfe,  0x5a,  0xf0,  0xfe,  0xc8,
14430   0x1d,  0x2e,  0xb4,  0xfe,  0x26,  0x10,  0x09,  0x1d,  0x36,  0x2e,  0x63,  0xfe,  0x1a,  0x10,  0x09,  0x0d,
14431   0x36,  0x2e,  0x94,  0xf2,  0x09,  0x07,  0x36,  0x2e,  0x95,  0xa1,  0xc8,  0x02,  0x1f,  0x93,  0x01,  0x42,
14432   0xfe,  0x04,  0xfe,  0x99,  0x03,  0x9c,  0x8b,  0x02,  0x2a,  0xfe,  0x1c,  0x1e,  0xfe,  0x14,  0xf0,  0x08,
14433   0x2f,  0xfe,  0x0c,  0x1e,  0x2a,  0xfe,  0x1c,  0x1e,  0x8f,  0xfe,  0x1c,  0x1e,  0xfe,  0x82,  0xf0,  0xfe,
14434   0x10,  0x1e,  0x02,  0x0f,  0x3f,  0x04,  0xfe,  0x80,  0x83,  0x33,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x18,
14435   0x80,  0x04,  0xfe,  0x98,  0x83,  0x33,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x02,  0x80,  0x04,  0xfe,  0x82,
14436   0x83,  0x33,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x06,  0x80,  0x04,  0xfe,  0x86,  0x83,  0x33,  0x0b,  0x0e,
14437   0x02,  0x0f,  0xfe,  0x1b,  0x80,  0x04,  0xfe,  0x9b,  0x83,  0x33,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x04,
14438   0x80,  0x04,  0xfe,  0x84,  0x83,  0x33,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x80,  0x80,  0x04,  0xfe,  0x80,
14439   0x83,  0xfe,  0xc9,  0x47,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x19,  0x81,  0x04,  0xfe,  0x99,  0x83,  0xfe,
14440   0xca,  0x47,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x06,  0x83,  0x04,  0xfe,  0x86,  0x83,  0xfe,  0xce,  0x47,
14441   0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x2c,  0x90,  0x04,  0xfe,  0xac,  0x93,  0x3a,  0x0b,  0x0e,  0x02,  0x0f,
14442   0xfe,  0xae,  0x90,  0x04,  0xfe,  0xae,  0x93,  0x79,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x08,  0x90,  0x04,
14443   0xfe,  0x88,  0x93,  0x3a,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x8a,  0x90,  0x04,  0xfe,  0x8a,  0x93,  0x79,
14444   0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x0c,  0x90,  0x04,  0xfe,  0x8c,  0x93,  0x3a,  0x0b,  0x0e,  0x02,  0x0f,
14445   0xfe,  0x8e,  0x90,  0x04,  0xfe,  0x8e,  0x93,  0x79,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x3c,  0x90,  0x04,
14446   0xfe,  0xbc,  0x93,  0x3a,  0x0b,  0x0e,  0x02,  0x8b,  0x0f,  0xfe,  0x03,  0x80,  0x04,  0xfe,  0x83,  0x83,
14447   0x33,  0x0b,  0x77,  0x0e,  0xa8,  0x02,  0xff,  0x66,  0x00,  0x00,
14448 };
14449
14450 STATIC unsigned short _adv_asc38C1600_size =
14451         sizeof(_adv_asc38C1600_buf); /* 0x1673 */
14452 STATIC ADV_DCNT _adv_asc38C1600_chksum =
14453         0x0604EF77UL; /* Expanded little-endian checksum. */
14454
14455 /* a_init.c */
14456 /*
14457  * EEPROM Configuration.
14458  *
14459  * All drivers should use this structure to set the default EEPROM
14460  * configuration. The BIOS now uses this structure when it is built.
14461  * Additional structure information can be found in a_condor.h where
14462  * the structure is defined.
14463  *
14464  * The *_Field_IsChar structs are needed to correct for endianness.
14465  * These values are read from the board 16 bits at a time directly
14466  * into the structs. Because some fields are char, the values will be
14467  * in the wrong order. The *_Field_IsChar tells when to flip the
14468  * bytes. Data read and written to PCI memory is automatically swapped
14469  * on big-endian platforms so char fields read as words are actually being
14470  * unswapped on big-endian platforms.
14471  */
14472 STATIC ADVEEP_3550_CONFIG
14473 Default_3550_EEPROM_Config ASC_INITDATA = {
14474     ADV_EEPROM_BIOS_ENABLE,     /* cfg_lsw */
14475     0x0000,                     /* cfg_msw */
14476     0xFFFF,                     /* disc_enable */
14477     0xFFFF,                     /* wdtr_able */
14478     0xFFFF,                     /* sdtr_able */
14479     0xFFFF,                     /* start_motor */
14480     0xFFFF,                     /* tagqng_able */
14481     0xFFFF,                     /* bios_scan */
14482     0,                          /* scam_tolerant */
14483     7,                          /* adapter_scsi_id */
14484     0,                          /* bios_boot_delay */
14485     3,                          /* scsi_reset_delay */
14486     0,                          /* bios_id_lun */
14487     0,                          /* termination */
14488     0,                          /* reserved1 */
14489     0xFFE7,                     /* bios_ctrl */
14490     0xFFFF,                     /* ultra_able */
14491     0,                          /* reserved2 */
14492     ASC_DEF_MAX_HOST_QNG,       /* max_host_qng */
14493     ASC_DEF_MAX_DVC_QNG,        /* max_dvc_qng */
14494     0,                          /* dvc_cntl */
14495     0,                          /* bug_fix */
14496     0,                          /* serial_number_word1 */
14497     0,                          /* serial_number_word2 */
14498     0,                          /* serial_number_word3 */
14499     0,                          /* check_sum */
14500     { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* oem_name[16] */
14501     0,                          /* dvc_err_code */
14502     0,                          /* adv_err_code */
14503     0,                          /* adv_err_addr */
14504     0,                          /* saved_dvc_err_code */
14505     0,                          /* saved_adv_err_code */
14506     0,                          /* saved_adv_err_addr */
14507     0                           /* num_of_err */
14508 };
14509
14510 STATIC ADVEEP_3550_CONFIG
14511 ADVEEP_3550_Config_Field_IsChar ASC_INITDATA = {
14512     0,                          /* cfg_lsw */
14513     0,                          /* cfg_msw */
14514     0,                          /* -disc_enable */
14515     0,                          /* wdtr_able */
14516     0,                          /* sdtr_able */
14517     0,                          /* start_motor */
14518     0,                          /* tagqng_able */
14519     0,                          /* bios_scan */
14520     0,                          /* scam_tolerant */
14521     1,                          /* adapter_scsi_id */
14522     1,                          /* bios_boot_delay */
14523     1,                          /* scsi_reset_delay */
14524     1,                          /* bios_id_lun */
14525     1,                          /* termination */
14526     1,                          /* reserved1 */
14527     0,                          /* bios_ctrl */
14528     0,                          /* ultra_able */
14529     0,                          /* reserved2 */
14530     1,                          /* max_host_qng */
14531     1,                          /* max_dvc_qng */
14532     0,                          /* dvc_cntl */
14533     0,                          /* bug_fix */
14534     0,                          /* serial_number_word1 */
14535     0,                          /* serial_number_word2 */
14536     0,                          /* serial_number_word3 */
14537     0,                          /* check_sum */
14538     { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* oem_name[16] */
14539     0,                          /* dvc_err_code */
14540     0,                          /* adv_err_code */
14541     0,                          /* adv_err_addr */
14542     0,                          /* saved_dvc_err_code */
14543     0,                          /* saved_adv_err_code */
14544     0,                          /* saved_adv_err_addr */
14545     0                           /* num_of_err */
14546 };
14547
14548 STATIC ADVEEP_38C0800_CONFIG
14549 Default_38C0800_EEPROM_Config ASC_INITDATA = {
14550     ADV_EEPROM_BIOS_ENABLE,     /* 00 cfg_lsw */
14551     0x0000,                     /* 01 cfg_msw */
14552     0xFFFF,                     /* 02 disc_enable */
14553     0xFFFF,                     /* 03 wdtr_able */
14554     0x4444,                     /* 04 sdtr_speed1 */
14555     0xFFFF,                     /* 05 start_motor */
14556     0xFFFF,                     /* 06 tagqng_able */
14557     0xFFFF,                     /* 07 bios_scan */
14558     0,                          /* 08 scam_tolerant */
14559     7,                          /* 09 adapter_scsi_id */
14560     0,                          /*    bios_boot_delay */
14561     3,                          /* 10 scsi_reset_delay */
14562     0,                          /*    bios_id_lun */
14563     0,                          /* 11 termination_se */
14564     0,                          /*    termination_lvd */
14565     0xFFE7,                     /* 12 bios_ctrl */
14566     0x4444,                     /* 13 sdtr_speed2 */
14567     0x4444,                     /* 14 sdtr_speed3 */
14568     ASC_DEF_MAX_HOST_QNG,       /* 15 max_host_qng */
14569     ASC_DEF_MAX_DVC_QNG,        /*    max_dvc_qng */
14570     0,                          /* 16 dvc_cntl */
14571     0x4444,                     /* 17 sdtr_speed4 */
14572     0,                          /* 18 serial_number_word1 */
14573     0,                          /* 19 serial_number_word2 */
14574     0,                          /* 20 serial_number_word3 */
14575     0,                          /* 21 check_sum */
14576     { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */
14577     0,                          /* 30 dvc_err_code */
14578     0,                          /* 31 adv_err_code */
14579     0,                          /* 32 adv_err_addr */
14580     0,                          /* 33 saved_dvc_err_code */
14581     0,                          /* 34 saved_adv_err_code */
14582     0,                          /* 35 saved_adv_err_addr */
14583     0,                          /* 36 reserved */
14584     0,                          /* 37 reserved */
14585     0,                          /* 38 reserved */
14586     0,                          /* 39 reserved */
14587     0,                          /* 40 reserved */
14588     0,                          /* 41 reserved */
14589     0,                          /* 42 reserved */
14590     0,                          /* 43 reserved */
14591     0,                          /* 44 reserved */
14592     0,                          /* 45 reserved */
14593     0,                          /* 46 reserved */
14594     0,                          /* 47 reserved */
14595     0,                          /* 48 reserved */
14596     0,                          /* 49 reserved */
14597     0,                          /* 50 reserved */
14598     0,                          /* 51 reserved */
14599     0,                          /* 52 reserved */
14600     0,                          /* 53 reserved */
14601     0,                          /* 54 reserved */
14602     0,                          /* 55 reserved */
14603     0,                          /* 56 cisptr_lsw */
14604     0,                          /* 57 cisprt_msw */
14605     ADV_PCI_VENDOR_ID,          /* 58 subsysvid */
14606     ADV_PCI_DEVID_38C0800_REV1, /* 59 subsysid */
14607     0,                          /* 60 reserved */
14608     0,                          /* 61 reserved */
14609     0,                          /* 62 reserved */
14610     0                           /* 63 reserved */
14611 };
14612
14613 STATIC ADVEEP_38C0800_CONFIG
14614 ADVEEP_38C0800_Config_Field_IsChar ASC_INITDATA = {
14615     0,                          /* 00 cfg_lsw */
14616     0,                          /* 01 cfg_msw */
14617     0,                          /* 02 disc_enable */
14618     0,                          /* 03 wdtr_able */
14619     0,                          /* 04 sdtr_speed1 */
14620     0,                          /* 05 start_motor */
14621     0,                          /* 06 tagqng_able */
14622     0,                          /* 07 bios_scan */
14623     0,                          /* 08 scam_tolerant */
14624     1,                          /* 09 adapter_scsi_id */
14625     1,                          /*    bios_boot_delay */
14626     1,                          /* 10 scsi_reset_delay */
14627     1,                          /*    bios_id_lun */
14628     1,                          /* 11 termination_se */
14629     1,                          /*    termination_lvd */
14630     0,                          /* 12 bios_ctrl */
14631     0,                          /* 13 sdtr_speed2 */
14632     0,                          /* 14 sdtr_speed3 */
14633     1,                          /* 15 max_host_qng */
14634     1,                          /*    max_dvc_qng */
14635     0,                          /* 16 dvc_cntl */
14636     0,                          /* 17 sdtr_speed4 */
14637     0,                          /* 18 serial_number_word1 */
14638     0,                          /* 19 serial_number_word2 */
14639     0,                          /* 20 serial_number_word3 */
14640     0,                          /* 21 check_sum */
14641     { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* 22-29 oem_name[16] */
14642     0,                          /* 30 dvc_err_code */
14643     0,                          /* 31 adv_err_code */
14644     0,                          /* 32 adv_err_addr */
14645     0,                          /* 33 saved_dvc_err_code */
14646     0,                          /* 34 saved_adv_err_code */
14647     0,                          /* 35 saved_adv_err_addr */
14648     0,                          /* 36 reserved */
14649     0,                          /* 37 reserved */
14650     0,                          /* 38 reserved */
14651     0,                          /* 39 reserved */
14652     0,                          /* 40 reserved */
14653     0,                          /* 41 reserved */
14654     0,                          /* 42 reserved */
14655     0,                          /* 43 reserved */
14656     0,                          /* 44 reserved */
14657     0,                          /* 45 reserved */
14658     0,                          /* 46 reserved */
14659     0,                          /* 47 reserved */
14660     0,                          /* 48 reserved */
14661     0,                          /* 49 reserved */
14662     0,                          /* 50 reserved */
14663     0,                          /* 51 reserved */
14664     0,                          /* 52 reserved */
14665     0,                          /* 53 reserved */
14666     0,                          /* 54 reserved */
14667     0,                          /* 55 reserved */
14668     0,                          /* 56 cisptr_lsw */
14669     0,                          /* 57 cisprt_msw */
14670     0,                          /* 58 subsysvid */
14671     0,                          /* 59 subsysid */
14672     0,                          /* 60 reserved */
14673     0,                          /* 61 reserved */
14674     0,                          /* 62 reserved */
14675     0                           /* 63 reserved */
14676 };
14677
14678 STATIC ADVEEP_38C1600_CONFIG
14679 Default_38C1600_EEPROM_Config ASC_INITDATA = {
14680     ADV_EEPROM_BIOS_ENABLE,     /* 00 cfg_lsw */
14681     0x0000,                     /* 01 cfg_msw */
14682     0xFFFF,                     /* 02 disc_enable */
14683     0xFFFF,                     /* 03 wdtr_able */
14684     0x5555,                     /* 04 sdtr_speed1 */
14685     0xFFFF,                     /* 05 start_motor */
14686     0xFFFF,                     /* 06 tagqng_able */
14687     0xFFFF,                     /* 07 bios_scan */
14688     0,                          /* 08 scam_tolerant */
14689     7,                          /* 09 adapter_scsi_id */
14690     0,                          /*    bios_boot_delay */
14691     3,                          /* 10 scsi_reset_delay */
14692     0,                          /*    bios_id_lun */
14693     0,                          /* 11 termination_se */
14694     0,                          /*    termination_lvd */
14695     0xFFE7,                     /* 12 bios_ctrl */
14696     0x5555,                     /* 13 sdtr_speed2 */
14697     0x5555,                     /* 14 sdtr_speed3 */
14698     ASC_DEF_MAX_HOST_QNG,       /* 15 max_host_qng */
14699     ASC_DEF_MAX_DVC_QNG,        /*    max_dvc_qng */
14700     0,                          /* 16 dvc_cntl */
14701     0x5555,                     /* 17 sdtr_speed4 */
14702     0,                          /* 18 serial_number_word1 */
14703     0,                          /* 19 serial_number_word2 */
14704     0,                          /* 20 serial_number_word3 */
14705     0,                          /* 21 check_sum */
14706     { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */
14707     0,                          /* 30 dvc_err_code */
14708     0,                          /* 31 adv_err_code */
14709     0,                          /* 32 adv_err_addr */
14710     0,                          /* 33 saved_dvc_err_code */
14711     0,                          /* 34 saved_adv_err_code */
14712     0,                          /* 35 saved_adv_err_addr */
14713     0,                          /* 36 reserved */
14714     0,                          /* 37 reserved */
14715     0,                          /* 38 reserved */
14716     0,                          /* 39 reserved */
14717     0,                          /* 40 reserved */
14718     0,                          /* 41 reserved */
14719     0,                          /* 42 reserved */
14720     0,                          /* 43 reserved */
14721     0,                          /* 44 reserved */
14722     0,                          /* 45 reserved */
14723     0,                          /* 46 reserved */
14724     0,                          /* 47 reserved */
14725     0,                          /* 48 reserved */
14726     0,                          /* 49 reserved */
14727     0,                          /* 50 reserved */
14728     0,                          /* 51 reserved */
14729     0,                          /* 52 reserved */
14730     0,                          /* 53 reserved */
14731     0,                          /* 54 reserved */
14732     0,                          /* 55 reserved */
14733     0,                          /* 56 cisptr_lsw */
14734     0,                          /* 57 cisprt_msw */
14735     ADV_PCI_VENDOR_ID,          /* 58 subsysvid */
14736     ADV_PCI_DEVID_38C1600_REV1, /* 59 subsysid */
14737     0,                          /* 60 reserved */
14738     0,                          /* 61 reserved */
14739     0,                          /* 62 reserved */
14740     0                           /* 63 reserved */
14741 };
14742
14743 STATIC ADVEEP_38C1600_CONFIG
14744 ADVEEP_38C1600_Config_Field_IsChar ASC_INITDATA = {
14745     0,                          /* 00 cfg_lsw */
14746     0,                          /* 01 cfg_msw */
14747     0,                          /* 02 disc_enable */
14748     0,                          /* 03 wdtr_able */
14749     0,                          /* 04 sdtr_speed1 */
14750     0,                          /* 05 start_motor */
14751     0,                          /* 06 tagqng_able */
14752     0,                          /* 07 bios_scan */
14753     0,                          /* 08 scam_tolerant */
14754     1,                          /* 09 adapter_scsi_id */
14755     1,                          /*    bios_boot_delay */
14756     1,                          /* 10 scsi_reset_delay */
14757     1,                          /*    bios_id_lun */
14758     1,                          /* 11 termination_se */
14759     1,                          /*    termination_lvd */
14760     0,                          /* 12 bios_ctrl */
14761     0,                          /* 13 sdtr_speed2 */
14762     0,                          /* 14 sdtr_speed3 */
14763     1,                          /* 15 max_host_qng */
14764     1,                          /*    max_dvc_qng */
14765     0,                          /* 16 dvc_cntl */
14766     0,                          /* 17 sdtr_speed4 */
14767     0,                          /* 18 serial_number_word1 */
14768     0,                          /* 19 serial_number_word2 */
14769     0,                          /* 20 serial_number_word3 */
14770     0,                          /* 21 check_sum */
14771     { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* 22-29 oem_name[16] */
14772     0,                          /* 30 dvc_err_code */
14773     0,                          /* 31 adv_err_code */
14774     0,                          /* 32 adv_err_addr */
14775     0,                          /* 33 saved_dvc_err_code */
14776     0,                          /* 34 saved_adv_err_code */
14777     0,                          /* 35 saved_adv_err_addr */
14778     0,                          /* 36 reserved */
14779     0,                          /* 37 reserved */
14780     0,                          /* 38 reserved */
14781     0,                          /* 39 reserved */
14782     0,                          /* 40 reserved */
14783     0,                          /* 41 reserved */
14784     0,                          /* 42 reserved */
14785     0,                          /* 43 reserved */
14786     0,                          /* 44 reserved */
14787     0,                          /* 45 reserved */
14788     0,                          /* 46 reserved */
14789     0,                          /* 47 reserved */
14790     0,                          /* 48 reserved */
14791     0,                          /* 49 reserved */
14792     0,                          /* 50 reserved */
14793     0,                          /* 51 reserved */
14794     0,                          /* 52 reserved */
14795     0,                          /* 53 reserved */
14796     0,                          /* 54 reserved */
14797     0,                          /* 55 reserved */
14798     0,                          /* 56 cisptr_lsw */
14799     0,                          /* 57 cisprt_msw */
14800     0,                          /* 58 subsysvid */
14801     0,                          /* 59 subsysid */
14802     0,                          /* 60 reserved */
14803     0,                          /* 61 reserved */
14804     0,                          /* 62 reserved */
14805     0                           /* 63 reserved */
14806 };
14807
14808 /*
14809  * Initialize the ADV_DVC_VAR structure.
14810  *
14811  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14812  *
14813  * For a non-fatal error return a warning code. If there are no warnings
14814  * then 0 is returned.
14815  */
14816 ASC_INITFUNC(
14817 STATIC int,
14818 AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
14819 )
14820 {
14821     ushort      warn_code;
14822     AdvPortAddr iop_base;
14823     uchar       pci_cmd_reg;
14824     int         status;
14825
14826     warn_code = 0;
14827     asc_dvc->err_code = 0;
14828     iop_base = asc_dvc->iop_base;
14829
14830     /*
14831      * PCI Command Register
14832      *
14833      * Note: AscPCICmdRegBits_BusMastering definition (0x0007) includes
14834      * I/O Space Control, Memory Space Control and Bus Master Control bits.
14835      */
14836
14837     if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
14838                             AscPCIConfigCommandRegister))
14839          & AscPCICmdRegBits_BusMastering)
14840         != AscPCICmdRegBits_BusMastering)
14841     {
14842         pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
14843
14844         DvcAdvWritePCIConfigByte(asc_dvc,
14845                 AscPCIConfigCommandRegister, pci_cmd_reg);
14846
14847         if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister))
14848              & AscPCICmdRegBits_BusMastering)
14849             != AscPCICmdRegBits_BusMastering)
14850         {
14851             warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14852         }
14853     }
14854
14855     /*
14856      * PCI Latency Timer
14857      *
14858      * If the "latency timer" register is 0x20 or above, then we don't need
14859      * to change it.  Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
14860      * comes up less than 0x20).
14861      */
14862     if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
14863         DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer, 0x20);
14864         if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20)
14865         {
14866             warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14867         }
14868     }
14869
14870     /*
14871      * Save the state of the PCI Configuration Command Register
14872      * "Parity Error Response Control" Bit. If the bit is clear (0),
14873      * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
14874      * DMA parity errors.
14875      */
14876     asc_dvc->cfg->control_flag = 0;
14877     if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
14878          & AscPCICmdRegBits_ParErrRespCtrl)) == 0)
14879     {
14880         asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
14881     }
14882
14883     asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
14884       ADV_LIB_VERSION_MINOR;
14885     asc_dvc->cfg->chip_version =
14886       AdvGetChipVersion(iop_base, asc_dvc->bus_type);
14887
14888     ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
14889         (ushort) AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
14890         (ushort) ADV_CHIP_ID_BYTE);
14891
14892     ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
14893         (ushort) AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
14894         (ushort) ADV_CHIP_ID_WORD);
14895
14896     /*
14897      * Reset the chip to start and allow register writes.
14898      */
14899     if (AdvFindSignature(iop_base) == 0)
14900     {
14901         asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
14902         return ADV_ERROR;
14903     }
14904     else {
14905         /*
14906          * The caller must set 'chip_type' to a valid setting.
14907          */
14908         if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
14909             asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
14910             asc_dvc->chip_type != ADV_CHIP_ASC38C1600)
14911         {
14912             asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14913             return ADV_ERROR;
14914         }
14915
14916         /*
14917          * Reset Chip.
14918          */
14919         AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14920             ADV_CTRL_REG_CMD_RESET);
14921         DvcSleepMilliSecond(100);
14922         AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14923             ADV_CTRL_REG_CMD_WR_IO_REG);
14924
14925         if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
14926         {
14927             if ((status = AdvInitFrom38C1600EEP(asc_dvc)) == ADV_ERROR)
14928             {
14929                 return ADV_ERROR;
14930             }
14931         } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
14932         {
14933             if ((status = AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR)
14934             {
14935                 return ADV_ERROR;
14936             }
14937         } else
14938         {
14939             if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR)
14940             {
14941                 return ADV_ERROR;
14942             }
14943         }
14944         warn_code |= status;
14945     }
14946
14947     return warn_code;
14948 }
14949
14950 /*
14951  * Initialize the ASC-3550.
14952  *
14953  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14954  *
14955  * For a non-fatal error return a warning code. If there are no warnings
14956  * then 0 is returned.
14957  *
14958  * Needed after initialization for error recovery.
14959  */
14960 STATIC int
14961 AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
14962 {
14963     AdvPortAddr iop_base;
14964     ushort      warn_code;
14965     ADV_DCNT    sum;
14966     int         begin_addr;
14967     int         end_addr;
14968     ushort      code_sum;
14969     int         word;
14970     int         j;
14971     int         adv_asc3550_expanded_size;
14972     ADV_CARR_T  *carrp;
14973     ADV_DCNT    contig_len;
14974     ADV_SDCNT   buf_size;
14975     ADV_PADDR   carr_paddr;
14976     int         i;
14977     ushort      scsi_cfg1;
14978     uchar       tid;
14979     ushort      bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
14980     ushort      wdtr_able = 0, sdtr_able, tagqng_able;
14981     uchar       max_cmd[ADV_MAX_TID + 1];
14982
14983     /* If there is already an error, don't continue. */
14984     if (asc_dvc->err_code != 0)
14985     {
14986         return ADV_ERROR;
14987     }
14988
14989     /*
14990      * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
14991      */
14992     if (asc_dvc->chip_type != ADV_CHIP_ASC3550)
14993     {
14994         asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14995         return ADV_ERROR;
14996     }
14997
14998     warn_code = 0;
14999     iop_base = asc_dvc->iop_base;
15000
15001     /*
15002      * Save the RISC memory BIOS region before writing the microcode.
15003      * The BIOS may already be loaded and using its RISC LRAM region
15004      * so its region must be saved and restored.
15005      *
15006      * Note: This code makes the assumption, which is currently true,
15007      * that a chip reset does not clear RISC LRAM.
15008      */
15009     for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15010     {
15011         AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15012     }
15013
15014     /*
15015      * Save current per TID negotiated values.
15016      */
15017     if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
15018     {
15019         ushort  bios_version, major, minor;
15020
15021         bios_version = bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM)/2];
15022         major = (bios_version  >> 12) & 0xF;
15023         minor = (bios_version  >> 8) & 0xF;
15024         if (major < 3 || (major == 3 && minor == 1))
15025         {
15026             /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
15027             AdvReadWordLram(iop_base, 0x120, wdtr_able);
15028         } else
15029         {
15030             AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15031         }
15032     }
15033     AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15034     AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15035     for (tid = 0; tid <= ADV_MAX_TID; tid++)
15036     {
15037         AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15038             max_cmd[tid]);
15039     }
15040
15041     /*
15042      * Load the Microcode
15043      *
15044      * Write the microcode image to RISC memory starting at address 0.
15045      */
15046     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15047     /* Assume the following compressed format of the microcode buffer:
15048      *
15049      *  254 word (508 byte) table indexed by byte code followed
15050      *  by the following byte codes:
15051      *
15052      *    1-Byte Code:
15053      *      00: Emit word 0 in table.
15054      *      01: Emit word 1 in table.
15055      *      .
15056      *      FD: Emit word 253 in table.
15057      *
15058      *    Multi-Byte Code:
15059      *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15060      *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15061      */
15062     word = 0;
15063     for (i = 253 * 2; i < _adv_asc3550_size; i++)
15064     {
15065         if (_adv_asc3550_buf[i] == 0xff)
15066         {
15067             for (j = 0; j < _adv_asc3550_buf[i + 1]; j++)
15068             {
15069                 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15070                     _adv_asc3550_buf[i + 3] << 8) |
15071                 _adv_asc3550_buf[i + 2]));
15072                 word++;
15073             }
15074             i += 3;
15075         } else if (_adv_asc3550_buf[i] == 0xfe)
15076         {
15077             AdvWriteWordAutoIncLram(iop_base, (((ushort)
15078                 _adv_asc3550_buf[i + 2] << 8) |
15079                 _adv_asc3550_buf[i + 1]));
15080             i += 2;
15081             word++;
15082         } else
15083         {
15084             AdvWriteWordAutoIncLram(iop_base, (((ushort)
15085                 _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) |
15086                 _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
15087             word++;
15088         }
15089     }
15090
15091     /*
15092      * Set 'word' for later use to clear the rest of memory and save
15093      * the expanded mcode size.
15094      */
15095     word *= 2;
15096     adv_asc3550_expanded_size = word;
15097
15098     /*
15099      * Clear the rest of ASC-3550 Internal RAM (8KB).
15100      */
15101     for (; word < ADV_3550_MEMSIZE; word += 2)
15102     {
15103         AdvWriteWordAutoIncLram(iop_base, 0);
15104     }
15105
15106     /*
15107      * Verify the microcode checksum.
15108      */
15109     sum = 0;
15110     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15111
15112     for (word = 0; word < adv_asc3550_expanded_size; word += 2)
15113     {
15114         sum += AdvReadWordAutoIncLram(iop_base);
15115     }
15116
15117     if (sum != _adv_asc3550_chksum)
15118     {
15119         asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15120         return ADV_ERROR;
15121     }
15122
15123     /*
15124      * Restore the RISC memory BIOS region.
15125      */
15126     for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15127     {
15128         AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15129     }
15130
15131     /*
15132      * Calculate and write the microcode code checksum to the microcode
15133      * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15134      */
15135     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15136     AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15137     code_sum = 0;
15138     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15139     for (word = begin_addr; word < end_addr; word += 2)
15140     {
15141         code_sum += AdvReadWordAutoIncLram(iop_base);
15142     }
15143     AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15144
15145     /*
15146      * Read and save microcode version and date.
15147      */
15148     AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
15149     AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
15150
15151     /*
15152      * Set the chip type to indicate the ASC3550.
15153      */
15154     AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
15155
15156     /*
15157      * If the PCI Configuration Command Register "Parity Error Response
15158      * Control" Bit was clear (0), then set the microcode variable
15159      * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15160      * to ignore DMA parity errors.
15161      */
15162     if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
15163     {
15164         AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15165         word |= CONTROL_FLAG_IGNORE_PERR;
15166         AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15167     }
15168
15169     /*
15170      * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
15171      * threshold of 128 bytes. This register is only accessible to the host.
15172      */
15173     AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15174         START_CTL_EMFU | READ_CMD_MRM);
15175
15176     /*
15177      * Microcode operating variables for WDTR, SDTR, and command tag
15178      * queuing will be set in AdvInquiryHandling() based on what a
15179      * device reports it is capable of in Inquiry byte 7.
15180      *
15181      * If SCSI Bus Resets have been disabled, then directly set
15182      * SDTR and WDTR from the EEPROM configuration. This will allow
15183      * the BIOS and warm boot to work without a SCSI bus hang on
15184      * the Inquiry caused by host and target mismatched DTR values.
15185      * Without the SCSI Bus Reset, before an Inquiry a device can't
15186      * be assumed to be in Asynchronous, Narrow mode.
15187      */
15188     if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
15189     {
15190         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
15191         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
15192     }
15193
15194     /*
15195      * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
15196      * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
15197      * bitmask. These values determine the maximum SDTR speed negotiated
15198      * with a device.
15199      *
15200      * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15201      * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15202      * without determining here whether the device supports SDTR.
15203      *
15204      * 4-bit speed  SDTR speed name
15205      * ===========  ===============
15206      * 0000b (0x0)  SDTR disabled
15207      * 0001b (0x1)  5 Mhz
15208      * 0010b (0x2)  10 Mhz
15209      * 0011b (0x3)  20 Mhz (Ultra)
15210      * 0100b (0x4)  40 Mhz (LVD/Ultra2)
15211      * 0101b (0x5)  80 Mhz (LVD2/Ultra3)
15212      * 0110b (0x6)  Undefined
15213      * .
15214      * 1111b (0xF)  Undefined
15215      */
15216     word = 0;
15217     for (tid = 0; tid <= ADV_MAX_TID; tid++)
15218     {
15219         if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able)
15220         {
15221             /* Set Ultra speed for TID 'tid'. */
15222             word |= (0x3 << (4 * (tid % 4)));
15223         } else
15224         {
15225             /* Set Fast speed for TID 'tid'. */
15226             word |= (0x2 << (4 * (tid % 4)));
15227         }
15228         if (tid == 3) /* Check if done with sdtr_speed1. */
15229         {
15230             AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
15231             word = 0;
15232         } else if (tid == 7) /* Check if done with sdtr_speed2. */
15233         {
15234             AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
15235             word = 0;
15236         } else if (tid == 11) /* Check if done with sdtr_speed3. */
15237         {
15238             AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
15239             word = 0;
15240         } else if (tid == 15) /* Check if done with sdtr_speed4. */
15241         {
15242             AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
15243             /* End of loop. */
15244         }
15245     }
15246
15247     /*
15248      * Set microcode operating variable for the disconnect per TID bitmask.
15249      */
15250     AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
15251
15252     /*
15253      * Set SCSI_CFG0 Microcode Default Value.
15254      *
15255      * The microcode will set the SCSI_CFG0 register using this value
15256      * after it is started below.
15257      */
15258     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15259         PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15260         asc_dvc->chip_scsi_id);
15261
15262     /*
15263      * Determine SCSI_CFG1 Microcode Default Value.
15264      *
15265      * The microcode will set the SCSI_CFG1 register using this value
15266      * after it is started below.
15267      */
15268
15269     /* Read current SCSI_CFG1 Register value. */
15270     scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15271
15272     /*
15273      * If all three connectors are in use, return an error.
15274      */
15275     if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
15276         (scsi_cfg1 & CABLE_ILLEGAL_B) == 0)
15277     {
15278             asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
15279             return ADV_ERROR;
15280     }
15281
15282     /*
15283      * If the internal narrow cable is reversed all of the SCSI_CTRL
15284      * register signals will be set. Check for and return an error if
15285      * this condition is found.
15286      */
15287     if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
15288     {
15289         asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15290         return ADV_ERROR;
15291     }
15292
15293     /*
15294      * If this is a differential board and a single-ended device
15295      * is attached to one of the connectors, return an error.
15296      */
15297     if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0)
15298     {
15299         asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
15300         return ADV_ERROR;
15301     }
15302
15303     /*
15304      * If automatic termination control is enabled, then set the
15305      * termination value based on a table listed in a_condor.h.
15306      *
15307      * If manual termination was specified with an EEPROM setting
15308      * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
15309      * is ready to be 'ored' into SCSI_CFG1.
15310      */
15311     if (asc_dvc->cfg->termination == 0)
15312     {
15313         /*
15314          * The software always controls termination by setting TERM_CTL_SEL.
15315          * If TERM_CTL_SEL were set to 0, the hardware would set termination.
15316          */
15317         asc_dvc->cfg->termination |= TERM_CTL_SEL;
15318
15319         switch(scsi_cfg1 & CABLE_DETECT)
15320         {
15321             /* TERM_CTL_H: on, TERM_CTL_L: on */
15322             case 0x3: case 0x7: case 0xB: case 0xD: case 0xE: case 0xF:
15323                 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
15324                 break;
15325
15326             /* TERM_CTL_H: on, TERM_CTL_L: off */
15327             case 0x1: case 0x5: case 0x9: case 0xA: case 0xC:
15328                 asc_dvc->cfg->termination |= TERM_CTL_H;
15329                 break;
15330
15331             /* TERM_CTL_H: off, TERM_CTL_L: off */
15332             case 0x2: case 0x6:
15333                 break;
15334         }
15335     }
15336
15337     /*
15338      * Clear any set TERM_CTL_H and TERM_CTL_L bits.
15339      */
15340     scsi_cfg1 &= ~TERM_CTL;
15341
15342     /*
15343      * Invert the TERM_CTL_H and TERM_CTL_L bits and then
15344      * set 'scsi_cfg1'. The TERM_POL bit does not need to be
15345      * referenced, because the hardware internally inverts
15346      * the Termination High and Low bits if TERM_POL is set.
15347      */
15348     scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
15349
15350     /*
15351      * Set SCSI_CFG1 Microcode Default Value
15352      *
15353      * Set filter value and possibly modified termination control
15354      * bits in the Microcode SCSI_CFG1 Register Value.
15355      *
15356      * The microcode will set the SCSI_CFG1 register using this value
15357      * after it is started below.
15358      */
15359     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
15360         FLTR_DISABLE | scsi_cfg1);
15361
15362     /*
15363      * Set MEM_CFG Microcode Default Value
15364      *
15365      * The microcode will set the MEM_CFG register using this value
15366      * after it is started below.
15367      *
15368      * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15369      * are defined.
15370      *
15371      * ASC-3550 has 8KB internal memory.
15372      */
15373     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15374         BIOS_EN | RAM_SZ_8KB);
15375
15376     /*
15377      * Set SEL_MASK Microcode Default Value
15378      *
15379      * The microcode will set the SEL_MASK register using this value
15380      * after it is started below.
15381      */
15382     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15383         ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15384
15385     /*
15386      * Build carrier freelist.
15387      *
15388      * Driver must have already allocated memory and set 'carrier_buf'.
15389      */
15390     ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15391
15392     carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15393     asc_dvc->carr_freelist = NULL;
15394     if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
15395     {
15396         buf_size = ADV_CARRIER_BUFSIZE;
15397     } else
15398     {
15399         buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15400     }
15401
15402     do {
15403         /*
15404          * Get physical address of the carrier 'carrp'.
15405          */
15406         contig_len = sizeof(ADV_CARR_T);
15407         carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
15408             (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
15409
15410         buf_size -= sizeof(ADV_CARR_T);
15411
15412         /*
15413          * If the current carrier is not physically contiguous, then
15414          * maybe there was a page crossing. Try the next carrier aligned
15415          * start address.
15416          */
15417         if (contig_len < sizeof(ADV_CARR_T))
15418         {
15419             carrp++;
15420             continue;
15421         }
15422
15423         carrp->carr_pa = carr_paddr;
15424         carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15425
15426         /*
15427          * Insert the carrier at the beginning of the freelist.
15428          */
15429         carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15430         asc_dvc->carr_freelist = carrp;
15431
15432         carrp++;
15433     }
15434     while (buf_size > 0);
15435
15436     /*
15437      * Set-up the Host->RISC Initiator Command Queue (ICQ).
15438      */
15439
15440     if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
15441     {
15442         asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15443         return ADV_ERROR;
15444     }
15445     asc_dvc->carr_freelist = (ADV_CARR_T *)
15446         ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15447
15448     /*
15449      * The first command issued will be placed in the stopper carrier.
15450      */
15451     asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15452
15453     /*
15454      * Set RISC ICQ physical address start value.
15455      */
15456     AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15457
15458     /*
15459      * Set-up the RISC->Host Initiator Response Queue (IRQ).
15460      */
15461     if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
15462     {
15463         asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15464         return ADV_ERROR;
15465     }
15466     asc_dvc->carr_freelist = (ADV_CARR_T *)
15467          ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15468
15469     /*
15470      * The first command completed by the RISC will be placed in
15471      * the stopper.
15472      *
15473      * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15474      * completed the RISC will set the ASC_RQ_STOPPER bit.
15475      */
15476     asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15477
15478     /*
15479      * Set RISC IRQ physical address start value.
15480      */
15481     AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15482     asc_dvc->carr_pending_cnt = 0;
15483
15484     AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15485         (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
15486
15487     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15488     AdvWriteWordRegister(iop_base, IOPW_PC, word);
15489
15490     /* finally, finally, gentlemen, start your engine */
15491     AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15492
15493     /*
15494      * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15495      * Resets should be performed. The RISC has to be running
15496      * to issue a SCSI Bus Reset.
15497      */
15498     if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
15499     {
15500         /*
15501          * If the BIOS Signature is present in memory, restore the
15502          * BIOS Handshake Configuration Table and do not perform
15503          * a SCSI Bus Reset.
15504          */
15505         if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
15506         {
15507             /*
15508              * Restore per TID negotiated values.
15509              */
15510             AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15511             AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15512             AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15513             for (tid = 0; tid <= ADV_MAX_TID; tid++)
15514             {
15515                 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15516                     max_cmd[tid]);
15517             }
15518         } else
15519         {
15520             if (AdvResetSB(asc_dvc) != ADV_TRUE)
15521             {
15522                 warn_code = ASC_WARN_BUSRESET_ERROR;
15523             }
15524         }
15525     }
15526
15527     return warn_code;
15528 }
15529
15530 /*
15531  * Initialize the ASC-38C0800.
15532  *
15533  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15534  *
15535  * For a non-fatal error return a warning code. If there are no warnings
15536  * then 0 is returned.
15537  *
15538  * Needed after initialization for error recovery.
15539  */
15540 STATIC int
15541 AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
15542 {
15543     AdvPortAddr iop_base;
15544     ushort      warn_code;
15545     ADV_DCNT    sum;
15546     int         begin_addr;
15547     int         end_addr;
15548     ushort      code_sum;
15549     int         word;
15550     int         j;
15551     int         adv_asc38C0800_expanded_size;
15552     ADV_CARR_T  *carrp;
15553     ADV_DCNT    contig_len;
15554     ADV_SDCNT   buf_size;
15555     ADV_PADDR   carr_paddr;
15556     int         i;
15557     ushort      scsi_cfg1;
15558     uchar       byte;
15559     uchar       tid;
15560     ushort      bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
15561     ushort      wdtr_able, sdtr_able, tagqng_able;
15562     uchar       max_cmd[ADV_MAX_TID + 1];
15563
15564     /* If there is already an error, don't continue. */
15565     if (asc_dvc->err_code != 0)
15566     {
15567         return ADV_ERROR;
15568     }
15569
15570     /*
15571      * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
15572      */
15573     if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800)
15574     {
15575         asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
15576         return ADV_ERROR;
15577     }
15578
15579     warn_code = 0;
15580     iop_base = asc_dvc->iop_base;
15581
15582     /*
15583      * Save the RISC memory BIOS region before writing the microcode.
15584      * The BIOS may already be loaded and using its RISC LRAM region
15585      * so its region must be saved and restored.
15586      *
15587      * Note: This code makes the assumption, which is currently true,
15588      * that a chip reset does not clear RISC LRAM.
15589      */
15590     for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15591     {
15592         AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15593     }
15594
15595     /*
15596      * Save current per TID negotiated values.
15597      */
15598     AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15599     AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15600     AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15601     for (tid = 0; tid <= ADV_MAX_TID; tid++)
15602     {
15603         AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15604             max_cmd[tid]);
15605     }
15606
15607     /*
15608      * RAM BIST (RAM Built-In Self Test)
15609      *
15610      * Address : I/O base + offset 0x38h register (byte).
15611      * Function: Bit 7-6(RW) : RAM mode
15612      *                          Normal Mode   : 0x00
15613      *                          Pre-test Mode : 0x40
15614      *                          RAM Test Mode : 0x80
15615      *           Bit 5       : unused
15616      *           Bit 4(RO)   : Done bit
15617      *           Bit 3-0(RO) : Status
15618      *                          Host Error    : 0x08
15619      *                          Int_RAM Error : 0x04
15620      *                          RISC Error    : 0x02
15621      *                          SCSI Error    : 0x01
15622      *                          No Error      : 0x00
15623      *
15624      * Note: RAM BIST code should be put right here, before loading the
15625      * microcode and after saving the RISC memory BIOS region.
15626      */
15627
15628     /*
15629      * LRAM Pre-test
15630      *
15631      * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15632      * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15633      * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15634      * to NORMAL_MODE, return an error too.
15635      */
15636     for (i = 0; i < 2; i++)
15637     {
15638         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15639         DvcSleepMilliSecond(10);  /* Wait for 10ms before reading back. */
15640         byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15641         if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE)
15642         {
15643             asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15644             return ADV_ERROR;
15645         }
15646
15647         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15648         DvcSleepMilliSecond(10);  /* Wait for 10ms before reading back. */
15649         if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15650             != NORMAL_VALUE)
15651         {
15652             asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15653             return ADV_ERROR;
15654         }
15655     }
15656
15657     /*
15658      * LRAM Test - It takes about 1.5 ms to run through the test.
15659      *
15660      * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15661      * If Done bit not set or Status not 0, save register byte, set the
15662      * err_code, and return an error.
15663      */
15664     AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15665     DvcSleepMilliSecond(10);  /* Wait for 10ms before checking status. */
15666
15667     byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15668     if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0)
15669     {
15670         /* Get here if Done bit not set or Status not 0. */
15671         asc_dvc->bist_err_code = byte;  /* for BIOS display message */
15672         asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15673         return ADV_ERROR;
15674     }
15675
15676     /* We need to reset back to normal mode after LRAM test passes. */
15677     AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15678
15679     /*
15680      * Load the Microcode
15681      *
15682      * Write the microcode image to RISC memory starting at address 0.
15683      *
15684      */
15685     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15686
15687     /* Assume the following compressed format of the microcode buffer:
15688      *
15689      *  254 word (508 byte) table indexed by byte code followed
15690      *  by the following byte codes:
15691      *
15692      *    1-Byte Code:
15693      *      00: Emit word 0 in table.
15694      *      01: Emit word 1 in table.
15695      *      .
15696      *      FD: Emit word 253 in table.
15697      *
15698      *    Multi-Byte Code:
15699      *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15700      *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15701      */
15702     word = 0;
15703     for (i = 253 * 2; i < _adv_asc38C0800_size; i++)
15704     {
15705         if (_adv_asc38C0800_buf[i] == 0xff)
15706         {
15707             for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++)
15708             {
15709                 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15710                     _adv_asc38C0800_buf[i + 3] << 8) |
15711                     _adv_asc38C0800_buf[i + 2]));
15712                 word++;
15713             }
15714             i += 3;
15715         } else if (_adv_asc38C0800_buf[i] == 0xfe)
15716         {
15717             AdvWriteWordAutoIncLram(iop_base, (((ushort)
15718                 _adv_asc38C0800_buf[i + 2] << 8) |
15719                 _adv_asc38C0800_buf[i + 1]));
15720             i += 2;
15721             word++;
15722         } else
15723         {
15724             AdvWriteWordAutoIncLram(iop_base, (((ushort)
15725                 _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) |
15726                 _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
15727             word++;
15728         }
15729     }
15730
15731     /*
15732      * Set 'word' for later use to clear the rest of memory and save
15733      * the expanded mcode size.
15734      */
15735     word *= 2;
15736     adv_asc38C0800_expanded_size = word;
15737
15738     /*
15739      * Clear the rest of ASC-38C0800 Internal RAM (16KB).
15740      */
15741     for (; word < ADV_38C0800_MEMSIZE; word += 2)
15742     {
15743         AdvWriteWordAutoIncLram(iop_base, 0);
15744     }
15745
15746     /*
15747      * Verify the microcode checksum.
15748      */
15749     sum = 0;
15750     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15751
15752     for (word = 0; word < adv_asc38C0800_expanded_size; word += 2)
15753     {
15754         sum += AdvReadWordAutoIncLram(iop_base);
15755     }
15756     ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
15757
15758     ASC_DBG2(1,
15759         "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
15760         (ulong) sum, (ulong) _adv_asc38C0800_chksum);
15761
15762     if (sum != _adv_asc38C0800_chksum)
15763     {
15764         asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15765         return ADV_ERROR;
15766     }
15767
15768     /*
15769      * Restore the RISC memory BIOS region.
15770      */
15771     for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15772     {
15773         AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15774     }
15775
15776     /*
15777      * Calculate and write the microcode code checksum to the microcode
15778      * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15779      */
15780     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15781     AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15782     code_sum = 0;
15783     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15784     for (word = begin_addr; word < end_addr; word += 2)
15785     {
15786         code_sum += AdvReadWordAutoIncLram(iop_base);
15787     }
15788     AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15789
15790     /*
15791      * Read microcode version and date.
15792      */
15793     AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
15794     AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
15795
15796     /*
15797      * Set the chip type to indicate the ASC38C0800.
15798      */
15799     AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
15800
15801     /*
15802      * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15803      * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15804      * cable detection and then we are able to read C_DET[3:0].
15805      *
15806      * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15807      * Microcode Default Value' section below.
15808      */
15809     scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15810     AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV);
15811
15812     /*
15813      * If the PCI Configuration Command Register "Parity Error Response
15814      * Control" Bit was clear (0), then set the microcode variable
15815      * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15816      * to ignore DMA parity errors.
15817      */
15818     if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
15819     {
15820         AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15821         word |= CONTROL_FLAG_IGNORE_PERR;
15822         AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15823     }
15824
15825     /*
15826      * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
15827      * bits for the default FIFO threshold.
15828      *
15829      * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
15830      *
15831      * For DMA Errata #4 set the BC_THRESH_ENB bit.
15832      */
15833     AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15834         BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
15835
15836     /*
15837      * Microcode operating variables for WDTR, SDTR, and command tag
15838      * queuing will be set in AdvInquiryHandling() based on what a
15839      * device reports it is capable of in Inquiry byte 7.
15840      *
15841      * If SCSI Bus Resets have been disabled, then directly set
15842      * SDTR and WDTR from the EEPROM configuration. This will allow
15843      * the BIOS and warm boot to work without a SCSI bus hang on
15844      * the Inquiry caused by host and target mismatched DTR values.
15845      * Without the SCSI Bus Reset, before an Inquiry a device can't
15846      * be assumed to be in Asynchronous, Narrow mode.
15847      */
15848     if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
15849     {
15850         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
15851         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
15852     }
15853
15854     /*
15855      * Set microcode operating variables for DISC and SDTR_SPEED1,
15856      * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15857      * configuration values.
15858      *
15859      * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15860      * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15861      * without determining here whether the device supports SDTR.
15862      */
15863     AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
15864     AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15865     AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15866     AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15867     AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15868
15869     /*
15870      * Set SCSI_CFG0 Microcode Default Value.
15871      *
15872      * The microcode will set the SCSI_CFG0 register using this value
15873      * after it is started below.
15874      */
15875     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15876         PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15877         asc_dvc->chip_scsi_id);
15878
15879     /*
15880      * Determine SCSI_CFG1 Microcode Default Value.
15881      *
15882      * The microcode will set the SCSI_CFG1 register using this value
15883      * after it is started below.
15884      */
15885
15886     /* Read current SCSI_CFG1 Register value. */
15887     scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15888
15889     /*
15890      * If the internal narrow cable is reversed all of the SCSI_CTRL
15891      * register signals will be set. Check for and return an error if
15892      * this condition is found.
15893      */
15894     if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
15895     {
15896         asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15897         return ADV_ERROR;
15898     }
15899
15900     /*
15901      * All kind of combinations of devices attached to one of four connectors
15902      * are acceptable except HVD device attached. For example, LVD device can
15903      * be attached to SE connector while SE device attached to LVD connector.
15904      * If LVD device attached to SE connector, it only runs up to Ultra speed.
15905      *
15906      * If an HVD device is attached to one of LVD connectors, return an error.
15907      * However, there is no way to detect HVD device attached to SE connectors.
15908      */
15909     if (scsi_cfg1 & HVD)
15910     {
15911         asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15912         return ADV_ERROR;
15913     }
15914
15915     /*
15916      * If either SE or LVD automatic termination control is enabled, then
15917      * set the termination value based on a table listed in a_condor.h.
15918      *
15919      * If manual termination was specified with an EEPROM setting then
15920      * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
15921      * be 'ored' into SCSI_CFG1.
15922      */
15923     if ((asc_dvc->cfg->termination & TERM_SE) == 0)
15924     {
15925         /* SE automatic termination control is enabled. */
15926         switch(scsi_cfg1 & C_DET_SE)
15927         {
15928             /* TERM_SE_HI: on, TERM_SE_LO: on */
15929             case 0x1: case 0x2: case 0x3:
15930                 asc_dvc->cfg->termination |= TERM_SE;
15931                 break;
15932
15933             /* TERM_SE_HI: on, TERM_SE_LO: off */
15934             case 0x0:
15935                 asc_dvc->cfg->termination |= TERM_SE_HI;
15936                 break;
15937         }
15938     }
15939
15940     if ((asc_dvc->cfg->termination & TERM_LVD) == 0)
15941     {
15942         /* LVD automatic termination control is enabled. */
15943         switch(scsi_cfg1 & C_DET_LVD)
15944         {
15945             /* TERM_LVD_HI: on, TERM_LVD_LO: on */
15946             case 0x4: case 0x8: case 0xC:
15947                 asc_dvc->cfg->termination |= TERM_LVD;
15948                 break;
15949
15950             /* TERM_LVD_HI: off, TERM_LVD_LO: off */
15951             case 0x0:
15952                 break;
15953         }
15954     }
15955
15956     /*
15957      * Clear any set TERM_SE and TERM_LVD bits.
15958      */
15959     scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
15960
15961     /*
15962      * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
15963      */
15964     scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
15965
15966     /*
15967      * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
15968      * and set possibly modified termination control bits in the Microcode
15969      * SCSI_CFG1 Register Value.
15970      */
15971     scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
15972
15973     /*
15974      * Set SCSI_CFG1 Microcode Default Value
15975      *
15976      * Set possibly modified termination control and reset DIS_TERM_DRV
15977      * bits in the Microcode SCSI_CFG1 Register Value.
15978      *
15979      * The microcode will set the SCSI_CFG1 register using this value
15980      * after it is started below.
15981      */
15982     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15983
15984     /*
15985      * Set MEM_CFG Microcode Default Value
15986      *
15987      * The microcode will set the MEM_CFG register using this value
15988      * after it is started below.
15989      *
15990      * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15991      * are defined.
15992      *
15993      * ASC-38C0800 has 16KB internal memory.
15994      */
15995     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15996         BIOS_EN | RAM_SZ_16KB);
15997
15998     /*
15999      * Set SEL_MASK Microcode Default Value
16000      *
16001      * The microcode will set the SEL_MASK register using this value
16002      * after it is started below.
16003      */
16004     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
16005         ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
16006
16007     /*
16008      * Build the carrier freelist.
16009      *
16010      * Driver must have already allocated memory and set 'carrier_buf'.
16011      */
16012     ASC_ASSERT(asc_dvc->carrier_buf != NULL);
16013
16014     carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
16015     asc_dvc->carr_freelist = NULL;
16016     if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
16017     {
16018         buf_size = ADV_CARRIER_BUFSIZE;
16019     } else
16020     {
16021         buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
16022     }
16023
16024     do {
16025         /*
16026          * Get physical address for the carrier 'carrp'.
16027          */
16028         contig_len = sizeof(ADV_CARR_T);
16029         carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
16030             (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
16031
16032         buf_size -= sizeof(ADV_CARR_T);
16033
16034         /*
16035          * If the current carrier is not physically contiguous, then
16036          * maybe there was a page crossing. Try the next carrier aligned
16037          * start address.
16038          */
16039         if (contig_len < sizeof(ADV_CARR_T))
16040         {
16041             carrp++;
16042             continue;
16043         }
16044
16045         carrp->carr_pa = carr_paddr;
16046         carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
16047
16048         /*
16049          * Insert the carrier at the beginning of the freelist.
16050          */
16051         carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
16052         asc_dvc->carr_freelist = carrp;
16053
16054         carrp++;
16055     }
16056     while (buf_size > 0);
16057
16058     /*
16059      * Set-up the Host->RISC Initiator Command Queue (ICQ).
16060      */
16061
16062     if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
16063     {
16064         asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16065         return ADV_ERROR;
16066     }
16067     asc_dvc->carr_freelist = (ADV_CARR_T *)
16068         ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
16069
16070     /*
16071      * The first command issued will be placed in the stopper carrier.
16072      */
16073     asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16074
16075     /*
16076      * Set RISC ICQ physical address start value.
16077      * carr_pa is LE, must be native before write
16078      */
16079     AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
16080
16081     /*
16082      * Set-up the RISC->Host Initiator Response Queue (IRQ).
16083      */
16084     if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
16085     {
16086         asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16087         return ADV_ERROR;
16088     }
16089     asc_dvc->carr_freelist = (ADV_CARR_T *)
16090         ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
16091
16092     /*
16093      * The first command completed by the RISC will be placed in
16094      * the stopper.
16095      *
16096      * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
16097      * completed the RISC will set the ASC_RQ_STOPPER bit.
16098      */
16099     asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16100
16101     /*
16102      * Set RISC IRQ physical address start value.
16103      *
16104      * carr_pa is LE, must be native before write *
16105      */
16106     AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
16107     asc_dvc->carr_pending_cnt = 0;
16108
16109     AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
16110         (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
16111
16112     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
16113     AdvWriteWordRegister(iop_base, IOPW_PC, word);
16114
16115     /* finally, finally, gentlemen, start your engine */
16116     AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
16117
16118     /*
16119      * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
16120      * Resets should be performed. The RISC has to be running
16121      * to issue a SCSI Bus Reset.
16122      */
16123     if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
16124     {
16125         /*
16126          * If the BIOS Signature is present in memory, restore the
16127          * BIOS Handshake Configuration Table and do not perform
16128          * a SCSI Bus Reset.
16129          */
16130         if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
16131         {
16132             /*
16133              * Restore per TID negotiated values.
16134              */
16135             AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16136             AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16137             AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16138             for (tid = 0; tid <= ADV_MAX_TID; tid++)
16139             {
16140                 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16141                     max_cmd[tid]);
16142             }
16143         } else
16144         {
16145             if (AdvResetSB(asc_dvc) != ADV_TRUE)
16146             {
16147                 warn_code = ASC_WARN_BUSRESET_ERROR;
16148             }
16149         }
16150     }
16151
16152     return warn_code;
16153 }
16154
16155 /*
16156  * Initialize the ASC-38C1600.
16157  *
16158  * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
16159  *
16160  * For a non-fatal error return a warning code. If there are no warnings
16161  * then 0 is returned.
16162  *
16163  * Needed after initialization for error recovery.
16164  */
16165 STATIC int
16166 AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
16167 {
16168     AdvPortAddr iop_base;
16169     ushort      warn_code;
16170     ADV_DCNT    sum;
16171     int         begin_addr;
16172     int         end_addr;
16173     ushort      code_sum;
16174     long        word;
16175     int         j;
16176     int         adv_asc38C1600_expanded_size;
16177     ADV_CARR_T  *carrp;
16178     ADV_DCNT    contig_len;
16179     ADV_SDCNT   buf_size;
16180     ADV_PADDR   carr_paddr;
16181     int         i;
16182     ushort      scsi_cfg1;
16183     uchar       byte;
16184     uchar       tid;
16185     ushort      bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
16186     ushort      wdtr_able, sdtr_able, ppr_able, tagqng_able;
16187     uchar       max_cmd[ASC_MAX_TID + 1];
16188
16189     /* If there is already an error, don't continue. */
16190     if (asc_dvc->err_code != 0)
16191     {
16192         return ADV_ERROR;
16193     }
16194
16195     /*
16196      * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
16197      */
16198     if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600)
16199     {
16200         asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
16201         return ADV_ERROR;
16202     }
16203
16204     warn_code = 0;
16205     iop_base = asc_dvc->iop_base;
16206
16207     /*
16208      * Save the RISC memory BIOS region before writing the microcode.
16209      * The BIOS may already be loaded and using its RISC LRAM region
16210      * so its region must be saved and restored.
16211      *
16212      * Note: This code makes the assumption, which is currently true,
16213      * that a chip reset does not clear RISC LRAM.
16214      */
16215     for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
16216     {
16217         AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
16218     }
16219
16220     /*
16221      * Save current per TID negotiated values.
16222      */
16223     AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16224     AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16225     AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16226     AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16227     for (tid = 0; tid <= ASC_MAX_TID; tid++)
16228     {
16229         AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16230             max_cmd[tid]);
16231     }
16232
16233     /*
16234      * RAM BIST (Built-In Self Test)
16235      *
16236      * Address : I/O base + offset 0x38h register (byte).
16237      * Function: Bit 7-6(RW) : RAM mode
16238      *                          Normal Mode   : 0x00
16239      *                          Pre-test Mode : 0x40
16240      *                          RAM Test Mode : 0x80
16241      *           Bit 5       : unused
16242      *           Bit 4(RO)   : Done bit
16243      *           Bit 3-0(RO) : Status
16244      *                          Host Error    : 0x08
16245      *                          Int_RAM Error : 0x04
16246      *                          RISC Error    : 0x02
16247      *                          SCSI Error    : 0x01
16248      *                          No Error      : 0x00
16249      *
16250      * Note: RAM BIST code should be put right here, before loading the
16251      * microcode and after saving the RISC memory BIOS region.
16252      */
16253
16254     /*
16255      * LRAM Pre-test
16256      *
16257      * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
16258      * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
16259      * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
16260      * to NORMAL_MODE, return an error too.
16261      */
16262     for (i = 0; i < 2; i++)
16263     {
16264         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
16265         DvcSleepMilliSecond(10);  /* Wait for 10ms before reading back. */
16266         byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
16267         if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE)
16268         {
16269             asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
16270             return ADV_ERROR;
16271         }
16272
16273         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
16274         DvcSleepMilliSecond(10);  /* Wait for 10ms before reading back. */
16275         if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
16276             != NORMAL_VALUE)
16277         {
16278             asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
16279             return ADV_ERROR;
16280         }
16281     }
16282
16283     /*
16284      * LRAM Test - It takes about 1.5 ms to run through the test.
16285      *
16286      * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
16287      * If Done bit not set or Status not 0, save register byte, set the
16288      * err_code, and return an error.
16289      */
16290     AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
16291     DvcSleepMilliSecond(10);  /* Wait for 10ms before checking status. */
16292
16293     byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
16294     if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0)
16295     {
16296         /* Get here if Done bit not set or Status not 0. */
16297         asc_dvc->bist_err_code = byte;  /* for BIOS display message */
16298         asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
16299         return ADV_ERROR;
16300     }
16301
16302     /* We need to reset back to normal mode after LRAM test passes. */
16303     AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
16304
16305     /*
16306      * Load the Microcode
16307      *
16308      * Write the microcode image to RISC memory starting at address 0.
16309      *
16310      */
16311     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
16312
16313     /*
16314      * Assume the following compressed format of the microcode buffer:
16315      *
16316      *  254 word (508 byte) table indexed by byte code followed
16317      *  by the following byte codes:
16318      *
16319      *    1-Byte Code:
16320      *      00: Emit word 0 in table.
16321      *      01: Emit word 1 in table.
16322      *      .
16323      *      FD: Emit word 253 in table.
16324      *
16325      *    Multi-Byte Code:
16326      *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
16327      *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
16328      */
16329     word = 0;
16330     for (i = 253 * 2; i < _adv_asc38C1600_size; i++)
16331     {
16332         if (_adv_asc38C1600_buf[i] == 0xff)
16333         {
16334             for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++)
16335             {
16336                 AdvWriteWordAutoIncLram(iop_base, (((ushort)
16337                      _adv_asc38C1600_buf[i + 3] << 8) |
16338                      _adv_asc38C1600_buf[i + 2]));
16339                 word++;
16340             }
16341            i += 3;
16342         } else if (_adv_asc38C1600_buf[i] == 0xfe)
16343         {
16344                 AdvWriteWordAutoIncLram(iop_base, (((ushort)
16345                      _adv_asc38C1600_buf[i + 2] << 8) |
16346                      _adv_asc38C1600_buf[i + 1]));
16347             i += 2;
16348             word++;
16349         } else
16350         {
16351             AdvWriteWordAutoIncLram(iop_base, (((ushort)
16352                  _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) |
16353                  _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
16354             word++;
16355         }
16356     }
16357
16358     /*
16359      * Set 'word' for later use to clear the rest of memory and save
16360      * the expanded mcode size.
16361      */
16362     word *= 2;
16363     adv_asc38C1600_expanded_size = word;
16364
16365     /*
16366      * Clear the rest of ASC-38C1600 Internal RAM (32KB).
16367      */
16368     for (; word < ADV_38C1600_MEMSIZE; word += 2)
16369     {
16370         AdvWriteWordAutoIncLram(iop_base, 0);
16371     }
16372
16373     /*
16374      * Verify the microcode checksum.
16375      */
16376     sum = 0;
16377     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
16378
16379     for (word = 0; word < adv_asc38C1600_expanded_size; word += 2)
16380     {
16381         sum += AdvReadWordAutoIncLram(iop_base);
16382     }
16383
16384     if (sum != _adv_asc38C1600_chksum)
16385     {
16386         asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
16387         return ADV_ERROR;
16388     }
16389
16390     /*
16391      * Restore the RISC memory BIOS region.
16392      */
16393     for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
16394     {
16395         AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
16396     }
16397
16398     /*
16399      * Calculate and write the microcode code checksum to the microcode
16400      * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
16401      */
16402     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
16403     AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
16404     code_sum = 0;
16405     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
16406     for (word = begin_addr; word < end_addr; word += 2)
16407     {
16408         code_sum += AdvReadWordAutoIncLram(iop_base);
16409     }
16410     AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
16411
16412     /*
16413      * Read microcode version and date.
16414      */
16415     AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
16416     AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
16417
16418     /*
16419      * Set the chip type to indicate the ASC38C1600.
16420      */
16421     AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
16422
16423     /*
16424      * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
16425      * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
16426      * cable detection and then we are able to read C_DET[3:0].
16427      *
16428      * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
16429      * Microcode Default Value' section below.
16430      */
16431     scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
16432     AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV);
16433
16434     /*
16435      * If the PCI Configuration Command Register "Parity Error Response
16436      * Control" Bit was clear (0), then set the microcode variable
16437      * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
16438      * to ignore DMA parity errors.
16439      */
16440     if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
16441     {
16442         AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16443         word |= CONTROL_FLAG_IGNORE_PERR;
16444         AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16445     }
16446
16447     /*
16448      * If the BIOS control flag AIPP (Asynchronous Information
16449      * Phase Protection) disable bit is not set, then set the firmware
16450      * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
16451      * AIPP checking and encoding.
16452      */
16453     if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0)
16454     {
16455         AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16456         word |= CONTROL_FLAG_ENABLE_AIPP;
16457         AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16458     }
16459
16460     /*
16461      * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
16462      * and START_CTL_TH [3:2].
16463      */
16464     AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
16465         FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
16466
16467     /*
16468      * Microcode operating variables for WDTR, SDTR, and command tag
16469      * queuing will be set in AdvInquiryHandling() based on what a
16470      * device reports it is capable of in Inquiry byte 7.
16471      *
16472      * If SCSI Bus Resets have been disabled, then directly set
16473      * SDTR and WDTR from the EEPROM configuration. This will allow
16474      * the BIOS and warm boot to work without a SCSI bus hang on
16475      * the Inquiry caused by host and target mismatched DTR values.
16476      * Without the SCSI Bus Reset, before an Inquiry a device can't
16477      * be assumed to be in Asynchronous, Narrow mode.
16478      */
16479     if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
16480     {
16481         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
16482         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
16483     }
16484
16485     /*
16486      * Set microcode operating variables for DISC and SDTR_SPEED1,
16487      * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
16488      * configuration values.
16489      *
16490      * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
16491      * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
16492      * without determining here whether the device supports SDTR.
16493      */
16494     AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
16495     AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
16496     AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
16497     AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
16498     AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
16499
16500     /*
16501      * Set SCSI_CFG0 Microcode Default Value.
16502      *
16503      * The microcode will set the SCSI_CFG0 register using this value
16504      * after it is started below.
16505      */
16506     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
16507         PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
16508         asc_dvc->chip_scsi_id);
16509
16510     /*
16511      * Calculate SCSI_CFG1 Microcode Default Value.
16512      *
16513      * The microcode will set the SCSI_CFG1 register using this value
16514      * after it is started below.
16515      *
16516      * Each ASC-38C1600 function has only two cable detect bits.
16517      * The bus mode override bits are in IOPB_SOFT_OVER_WR.
16518      */
16519     scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
16520
16521     /*
16522      * If the cable is reversed all of the SCSI_CTRL register signals
16523      * will be set. Check for and return an error if this condition is
16524      * found.
16525      */
16526     if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
16527     {
16528         asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
16529         return ADV_ERROR;
16530     }
16531
16532     /*
16533      * Each ASC-38C1600 function has two connectors. Only an HVD device
16534      * can not be connected to either connector. An LVD device or SE device
16535      * may be connected to either connecor. If an SE device is connected,
16536      * then at most Ultra speed (20 Mhz) can be used on both connectors.
16537      *
16538      * If an HVD device is attached, return an error.
16539      */
16540     if (scsi_cfg1 & HVD)
16541     {
16542         asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
16543         return ADV_ERROR;
16544     }
16545
16546     /*
16547      * Each function in the ASC-38C1600 uses only the SE cable detect and
16548      * termination because there are two connectors for each function. Each
16549      * function may use either LVD or SE mode. Corresponding the SE automatic
16550      * termination control EEPROM bits are used for each function. Each
16551      * function has its own EEPROM. If SE automatic control is enabled for
16552      * the function, then set the termination value based on a table listed
16553      * in a_condor.h.
16554      *
16555      * If manual termination is specified in the EEPROM for the function,
16556      * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
16557      * ready to be 'ored' into SCSI_CFG1.
16558      */
16559     if ((asc_dvc->cfg->termination & TERM_SE) == 0)
16560     {
16561         /* SE automatic termination control is enabled. */
16562         switch(scsi_cfg1 & C_DET_SE)
16563         {
16564             /* TERM_SE_HI: on, TERM_SE_LO: on */
16565             case 0x1: case 0x2: case 0x3:
16566                 asc_dvc->cfg->termination |= TERM_SE;
16567                 break;
16568
16569             case 0x0:
16570                 if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0)
16571                 {
16572                     /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
16573                 }
16574                 else
16575                 {
16576                     /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
16577                     asc_dvc->cfg->termination |= TERM_SE_HI;
16578                 }
16579                 break;
16580         }
16581     }
16582
16583     /*
16584      * Clear any set TERM_SE bits.
16585      */
16586     scsi_cfg1 &= ~TERM_SE;
16587
16588     /*
16589      * Invert the TERM_SE bits and then set 'scsi_cfg1'.
16590      */
16591     scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
16592
16593     /*
16594      * Clear Big Endian and Terminator Polarity bits and set possibly
16595      * modified termination control bits in the Microcode SCSI_CFG1
16596      * Register Value.
16597      *
16598      * Big Endian bit is not used even on big endian machines.
16599      */
16600     scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
16601
16602     /*
16603      * Set SCSI_CFG1 Microcode Default Value
16604      *
16605      * Set possibly modified termination control bits in the Microcode
16606      * SCSI_CFG1 Register Value.
16607      *
16608      * The microcode will set the SCSI_CFG1 register using this value
16609      * after it is started below.
16610      */
16611     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
16612
16613     /*
16614      * Set MEM_CFG Microcode Default Value
16615      *
16616      * The microcode will set the MEM_CFG register using this value
16617      * after it is started below.
16618      *
16619      * MEM_CFG may be accessed as a word or byte, but only bits 0-7
16620      * are defined.
16621      *
16622      * ASC-38C1600 has 32KB internal memory.
16623      *
16624      * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
16625      * out a special 16K Adv Library and Microcode version. After the issue
16626      * resolved, we should turn back to the 32K support. Both a_condor.h and
16627      * mcode.sas files also need to be updated.
16628      *
16629      * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
16630      *  BIOS_EN | RAM_SZ_32KB);
16631      */
16632      AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, BIOS_EN | RAM_SZ_16KB);
16633
16634     /*
16635      * Set SEL_MASK Microcode Default Value
16636      *
16637      * The microcode will set the SEL_MASK register using this value
16638      * after it is started below.
16639      */
16640     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
16641         ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
16642
16643     /*
16644      * Build the carrier freelist.
16645      *
16646      * Driver must have already allocated memory and set 'carrier_buf'.
16647      */
16648
16649     ASC_ASSERT(asc_dvc->carrier_buf != NULL);
16650
16651     carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
16652     asc_dvc->carr_freelist = NULL;
16653     if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
16654     {
16655         buf_size = ADV_CARRIER_BUFSIZE;
16656     } else
16657     {
16658         buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
16659     }
16660
16661     do {
16662         /*
16663          * Get physical address for the carrier 'carrp'.
16664          */
16665         contig_len = sizeof(ADV_CARR_T);
16666         carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
16667             (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
16668
16669         buf_size -= sizeof(ADV_CARR_T);
16670
16671         /*
16672          * If the current carrier is not physically contiguous, then
16673          * maybe there was a page crossing. Try the next carrier aligned
16674          * start address.
16675          */
16676         if (contig_len < sizeof(ADV_CARR_T))
16677         {
16678             carrp++;
16679             continue;
16680         }
16681
16682         carrp->carr_pa = carr_paddr;
16683         carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
16684
16685         /*
16686          * Insert the carrier at the beginning of the freelist.
16687          */
16688         carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
16689         asc_dvc->carr_freelist = carrp;
16690
16691         carrp++;
16692     }
16693     while (buf_size > 0);
16694
16695     /*
16696      * Set-up the Host->RISC Initiator Command Queue (ICQ).
16697      */
16698     if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
16699     {
16700         asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16701         return ADV_ERROR;
16702     }
16703     asc_dvc->carr_freelist = (ADV_CARR_T *)
16704         ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
16705
16706     /*
16707      * The first command issued will be placed in the stopper carrier.
16708      */
16709     asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16710
16711     /*
16712      * Set RISC ICQ physical address start value. Initialize the
16713      * COMMA register to the same value otherwise the RISC will
16714      * prematurely detect a command is available.
16715      */
16716     AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
16717     AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
16718         le32_to_cpu(asc_dvc->icq_sp->carr_pa));
16719
16720     /*
16721      * Set-up the RISC->Host Initiator Response Queue (IRQ).
16722      */
16723     if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
16724     {
16725         asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16726         return ADV_ERROR;
16727     }
16728     asc_dvc->carr_freelist = (ADV_CARR_T *)
16729         ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
16730
16731     /*
16732      * The first command completed by the RISC will be placed in
16733      * the stopper.
16734      *
16735      * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
16736      * completed the RISC will set the ASC_RQ_STOPPER bit.
16737      */
16738     asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16739
16740     /*
16741      * Set RISC IRQ physical address start value.
16742      */
16743     AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
16744     asc_dvc->carr_pending_cnt = 0;
16745
16746     AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
16747         (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
16748     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
16749     AdvWriteWordRegister(iop_base, IOPW_PC, word);
16750
16751     /* finally, finally, gentlemen, start your engine */
16752     AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
16753
16754     /*
16755      * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
16756      * Resets should be performed. The RISC has to be running
16757      * to issue a SCSI Bus Reset.
16758      */
16759     if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
16760     {
16761         /*
16762          * If the BIOS Signature is present in memory, restore the
16763          * per TID microcode operating variables.
16764          */
16765         if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
16766         {
16767             /*
16768              * Restore per TID negotiated values.
16769              */
16770             AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16771             AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16772             AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16773             AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16774             for (tid = 0; tid <= ASC_MAX_TID; tid++)
16775             {
16776                 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16777                     max_cmd[tid]);
16778             }
16779         } else
16780         {
16781             if (AdvResetSB(asc_dvc) != ADV_TRUE)
16782             {
16783                 warn_code = ASC_WARN_BUSRESET_ERROR;
16784             }
16785         }
16786     }
16787
16788     return warn_code;
16789 }
16790
16791 /*
16792  * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16793  * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16794  * all of this is done.
16795  *
16796  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16797  *
16798  * For a non-fatal error return a warning code. If there are no warnings
16799  * then 0 is returned.
16800  *
16801  * Note: Chip is stopped on entry.
16802  */
16803 ASC_INITFUNC(
16804 STATIC int,
16805 AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
16806 )
16807 {
16808     AdvPortAddr         iop_base;
16809     ushort              warn_code;
16810     ADVEEP_3550_CONFIG  eep_config;
16811     int                 i;
16812
16813     iop_base = asc_dvc->iop_base;
16814
16815     warn_code = 0;
16816
16817     /*
16818      * Read the board's EEPROM configuration.
16819      *
16820      * Set default values if a bad checksum is found.
16821      */
16822     if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16823     {
16824         warn_code |= ASC_WARN_EEPROM_CHKSUM;
16825
16826         /*
16827          * Set EEPROM default values.
16828          */
16829         for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++)
16830         {
16831             *((uchar *) &eep_config + i) =
16832                 *((uchar *) &Default_3550_EEPROM_Config + i);
16833         }
16834
16835         /*
16836          * Assume the 6 byte board serial number that was read
16837          * from EEPROM is correct even if the EEPROM checksum
16838          * failed.
16839          */
16840         eep_config.serial_number_word3 =
16841             AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16842
16843         eep_config.serial_number_word2 =
16844             AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16845
16846         eep_config.serial_number_word1 =
16847             AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16848
16849         AdvSet3550EEPConfig(iop_base, &eep_config);
16850     }
16851     /*
16852      * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16853      * EEPROM configuration that was read.
16854      *
16855      * This is the mapping of EEPROM fields to Adv Library fields.
16856      */
16857     asc_dvc->wdtr_able = eep_config.wdtr_able;
16858     asc_dvc->sdtr_able = eep_config.sdtr_able;
16859     asc_dvc->ultra_able = eep_config.ultra_able;
16860     asc_dvc->tagqng_able = eep_config.tagqng_able;
16861     asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16862     asc_dvc->max_host_qng = eep_config.max_host_qng;
16863     asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16864     asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16865     asc_dvc->start_motor = eep_config.start_motor;
16866     asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16867     asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16868     asc_dvc->no_scam = eep_config.scam_tolerant;
16869     asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16870     asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16871     asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16872
16873     /*
16874      * Set the host maximum queuing (max. 253, min. 16) and the per device
16875      * maximum queuing (max. 63, min. 4).
16876      */
16877     if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
16878     {
16879         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16880     } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
16881     {
16882         /* If the value is zero, assume it is uninitialized. */
16883         if (eep_config.max_host_qng == 0)
16884         {
16885             eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16886         } else
16887         {
16888             eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16889         }
16890     }
16891
16892     if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
16893     {
16894         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16895     } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
16896     {
16897         /* If the value is zero, assume it is uninitialized. */
16898         if (eep_config.max_dvc_qng == 0)
16899         {
16900             eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16901         } else
16902         {
16903             eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16904         }
16905     }
16906
16907     /*
16908      * If 'max_dvc_qng' is greater than 'max_host_qng', then
16909      * set 'max_dvc_qng' to 'max_host_qng'.
16910      */
16911     if (eep_config.max_dvc_qng > eep_config.max_host_qng)
16912     {
16913         eep_config.max_dvc_qng = eep_config.max_host_qng;
16914     }
16915
16916     /*
16917      * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16918      * values based on possibly adjusted EEPROM values.
16919      */
16920     asc_dvc->max_host_qng = eep_config.max_host_qng;
16921     asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16922
16923
16924     /*
16925      * If the EEPROM 'termination' field is set to automatic (0), then set
16926      * the ADV_DVC_CFG 'termination' field to automatic also.
16927      *
16928      * If the termination is specified with a non-zero 'termination'
16929      * value check that a legal value is set and set the ADV_DVC_CFG
16930      * 'termination' field appropriately.
16931      */
16932     if (eep_config.termination == 0)
16933     {
16934         asc_dvc->cfg->termination = 0;    /* auto termination */
16935     } else
16936     {
16937         /* Enable manual control with low off / high off. */
16938         if (eep_config.termination == 1)
16939         {
16940             asc_dvc->cfg->termination = TERM_CTL_SEL;
16941
16942         /* Enable manual control with low off / high on. */
16943         } else if (eep_config.termination == 2)
16944         {
16945             asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
16946
16947         /* Enable manual control with low on / high on. */
16948         } else if (eep_config.termination == 3)
16949         {
16950             asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
16951         } else
16952         {
16953             /*
16954              * The EEPROM 'termination' field contains a bad value. Use
16955              * automatic termination instead.
16956              */
16957             asc_dvc->cfg->termination = 0;
16958             warn_code |= ASC_WARN_EEPROM_TERMINATION;
16959         }
16960     }
16961
16962     return warn_code;
16963 }
16964
16965 /*
16966  * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16967  * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16968  * all of this is done.
16969  *
16970  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16971  *
16972  * For a non-fatal error return a warning code. If there are no warnings
16973  * then 0 is returned.
16974  *
16975  * Note: Chip is stopped on entry.
16976  */
16977 ASC_INITFUNC(
16978 STATIC int,
16979 AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
16980 )
16981 {
16982     AdvPortAddr              iop_base;
16983     ushort                   warn_code;
16984     ADVEEP_38C0800_CONFIG    eep_config;
16985     int                      i;
16986     uchar                    tid, termination;
16987     ushort                   sdtr_speed = 0;
16988
16989     iop_base = asc_dvc->iop_base;
16990
16991     warn_code = 0;
16992
16993     /*
16994      * Read the board's EEPROM configuration.
16995      *
16996      * Set default values if a bad checksum is found.
16997      */
16998     if (AdvGet38C0800EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16999     {
17000         warn_code |= ASC_WARN_EEPROM_CHKSUM;
17001
17002         /*
17003          * Set EEPROM default values.
17004          */
17005         for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++)
17006         {
17007             *((uchar *) &eep_config + i) =
17008                 *((uchar *) &Default_38C0800_EEPROM_Config + i);
17009         }
17010
17011         /*
17012          * Assume the 6 byte board serial number that was read
17013          * from EEPROM is correct even if the EEPROM checksum
17014          * failed.
17015          */
17016         eep_config.serial_number_word3 =
17017             AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
17018
17019         eep_config.serial_number_word2 =
17020             AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
17021
17022         eep_config.serial_number_word1 =
17023             AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
17024
17025         AdvSet38C0800EEPConfig(iop_base, &eep_config);
17026     }
17027     /*
17028      * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
17029      * EEPROM configuration that was read.
17030      *
17031      * This is the mapping of EEPROM fields to Adv Library fields.
17032      */
17033     asc_dvc->wdtr_able = eep_config.wdtr_able;
17034     asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
17035     asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
17036     asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
17037     asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
17038     asc_dvc->tagqng_able = eep_config.tagqng_able;
17039     asc_dvc->cfg->disc_enable = eep_config.disc_enable;
17040     asc_dvc->max_host_qng = eep_config.max_host_qng;
17041     asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
17042     asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
17043     asc_dvc->start_motor = eep_config.start_motor;
17044     asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
17045     asc_dvc->bios_ctrl = eep_config.bios_ctrl;
17046     asc_dvc->no_scam = eep_config.scam_tolerant;
17047     asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
17048     asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
17049     asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
17050
17051     /*
17052      * For every Target ID if any of its 'sdtr_speed[1234]' bits
17053      * are set, then set an 'sdtr_able' bit for it.
17054      */
17055     asc_dvc->sdtr_able = 0;
17056     for (tid = 0; tid <= ADV_MAX_TID; tid++)
17057     {
17058         if (tid == 0)
17059         {
17060             sdtr_speed = asc_dvc->sdtr_speed1;
17061         } else if (tid == 4)
17062         {
17063             sdtr_speed = asc_dvc->sdtr_speed2;
17064         } else if (tid == 8)
17065         {
17066             sdtr_speed = asc_dvc->sdtr_speed3;
17067         } else if (tid == 12)
17068         {
17069             sdtr_speed = asc_dvc->sdtr_speed4;
17070         }
17071         if (sdtr_speed & ADV_MAX_TID)
17072         {
17073             asc_dvc->sdtr_able |= (1 << tid);
17074         }
17075         sdtr_speed >>= 4;
17076     }
17077
17078     /*
17079      * Set the host maximum queuing (max. 253, min. 16) and the per device
17080      * maximum queuing (max. 63, min. 4).
17081      */
17082     if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
17083     {
17084         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17085     } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
17086     {
17087         /* If the value is zero, assume it is uninitialized. */
17088         if (eep_config.max_host_qng == 0)
17089         {
17090             eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17091         } else
17092         {
17093             eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
17094         }
17095     }
17096
17097     if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
17098     {
17099         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17100     } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
17101     {
17102         /* If the value is zero, assume it is uninitialized. */
17103         if (eep_config.max_dvc_qng == 0)
17104         {
17105             eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17106         } else
17107         {
17108             eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
17109         }
17110     }
17111
17112     /*
17113      * If 'max_dvc_qng' is greater than 'max_host_qng', then
17114      * set 'max_dvc_qng' to 'max_host_qng'.
17115      */
17116     if (eep_config.max_dvc_qng > eep_config.max_host_qng)
17117     {
17118         eep_config.max_dvc_qng = eep_config.max_host_qng;
17119     }
17120
17121     /*
17122      * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
17123      * values based on possibly adjusted EEPROM values.
17124      */
17125     asc_dvc->max_host_qng = eep_config.max_host_qng;
17126     asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
17127
17128     /*
17129      * If the EEPROM 'termination' field is set to automatic (0), then set
17130      * the ADV_DVC_CFG 'termination' field to automatic also.
17131      *
17132      * If the termination is specified with a non-zero 'termination'
17133      * value check that a legal value is set and set the ADV_DVC_CFG
17134      * 'termination' field appropriately.
17135      */
17136     if (eep_config.termination_se == 0)
17137     {
17138         termination = 0;                         /* auto termination for SE */
17139     } else
17140     {
17141         /* Enable manual control with low off / high off. */
17142         if (eep_config.termination_se == 1)
17143         {
17144             termination = 0;
17145
17146         /* Enable manual control with low off / high on. */
17147         } else if (eep_config.termination_se == 2)
17148         {
17149             termination = TERM_SE_HI;
17150
17151         /* Enable manual control with low on / high on. */
17152         } else if (eep_config.termination_se == 3)
17153         {
17154             termination = TERM_SE;
17155         } else
17156         {
17157             /*
17158              * The EEPROM 'termination_se' field contains a bad value.
17159              * Use automatic termination instead.
17160              */
17161             termination = 0;
17162             warn_code |= ASC_WARN_EEPROM_TERMINATION;
17163         }
17164     }
17165
17166     if (eep_config.termination_lvd == 0)
17167     {
17168         asc_dvc->cfg->termination = termination; /* auto termination for LVD */
17169     } else
17170     {
17171         /* Enable manual control with low off / high off. */
17172         if (eep_config.termination_lvd == 1)
17173         {
17174             asc_dvc->cfg->termination = termination;
17175
17176         /* Enable manual control with low off / high on. */
17177         } else if (eep_config.termination_lvd == 2)
17178         {
17179             asc_dvc->cfg->termination = termination | TERM_LVD_HI;
17180
17181         /* Enable manual control with low on / high on. */
17182         } else if (eep_config.termination_lvd == 3)
17183         {
17184             asc_dvc->cfg->termination =
17185                 termination | TERM_LVD;
17186         } else
17187         {
17188             /*
17189              * The EEPROM 'termination_lvd' field contains a bad value.
17190              * Use automatic termination instead.
17191              */
17192             asc_dvc->cfg->termination = termination;
17193             warn_code |= ASC_WARN_EEPROM_TERMINATION;
17194         }
17195     }
17196
17197     return warn_code;
17198 }
17199
17200 /*
17201  * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
17202  * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
17203  * all of this is done.
17204  *
17205  * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
17206  *
17207  * For a non-fatal error return a warning code. If there are no warnings
17208  * then 0 is returned.
17209  *
17210  * Note: Chip is stopped on entry.
17211  */
17212 ASC_INITFUNC(
17213 STATIC int,
17214 AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
17215 )
17216 {
17217     AdvPortAddr              iop_base;
17218     ushort                   warn_code;
17219     ADVEEP_38C1600_CONFIG    eep_config;
17220     int                      i;
17221     uchar                    tid, termination;
17222     ushort                   sdtr_speed = 0;
17223
17224     iop_base = asc_dvc->iop_base;
17225
17226     warn_code = 0;
17227
17228     /*
17229      * Read the board's EEPROM configuration.
17230      *
17231      * Set default values if a bad checksum is found.
17232      */
17233     if (AdvGet38C1600EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
17234     {
17235         warn_code |= ASC_WARN_EEPROM_CHKSUM;
17236
17237         /*
17238          * Set EEPROM default values.
17239          */
17240         for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++)
17241         {
17242             if (i == 1 && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) != 0)
17243             {
17244                 /*
17245                  * Set Function 1 EEPROM Word 0 MSB
17246                  *
17247                  * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11)
17248                  * EEPROM bits.
17249                  *
17250                  * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and
17251                  * old Mac system booting problem. The Expansion ROM must
17252                  * be disabled in Function 1 for these systems.
17253                  *
17254                  */
17255                 *((uchar *) &eep_config + i) =
17256                 ((*((uchar *) &Default_38C1600_EEPROM_Config + i)) &
17257                     (~(((ADV_EEPROM_BIOS_ENABLE | ADV_EEPROM_INTAB) >> 8) &
17258                      0xFF)));
17259
17260                 /*
17261                  * Set the INTAB (bit 11) if the GPIO 0 input indicates
17262                  * the Function 1 interrupt line is wired to INTA.
17263                  *
17264                  * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
17265                  *   1 - Function 1 interrupt line wired to INT A.
17266                  *   0 - Function 1 interrupt line wired to INT B.
17267                  *
17268                  * Note: Adapter boards always have Function 0 wired to INTA.
17269                  * Put all 5 GPIO bits in input mode and then read
17270                  * their input values.
17271                  */
17272                 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
17273                 if (AdvReadByteRegister(iop_base, IOPB_GPIO_DATA) & 0x01)
17274                 {
17275                     /* Function 1 interrupt wired to INTA; Set EEPROM bit. */
17276                 *((uchar *) &eep_config + i) |=
17277                     ((ADV_EEPROM_INTAB >> 8) & 0xFF);
17278                 }
17279             }
17280             else
17281             {
17282                 *((uchar *) &eep_config + i) =
17283                 *((uchar *) &Default_38C1600_EEPROM_Config + i);
17284             }
17285         }
17286
17287         /*
17288          * Assume the 6 byte board serial number that was read
17289          * from EEPROM is correct even if the EEPROM checksum
17290          * failed.
17291          */
17292         eep_config.serial_number_word3 =
17293             AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
17294
17295         eep_config.serial_number_word2 =
17296             AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
17297
17298         eep_config.serial_number_word1 =
17299             AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
17300
17301         AdvSet38C1600EEPConfig(iop_base, &eep_config);
17302     }
17303
17304     /*
17305      * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
17306      * EEPROM configuration that was read.
17307      *
17308      * This is the mapping of EEPROM fields to Adv Library fields.
17309      */
17310     asc_dvc->wdtr_able = eep_config.wdtr_able;
17311     asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
17312     asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
17313     asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
17314     asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
17315     asc_dvc->ppr_able = 0;
17316     asc_dvc->tagqng_able = eep_config.tagqng_able;
17317     asc_dvc->cfg->disc_enable = eep_config.disc_enable;
17318     asc_dvc->max_host_qng = eep_config.max_host_qng;
17319     asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
17320     asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
17321     asc_dvc->start_motor = eep_config.start_motor;
17322     asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
17323     asc_dvc->bios_ctrl = eep_config.bios_ctrl;
17324     asc_dvc->no_scam = eep_config.scam_tolerant;
17325
17326     /*
17327      * For every Target ID if any of its 'sdtr_speed[1234]' bits
17328      * are set, then set an 'sdtr_able' bit for it.
17329      */
17330     asc_dvc->sdtr_able = 0;
17331     for (tid = 0; tid <= ASC_MAX_TID; tid++)
17332     {
17333         if (tid == 0)
17334         {
17335             sdtr_speed = asc_dvc->sdtr_speed1;
17336         } else if (tid == 4)
17337         {
17338             sdtr_speed = asc_dvc->sdtr_speed2;
17339         } else if (tid == 8)
17340         {
17341             sdtr_speed = asc_dvc->sdtr_speed3;
17342         } else if (tid == 12)
17343         {
17344             sdtr_speed = asc_dvc->sdtr_speed4;
17345         }
17346         if (sdtr_speed & ASC_MAX_TID)
17347         {
17348             asc_dvc->sdtr_able |= (1 << tid);
17349         }
17350         sdtr_speed >>= 4;
17351     }
17352
17353     /*
17354      * Set the host maximum queuing (max. 253, min. 16) and the per device
17355      * maximum queuing (max. 63, min. 4).
17356      */
17357     if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
17358     {
17359         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17360     } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
17361     {
17362         /* If the value is zero, assume it is uninitialized. */
17363         if (eep_config.max_host_qng == 0)
17364         {
17365             eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17366         } else
17367         {
17368             eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
17369         }
17370     }
17371
17372     if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
17373     {
17374         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17375     } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
17376     {
17377         /* If the value is zero, assume it is uninitialized. */
17378         if (eep_config.max_dvc_qng == 0)
17379         {
17380             eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17381         } else
17382         {
17383             eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
17384         }
17385     }
17386
17387     /*
17388      * If 'max_dvc_qng' is greater than 'max_host_qng', then
17389      * set 'max_dvc_qng' to 'max_host_qng'.
17390      */
17391     if (eep_config.max_dvc_qng > eep_config.max_host_qng)
17392     {
17393         eep_config.max_dvc_qng = eep_config.max_host_qng;
17394     }
17395
17396     /*
17397      * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
17398      * values based on possibly adjusted EEPROM values.
17399      */
17400     asc_dvc->max_host_qng = eep_config.max_host_qng;
17401     asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
17402
17403     /*
17404      * If the EEPROM 'termination' field is set to automatic (0), then set
17405      * the ASC_DVC_CFG 'termination' field to automatic also.
17406      *
17407      * If the termination is specified with a non-zero 'termination'
17408      * value check that a legal value is set and set the ASC_DVC_CFG
17409      * 'termination' field appropriately.
17410      */
17411     if (eep_config.termination_se == 0)
17412     {
17413         termination = 0;                         /* auto termination for SE */
17414     } else
17415     {
17416         /* Enable manual control with low off / high off. */
17417         if (eep_config.termination_se == 1)
17418         {
17419             termination = 0;
17420
17421         /* Enable manual control with low off / high on. */
17422         } else if (eep_config.termination_se == 2)
17423         {
17424             termination = TERM_SE_HI;
17425
17426         /* Enable manual control with low on / high on. */
17427         } else if (eep_config.termination_se == 3)
17428         {
17429             termination = TERM_SE;
17430         } else
17431         {
17432             /*
17433              * The EEPROM 'termination_se' field contains a bad value.
17434              * Use automatic termination instead.
17435              */
17436             termination = 0;
17437             warn_code |= ASC_WARN_EEPROM_TERMINATION;
17438         }
17439     }
17440
17441     if (eep_config.termination_lvd == 0)
17442     {
17443         asc_dvc->cfg->termination = termination; /* auto termination for LVD */
17444     } else
17445     {
17446         /* Enable manual control with low off / high off. */
17447         if (eep_config.termination_lvd == 1)
17448         {
17449             asc_dvc->cfg->termination = termination;
17450
17451         /* Enable manual control with low off / high on. */
17452         } else if (eep_config.termination_lvd == 2)
17453         {
17454             asc_dvc->cfg->termination = termination | TERM_LVD_HI;
17455
17456         /* Enable manual control with low on / high on. */
17457         } else if (eep_config.termination_lvd == 3)
17458         {
17459             asc_dvc->cfg->termination =
17460                 termination | TERM_LVD;
17461         } else
17462         {
17463             /*
17464              * The EEPROM 'termination_lvd' field contains a bad value.
17465              * Use automatic termination instead.
17466              */
17467             asc_dvc->cfg->termination = termination;
17468             warn_code |= ASC_WARN_EEPROM_TERMINATION;
17469         }
17470     }
17471
17472     return warn_code;
17473 }
17474
17475 /*
17476  * Read EEPROM configuration into the specified buffer.
17477  *
17478  * Return a checksum based on the EEPROM configuration read.
17479  */
17480 ASC_INITFUNC(
17481 STATIC ushort,
17482 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
17483 )
17484 {
17485     ushort              wval, chksum;
17486     ushort              *wbuf;
17487     int                 eep_addr;
17488     ushort              *charfields;
17489
17490     charfields = (ushort *) &ADVEEP_3550_Config_Field_IsChar;
17491     wbuf = (ushort *) cfg_buf;
17492     chksum = 0;
17493
17494     for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17495          eep_addr < ADV_EEP_DVC_CFG_END;
17496          eep_addr++, wbuf++)
17497     {
17498         wval = AdvReadEEPWord(iop_base, eep_addr);
17499         chksum += wval; /* Checksum is calculated from word values. */
17500         if (*charfields++) {
17501             *wbuf = le16_to_cpu(wval);
17502         } else {
17503             *wbuf = wval;
17504         }
17505     }
17506     /* Read checksum word. */
17507     *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17508     wbuf++; charfields++;
17509
17510     /* Read rest of EEPROM not covered by the checksum. */
17511     for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17512          eep_addr < ADV_EEP_MAX_WORD_ADDR;
17513          eep_addr++, wbuf++)
17514     {
17515         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17516         if (*charfields++) {
17517             *wbuf = le16_to_cpu(*wbuf);
17518         }
17519     }
17520     return chksum;
17521 }
17522
17523 /*
17524  * Read EEPROM configuration into the specified buffer.
17525  *
17526  * Return a checksum based on the EEPROM configuration read.
17527  */
17528 ASC_INITFUNC(
17529 STATIC ushort,
17530 AdvGet38C0800EEPConfig(AdvPortAddr iop_base,
17531                        ADVEEP_38C0800_CONFIG *cfg_buf)
17532 )
17533 {
17534     ushort              wval, chksum;
17535     ushort              *wbuf;
17536     int                 eep_addr;
17537     ushort              *charfields;
17538
17539     charfields = (ushort *) &ADVEEP_38C0800_Config_Field_IsChar;
17540     wbuf = (ushort *) cfg_buf;
17541     chksum = 0;
17542
17543     for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17544          eep_addr < ADV_EEP_DVC_CFG_END;
17545          eep_addr++, wbuf++)
17546     {
17547         wval = AdvReadEEPWord(iop_base, eep_addr);
17548         chksum += wval; /* Checksum is calculated from word values. */
17549         if (*charfields++) {
17550             *wbuf = le16_to_cpu(wval);
17551         } else {
17552             *wbuf = wval;
17553         }
17554     }
17555     /* Read checksum word. */
17556     *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17557     wbuf++; charfields++;
17558
17559     /* Read rest of EEPROM not covered by the checksum. */
17560     for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17561          eep_addr < ADV_EEP_MAX_WORD_ADDR;
17562          eep_addr++, wbuf++)
17563     {
17564         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17565         if (*charfields++) {
17566             *wbuf = le16_to_cpu(*wbuf);
17567         }
17568     }
17569     return chksum;
17570 }
17571
17572 /*
17573  * Read EEPROM configuration into the specified buffer.
17574  *
17575  * Return a checksum based on the EEPROM configuration read.
17576  */
17577 ASC_INITFUNC(
17578 STATIC ushort,
17579 AdvGet38C1600EEPConfig(AdvPortAddr iop_base,
17580                        ADVEEP_38C1600_CONFIG *cfg_buf)
17581 )
17582 {
17583     ushort              wval, chksum;
17584     ushort              *wbuf;
17585     int                 eep_addr;
17586     ushort              *charfields;
17587
17588     charfields = (ushort*) &ADVEEP_38C1600_Config_Field_IsChar;
17589     wbuf = (ushort *) cfg_buf;
17590     chksum = 0;
17591
17592     for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17593          eep_addr < ADV_EEP_DVC_CFG_END;
17594          eep_addr++, wbuf++)
17595     {
17596         wval = AdvReadEEPWord(iop_base, eep_addr);
17597         chksum += wval; /* Checksum is calculated from word values. */
17598         if (*charfields++) {
17599             *wbuf = le16_to_cpu(wval);
17600         } else {
17601             *wbuf = wval;
17602         }
17603     }
17604     /* Read checksum word. */
17605     *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17606     wbuf++; charfields++;
17607
17608     /* Read rest of EEPROM not covered by the checksum. */
17609     for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17610          eep_addr < ADV_EEP_MAX_WORD_ADDR;
17611          eep_addr++, wbuf++)
17612     {
17613         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17614         if (*charfields++) {
17615             *wbuf = le16_to_cpu(*wbuf);
17616         }
17617     }
17618     return chksum;
17619 }
17620
17621 /*
17622  * Read the EEPROM from specified location
17623  */
17624 ASC_INITFUNC(
17625 STATIC ushort,
17626 AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
17627 )
17628 {
17629     AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
17630         ASC_EEP_CMD_READ | eep_word_addr);
17631     AdvWaitEEPCmd(iop_base);
17632     return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
17633 }
17634
17635 /*
17636  * Wait for EEPROM command to complete
17637  */
17638 ASC_INITFUNC(
17639 STATIC void,
17640 AdvWaitEEPCmd(AdvPortAddr iop_base)
17641 )
17642 {
17643     int eep_delay_ms;
17644
17645     for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++)
17646     {
17647         if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE)
17648         {
17649             break;
17650         }
17651         DvcSleepMilliSecond(1);
17652     }
17653     if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == 0)
17654     {
17655         ASC_ASSERT(0);
17656     }
17657     return;
17658 }
17659
17660 /*
17661  * Write the EEPROM from 'cfg_buf'.
17662  */
17663 void
17664 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
17665 {
17666     ushort *wbuf;
17667     ushort addr, chksum;
17668     ushort *charfields;
17669
17670     wbuf = (ushort *) cfg_buf;
17671     charfields = (ushort *) &ADVEEP_3550_Config_Field_IsChar;
17672     chksum = 0;
17673
17674     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17675     AdvWaitEEPCmd(iop_base);
17676
17677     /*
17678      * Write EEPROM from word 0 to word 20.
17679      */
17680     for (addr = ADV_EEP_DVC_CFG_BEGIN;
17681          addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17682     {
17683         ushort word;
17684
17685         if (*charfields++) {
17686             word = cpu_to_le16(*wbuf);
17687         } else {
17688             word = *wbuf;
17689         }
17690         chksum += *wbuf; /* Checksum is calculated from word values. */
17691         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17692         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17693         AdvWaitEEPCmd(iop_base);
17694         DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17695     }
17696
17697     /*
17698      * Write EEPROM checksum at word 21.
17699      */
17700     AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17701     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17702     AdvWaitEEPCmd(iop_base);
17703     wbuf++; charfields++;
17704
17705     /*
17706      * Write EEPROM OEM name at words 22 to 29.
17707      */
17708     for (addr = ADV_EEP_DVC_CTL_BEGIN;
17709          addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17710     {
17711         ushort word;
17712
17713         if (*charfields++) {
17714             word = cpu_to_le16(*wbuf);
17715         } else {
17716             word = *wbuf;
17717         }
17718         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17719         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17720         AdvWaitEEPCmd(iop_base);
17721     }
17722     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17723     AdvWaitEEPCmd(iop_base);
17724     return;
17725 }
17726
17727 /*
17728  * Write the EEPROM from 'cfg_buf'.
17729  */
17730 void
17731 AdvSet38C0800EEPConfig(AdvPortAddr iop_base,
17732                        ADVEEP_38C0800_CONFIG *cfg_buf)
17733 {
17734     ushort *wbuf;
17735     ushort *charfields;
17736     ushort addr, chksum;
17737
17738     wbuf = (ushort *) cfg_buf;
17739     charfields = (ushort *) &ADVEEP_38C0800_Config_Field_IsChar;
17740     chksum = 0;
17741
17742     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17743     AdvWaitEEPCmd(iop_base);
17744
17745     /*
17746      * Write EEPROM from word 0 to word 20.
17747      */
17748     for (addr = ADV_EEP_DVC_CFG_BEGIN;
17749          addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17750     {
17751         ushort word;
17752
17753         if (*charfields++) {
17754             word = cpu_to_le16(*wbuf);
17755         } else {
17756             word = *wbuf;
17757         }
17758         chksum += *wbuf; /* Checksum is calculated from word values. */
17759         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17760         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17761         AdvWaitEEPCmd(iop_base);
17762         DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17763     }
17764
17765     /*
17766      * Write EEPROM checksum at word 21.
17767      */
17768     AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17769     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17770     AdvWaitEEPCmd(iop_base);
17771     wbuf++; charfields++;
17772
17773     /*
17774      * Write EEPROM OEM name at words 22 to 29.
17775      */
17776     for (addr = ADV_EEP_DVC_CTL_BEGIN;
17777          addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17778     {
17779         ushort word;
17780
17781         if (*charfields++) {
17782             word = cpu_to_le16(*wbuf);
17783         } else {
17784             word = *wbuf;
17785         }
17786         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17787         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17788         AdvWaitEEPCmd(iop_base);
17789     }
17790     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17791     AdvWaitEEPCmd(iop_base);
17792     return;
17793 }
17794
17795 /*
17796  * Write the EEPROM from 'cfg_buf'.
17797  */
17798 void
17799 AdvSet38C1600EEPConfig(AdvPortAddr iop_base,
17800                        ADVEEP_38C1600_CONFIG *cfg_buf)
17801 {
17802     ushort              *wbuf;
17803     ushort              *charfields;
17804     ushort              addr, chksum;
17805
17806     wbuf = (ushort *) cfg_buf;
17807     charfields = (ushort *) &ADVEEP_38C1600_Config_Field_IsChar;
17808     chksum = 0;
17809
17810     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17811     AdvWaitEEPCmd(iop_base);
17812
17813     /*
17814      * Write EEPROM from word 0 to word 20.
17815      */
17816     for (addr = ADV_EEP_DVC_CFG_BEGIN;
17817          addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17818     {
17819         ushort word;
17820
17821         if (*charfields++) {
17822             word = cpu_to_le16(*wbuf);
17823         } else {
17824             word = *wbuf;
17825         }
17826         chksum += *wbuf; /* Checksum is calculated from word values. */
17827         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17828         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17829         AdvWaitEEPCmd(iop_base);
17830         DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17831     }
17832
17833     /*
17834      * Write EEPROM checksum at word 21.
17835      */
17836     AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17837     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17838     AdvWaitEEPCmd(iop_base);
17839     wbuf++; charfields++;
17840
17841     /*
17842      * Write EEPROM OEM name at words 22 to 29.
17843      */
17844     for (addr = ADV_EEP_DVC_CTL_BEGIN;
17845          addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17846     {
17847         ushort word;
17848
17849         if (*charfields++) {
17850             word = cpu_to_le16(*wbuf);
17851         } else {
17852             word = *wbuf;
17853         }
17854         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17855         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17856         AdvWaitEEPCmd(iop_base);
17857     }
17858     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17859     AdvWaitEEPCmd(iop_base);
17860     return;
17861 }
17862
17863 /* a_advlib.c */
17864 /*
17865  * AdvExeScsiQueue() - Send a request to the RISC microcode program.
17866  *
17867  *   Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
17868  *   add the carrier to the ICQ (Initiator Command Queue), and tickle the
17869  *   RISC to notify it a new command is ready to be executed.
17870  *
17871  * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
17872  * set to SCSI_MAX_RETRY.
17873  *
17874  * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
17875  * for DMA addresses or math operations are byte swapped to little-endian
17876  * order.
17877  *
17878  * Return:
17879  *      ADV_SUCCESS(1) - The request was successfully queued.
17880  *      ADV_BUSY(0) -    Resource unavailable; Retry again after pending
17881  *                       request completes.
17882  *      ADV_ERROR(-1) -  Invalid ADV_SCSI_REQ_Q request structure
17883  *                       host IC error.
17884  */
17885 STATIC int
17886 AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc,
17887                 ADV_SCSI_REQ_Q *scsiq)
17888 {
17889     ulong                  last_int_level;
17890     AdvPortAddr            iop_base;
17891     ADV_DCNT               req_size;
17892     ADV_PADDR              req_paddr;
17893     ADV_CARR_T             *new_carrp;
17894
17895     ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
17896
17897     /*
17898      * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
17899      */
17900     if (scsiq->target_id > ADV_MAX_TID)
17901     {
17902         scsiq->host_status = QHSTA_M_INVALID_DEVICE;
17903         scsiq->done_status = QD_WITH_ERROR;
17904         return ADV_ERROR;
17905     }
17906
17907     iop_base = asc_dvc->iop_base;
17908
17909     last_int_level = DvcEnterCritical();
17910
17911     /*
17912      * Allocate a carrier ensuring at least one carrier always
17913      * remains on the freelist and initialize fields.
17914      */
17915     if ((new_carrp = asc_dvc->carr_freelist) == NULL)
17916     {
17917        DvcLeaveCritical(last_int_level);
17918        return ADV_BUSY;
17919     }
17920     asc_dvc->carr_freelist = (ADV_CARR_T *)
17921         ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
17922     asc_dvc->carr_pending_cnt++;
17923
17924     /*
17925      * Set the carrier to be a stopper by setting 'next_vpa'
17926      * to the stopper value. The current stopper will be changed
17927      * below to point to the new stopper.
17928      */
17929     new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
17930
17931     /*
17932      * Clear the ADV_SCSI_REQ_Q done flag.
17933      */
17934     scsiq->a_flag &= ~ADV_SCSIQ_DONE;
17935
17936     req_size = sizeof(ADV_SCSI_REQ_Q);
17937     req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *) scsiq,
17938         (ADV_SDCNT *) &req_size, ADV_IS_SCSIQ_FLAG);
17939
17940     ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
17941     ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
17942
17943     /* Wait for assertion before making little-endian */
17944     req_paddr = cpu_to_le32(req_paddr);
17945
17946     /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
17947     scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
17948     scsiq->scsiq_rptr = req_paddr;
17949
17950     scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
17951     /*
17952      * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
17953      * order during initialization.
17954      */
17955     scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
17956
17957    /*
17958     * Use the current stopper to send the ADV_SCSI_REQ_Q command to
17959     * the microcode. The newly allocated stopper will become the new
17960     * stopper.
17961     */
17962     asc_dvc->icq_sp->areq_vpa = req_paddr;
17963
17964     /*
17965      * Set the 'next_vpa' pointer for the old stopper to be the
17966      * physical address of the new stopper. The RISC can only
17967      * follow physical addresses.
17968      */
17969     asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
17970
17971     /*
17972      * Set the host adapter stopper pointer to point to the new carrier.
17973      */
17974     asc_dvc->icq_sp = new_carrp;
17975
17976     if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17977         asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
17978     {
17979         /*
17980          * Tickle the RISC to tell it to read its Command Queue Head pointer.
17981          */
17982         AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
17983         if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
17984         {
17985             /*
17986              * Clear the tickle value. In the ASC-3550 the RISC flag
17987              * command 'clr_tickle_a' does not work unless the host
17988              * value is cleared.
17989              */
17990             AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17991         }
17992     } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17993     {
17994         /*
17995          * Notify the RISC a carrier is ready by writing the physical
17996          * address of the new carrier stopper to the COMMA register.
17997          */
17998         AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
17999                 le32_to_cpu(new_carrp->carr_pa));
18000     }
18001
18002     DvcLeaveCritical(last_int_level);
18003
18004     return ADV_SUCCESS;
18005 }
18006
18007 /*
18008  * Reset SCSI Bus and purge all outstanding requests.
18009  *
18010  * Return Value:
18011  *      ADV_TRUE(1) -   All requests are purged and SCSI Bus is reset.
18012  *      ADV_FALSE(0) -  Microcode command failed.
18013  *      ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
18014  *                      may be hung which requires driver recovery.
18015  */
18016 STATIC int
18017 AdvResetSB(ADV_DVC_VAR *asc_dvc)
18018 {
18019     int         status;
18020
18021     /*
18022      * Send the SCSI Bus Reset idle start idle command which asserts
18023      * the SCSI Bus Reset signal.
18024      */
18025     status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_START, 0L);
18026     if (status != ADV_TRUE)
18027     {
18028         return status;
18029     }
18030
18031     /*
18032      * Delay for the specified SCSI Bus Reset hold time.
18033      *
18034      * The hold time delay is done on the host because the RISC has no
18035      * microsecond accurate timer.
18036      */
18037     DvcDelayMicroSecond(asc_dvc, (ushort) ASC_SCSI_RESET_HOLD_TIME_US);
18038
18039     /*
18040      * Send the SCSI Bus Reset end idle command which de-asserts
18041      * the SCSI Bus Reset signal and purges any pending requests.
18042      */
18043     status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_END, 0L);
18044     if (status != ADV_TRUE)
18045     {
18046         return status;
18047     }
18048
18049     DvcSleepMilliSecond((ADV_DCNT) asc_dvc->scsi_reset_wait * 1000);
18050
18051     return status;
18052 }
18053
18054 /*
18055  * Reset chip and SCSI Bus.
18056  *
18057  * Return Value:
18058  *      ADV_TRUE(1) -   Chip re-initialization and SCSI Bus Reset successful.
18059  *      ADV_FALSE(0) -  Chip re-initialization and SCSI Bus Reset failure.
18060  */
18061 STATIC int
18062 AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
18063 {
18064     int         status;
18065     ushort      wdtr_able, sdtr_able, tagqng_able;
18066     ushort      ppr_able = 0;
18067     uchar       tid, max_cmd[ADV_MAX_TID + 1];
18068     AdvPortAddr iop_base;
18069     ushort      bios_sig;
18070
18071     iop_base = asc_dvc->iop_base;
18072
18073     /*
18074      * Save current per TID negotiated values.
18075      */
18076     AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
18077     AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
18078     if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
18079     {
18080         AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
18081     }
18082     AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
18083     for (tid = 0; tid <= ADV_MAX_TID; tid++)
18084     {
18085         AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
18086             max_cmd[tid]);
18087     }
18088
18089     /*
18090      * Force the AdvInitAsc3550/38C0800Driver() function to
18091      * perform a SCSI Bus Reset by clearing the BIOS signature word.
18092      * The initialization functions assumes a SCSI Bus Reset is not
18093      * needed if the BIOS signature word is present.
18094      */
18095     AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
18096     AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
18097
18098     /*
18099      * Stop chip and reset it.
18100      */
18101     AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
18102     AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
18103     DvcSleepMilliSecond(100);
18104     AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG);
18105
18106     /*
18107      * Reset Adv Library error code, if any, and try
18108      * re-initializing the chip.
18109      */
18110     asc_dvc->err_code = 0;
18111     if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
18112     {
18113         status = AdvInitAsc38C1600Driver(asc_dvc);
18114     }
18115     else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
18116     {
18117         status = AdvInitAsc38C0800Driver(asc_dvc);
18118     } else
18119     {
18120         status = AdvInitAsc3550Driver(asc_dvc);
18121     }
18122
18123     /* Translate initialization return value to status value. */
18124     if (status == 0)
18125     {
18126         status = ADV_TRUE;
18127     } else
18128     {
18129         status = ADV_FALSE;
18130     }
18131
18132     /*
18133      * Restore the BIOS signature word.
18134      */
18135     AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
18136
18137     /*
18138      * Restore per TID negotiated values.
18139      */
18140     AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
18141     AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
18142     if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
18143     {
18144         AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
18145     }
18146     AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
18147     for (tid = 0; tid <= ADV_MAX_TID; tid++)
18148     {
18149         AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
18150             max_cmd[tid]);
18151     }
18152
18153     return status;
18154 }
18155
18156 /*
18157  * Adv Library Interrupt Service Routine
18158  *
18159  *  This function is called by a driver's interrupt service routine.
18160  *  The function disables and re-enables interrupts.
18161  *
18162  *  When a microcode idle command is completed, the ADV_DVC_VAR
18163  *  'idle_cmd_done' field is set to ADV_TRUE.
18164  *
18165  *  Note: AdvISR() can be called when interrupts are disabled or even
18166  *  when there is no hardware interrupt condition present. It will
18167  *  always check for completed idle commands and microcode requests.
18168  *  This is an important feature that shouldn't be changed because it
18169  *  allows commands to be completed from polling mode loops.
18170  *
18171  * Return:
18172  *   ADV_TRUE(1) - interrupt was pending
18173  *   ADV_FALSE(0) - no interrupt was pending
18174  */
18175 STATIC int
18176 AdvISR(ADV_DVC_VAR *asc_dvc)
18177 {
18178     AdvPortAddr                 iop_base;
18179     uchar                       int_stat;
18180     ushort                      target_bit;
18181     ADV_CARR_T                  *free_carrp;
18182     ADV_VADDR                   irq_next_vpa;
18183     int                         flags;
18184     ADV_SCSI_REQ_Q              *scsiq;
18185
18186     flags = DvcEnterCritical();
18187
18188     iop_base = asc_dvc->iop_base;
18189
18190     /* Reading the register clears the interrupt. */
18191     int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
18192
18193     if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
18194          ADV_INTR_STATUS_INTRC)) == 0)
18195     {
18196         DvcLeaveCritical(flags);
18197         return ADV_FALSE;
18198     }
18199
18200     /*
18201      * Notify the driver of an asynchronous microcode condition by
18202      * calling the ADV_DVC_VAR.async_callback function. The function
18203      * is passed the microcode ASC_MC_INTRB_CODE byte value.
18204      */
18205     if (int_stat & ADV_INTR_STATUS_INTRB)
18206     {
18207         uchar intrb_code;
18208
18209         AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
18210
18211         if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
18212             asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
18213         {
18214             if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
18215                 asc_dvc->carr_pending_cnt != 0)
18216             {
18217                 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
18218                 if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
18219                 {
18220                     AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
18221                 }
18222             }
18223         }
18224
18225         if (asc_dvc->async_callback != 0)
18226         {
18227             (*asc_dvc->async_callback)(asc_dvc, intrb_code);
18228         }
18229     }
18230
18231     /*
18232      * Check if the IRQ stopper carrier contains a completed request.
18233      */
18234     while (((irq_next_vpa =
18235              le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0)
18236     {
18237         /*
18238          * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
18239          * The RISC will have set 'areq_vpa' to a virtual address.
18240          *
18241          * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
18242          * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
18243          * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
18244          * in AdvExeScsiQueue().
18245          */
18246         scsiq = (ADV_SCSI_REQ_Q *)
18247             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
18248
18249         /*
18250          * Request finished with good status and the queue was not
18251          * DMAed to host memory by the firmware. Set all status fields
18252          * to indicate good status.
18253          */
18254         if ((irq_next_vpa & ASC_RQ_GOOD) != 0)
18255         {
18256             scsiq->done_status = QD_NO_ERROR;
18257             scsiq->host_status = scsiq->scsi_status = 0;
18258             scsiq->data_cnt = 0L;
18259         }
18260
18261         /*
18262          * Advance the stopper pointer to the next carrier
18263          * ignoring the lower four bits. Free the previous
18264          * stopper carrier.
18265          */
18266         free_carrp = asc_dvc->irq_sp;
18267         asc_dvc->irq_sp = (ADV_CARR_T *)
18268             ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
18269
18270         free_carrp->next_vpa =
18271                 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
18272         asc_dvc->carr_freelist = free_carrp;
18273         asc_dvc->carr_pending_cnt--;
18274
18275         ASC_ASSERT(scsiq != NULL);
18276         target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
18277
18278         /*
18279          * Clear request microcode control flag.
18280          */
18281         scsiq->cntl = 0;
18282
18283         /*
18284          * If the command that completed was a SCSI INQUIRY and
18285          * LUN 0 was sent the command, then process the INQUIRY
18286          * command information for the device.
18287          *
18288          * Note: If data returned were either VPD or CmdDt data,
18289          * don't process the INQUIRY command information for
18290          * the device, otherwise may erroneously set *_able bits.
18291          */
18292         if (scsiq->done_status == QD_NO_ERROR &&
18293             scsiq->cdb[0] == SCSICMD_Inquiry &&
18294             scsiq->target_lun == 0 &&
18295             (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
18296                 == ADV_INQ_RTN_STD_INQUIRY_DATA)
18297         {
18298             AdvInquiryHandling(asc_dvc, scsiq);
18299         }
18300
18301         /*
18302          * Notify the driver of the completed request by passing
18303          * the ADV_SCSI_REQ_Q pointer to its callback function.
18304          */
18305         scsiq->a_flag |= ADV_SCSIQ_DONE;
18306         (*asc_dvc->isr_callback)(asc_dvc, scsiq);
18307         /*
18308          * Note: After the driver callback function is called, 'scsiq'
18309          * can no longer be referenced.
18310          *
18311          * Fall through and continue processing other completed
18312          * requests...
18313          */
18314
18315         /*
18316          * Disable interrupts again in case the driver inadvertently
18317          * enabled interrupts in its callback function.
18318          *
18319          * The DvcEnterCritical() return value is ignored, because
18320          * the 'flags' saved when AdvISR() was first entered will be
18321          * used to restore the interrupt flag on exit.
18322          */
18323         (void) DvcEnterCritical();
18324     }
18325     DvcLeaveCritical(flags);
18326     return ADV_TRUE;
18327 }
18328
18329 /*
18330  * Send an idle command to the chip and wait for completion.
18331  *
18332  * Command completion is polled for once per microsecond.
18333  *
18334  * The function can be called from anywhere including an interrupt handler.
18335  * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
18336  * functions to prevent reentrancy.
18337  *
18338  * Return Values:
18339  *   ADV_TRUE - command completed successfully
18340  *   ADV_FALSE - command failed
18341  *   ADV_ERROR - command timed out
18342  */
18343 STATIC int
18344 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
18345                ushort idle_cmd,
18346                ADV_DCNT idle_cmd_parameter)
18347 {
18348     ulong       last_int_level;
18349     int         result;
18350     ADV_DCNT    i, j;
18351     AdvPortAddr iop_base;
18352
18353     last_int_level = DvcEnterCritical();
18354
18355     iop_base = asc_dvc->iop_base;
18356
18357     /*
18358      * Clear the idle command status which is set by the microcode
18359      * to a non-zero value to indicate when the command is completed.
18360      * The non-zero result is one of the IDLE_CMD_STATUS_* values
18361      * defined in a_advlib.h.
18362      */
18363     AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort) 0);
18364
18365     /*
18366      * Write the idle command value after the idle command parameter
18367      * has been written to avoid a race condition. If the order is not
18368      * followed, the microcode may process the idle command before the
18369      * parameters have been written to LRAM.
18370      */
18371     AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
18372         cpu_to_le32(idle_cmd_parameter));
18373     AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
18374
18375     /*
18376      * Tickle the RISC to tell it to process the idle command.
18377      */
18378     AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
18379     if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
18380     {
18381         /*
18382          * Clear the tickle value. In the ASC-3550 the RISC flag
18383          * command 'clr_tickle_b' does not work unless the host
18384          * value is cleared.
18385          */
18386         AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
18387     }
18388
18389     /* Wait for up to 100 millisecond for the idle command to timeout. */
18390     for (i = 0; i < SCSI_WAIT_100_MSEC; i++)
18391     {
18392         /* Poll once each microsecond for command completion. */
18393         for (j = 0; j < SCSI_US_PER_MSEC; j++)
18394         {
18395             AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, result);
18396             if (result != 0)
18397             {
18398                 DvcLeaveCritical(last_int_level);
18399                 return result;
18400             }
18401             DvcDelayMicroSecond(asc_dvc, (ushort) 1);
18402         }
18403     }
18404
18405     ASC_ASSERT(0); /* The idle command should never timeout. */
18406     DvcLeaveCritical(last_int_level);
18407     return ADV_ERROR;
18408 }
18409
18410 /*
18411  * Inquiry Information Byte 7 Handling
18412  *
18413  * Handle SCSI Inquiry Command information for a device by setting
18414  * microcode operating variables that affect WDTR, SDTR, and Tag
18415  * Queuing.
18416  */
18417 STATIC void
18418 AdvInquiryHandling(
18419     ADV_DVC_VAR                 *asc_dvc,
18420     ADV_SCSI_REQ_Q              *scsiq)
18421 {
18422     AdvPortAddr                 iop_base;
18423     uchar                       tid;
18424     ADV_SCSI_INQUIRY            *inq;
18425     ushort                      tidmask;
18426     ushort                      cfg_word;
18427
18428     /*
18429      * AdvInquiryHandling() requires up to INQUIRY information Byte 7
18430      * to be available.
18431      *
18432      * If less than 8 bytes of INQUIRY information were requested or less
18433      * than 8 bytes were transferred, then return. cdb[4] is the request
18434      * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
18435      * microcode to the transfer residual count.
18436      */
18437
18438     if (scsiq->cdb[4] < 8 ||
18439         (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8)
18440     {
18441         return;
18442     }
18443
18444     iop_base = asc_dvc->iop_base;
18445     tid = scsiq->target_id;
18446
18447     inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr;
18448
18449     /*
18450      * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
18451      */
18452     if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2)
18453     {
18454         return;
18455     } else
18456     {
18457         /*
18458          * INQUIRY Byte 7 Handling
18459          *
18460          * Use a device's INQUIRY byte 7 to determine whether it
18461          * supports WDTR, SDTR, and Tag Queuing. If the feature
18462          * is enabled in the EEPROM and the device supports the
18463          * feature, then enable it in the microcode.
18464          */
18465
18466         tidmask = ADV_TID_TO_TIDMASK(tid);
18467
18468         /*
18469          * Wide Transfers
18470          *
18471          * If the EEPROM enabled WDTR for the device and the device
18472          * supports wide bus (16 bit) transfers, then turn on the
18473          * device's 'wdtr_able' bit and write the new value to the
18474          * microcode.
18475          */
18476         if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq))
18477         {
18478             AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
18479             if ((cfg_word & tidmask) == 0)
18480             {
18481                 cfg_word |= tidmask;
18482                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
18483
18484                 /*
18485                  * Clear the microcode "SDTR negotiation" and "WDTR
18486                  * negotiation" done indicators for the target to cause
18487                  * it to negotiate with the new setting set above.
18488                  * WDTR when accepted causes the target to enter
18489                  * asynchronous mode, so SDTR must be negotiated.
18490                  */
18491                 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18492                 cfg_word &= ~tidmask;
18493                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18494                 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
18495                 cfg_word &= ~tidmask;
18496                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
18497             }
18498         }
18499
18500         /*
18501          * Synchronous Transfers
18502          *
18503          * If the EEPROM enabled SDTR for the device and the device
18504          * supports synchronous transfers, then turn on the device's
18505          * 'sdtr_able' bit. Write the new value to the microcode.
18506          */
18507         if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq))
18508         {
18509             AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
18510             if ((cfg_word & tidmask) == 0)
18511             {
18512                 cfg_word |= tidmask;
18513                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
18514
18515                 /*
18516                  * Clear the microcode "SDTR negotiation" done indicator
18517                  * for the target to cause it to negotiate with the new
18518                  * setting set above.
18519                  */
18520                 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18521                 cfg_word &= ~tidmask;
18522                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18523             }
18524         }
18525         /*
18526          * If the Inquiry data included enough space for the SPI-3
18527          * Clocking field, then check if DT mode is supported.
18528          */
18529         if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 &&
18530             (scsiq->cdb[4] >= 57 ||
18531             (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57))
18532         {
18533             /*
18534              * PPR (Parallel Protocol Request) Capable
18535              *
18536              * If the device supports DT mode, then it must be PPR capable.
18537              * The PPR message will be used in place of the SDTR and WDTR
18538              * messages to negotiate synchronous speed and offset, transfer
18539              * width, and protocol options.
18540              */
18541             if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY)
18542             {
18543                 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, asc_dvc->ppr_able);
18544                 asc_dvc->ppr_able |= tidmask;
18545                 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, asc_dvc->ppr_able);
18546             }
18547         }
18548
18549         /*
18550          * If the EEPROM enabled Tag Queuing for the device and the
18551          * device supports Tag Queueing, then turn on the device's
18552          * 'tagqng_enable' bit in the microcode and set the microcode
18553          * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
18554          * value.
18555          *
18556          * Tag Queuing is disabled for the BIOS which runs in polled
18557          * mode and would see no benefit from Tag Queuing. Also by
18558          * disabling Tag Queuing in the BIOS devices with Tag Queuing
18559          * bugs will at least work with the BIOS.
18560          */
18561         if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq))
18562         {
18563             AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
18564             cfg_word |= tidmask;
18565             AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
18566
18567             AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
18568                 asc_dvc->max_dvc_qng);
18569         }
18570     }
18571 }
18572 MODULE_LICENSE("Dual BSD/GPL");