]> Pileus Git - ~andy/linux/blob - drivers/scsi/advansys.c
[SCSI] advansys: Convert to ISA driver model
[~andy/linux] / drivers / scsi / advansys.c
1 #define ASC_VERSION "3.4"       /* AdvanSys Driver Version */
2
3 /*
4  * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
5  *
6  * Copyright (c) 1995-2000 Advanced System Products, Inc.
7  * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
8  * Copyright (c) 2007 Matthew Wilcox <matthew@wil.cx>
9  * All Rights Reserved.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  */
16
17 /*
18  * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
19  * changed its name to ConnectCom Solutions, Inc.
20  * On June 18, 2001 Initio Corp. acquired ConnectCom's SCSI assets
21  */
22
23 /*
24
25   Documentation for the AdvanSys Driver
26
27   A. Linux Kernels Supported by this Driver
28   B. Adapters Supported by this Driver
29   C. Linux source files modified by AdvanSys Driver
30   D. Source Comments
31   E. Driver Compile Time Options and Debugging
32   F. Driver LILO Option
33   G. Tests to run before releasing new driver
34   H. Release History
35   I. Known Problems/Fix List
36   J. Credits (Chronological Order)
37
38   A. Linux Kernels Supported by this Driver
39
40      This driver has been tested in the following Linux kernels: v2.2.18
41      v2.4.0. The driver is supported on v2.2 and v2.4 kernels and on x86,
42      alpha, and PowerPC platforms.
43
44   B. Adapters Supported by this Driver
45
46      AdvanSys (Advanced System Products, Inc.) manufactures the following
47      RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow
48      (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI
49      buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit
50      transfer) SCSI Host Adapters for the PCI bus.
51
52      The CDB counts below indicate the number of SCSI CDB (Command
53      Descriptor Block) requests that can be stored in the RISC chip
54      cache and board LRAM. A CDB is a single SCSI command. The driver
55      detect routine will display the number of CDBs available for each
56      adapter detected. The number of CDBs used by the driver can be
57      lowered in the BIOS by changing the 'Host Queue Size' adapter setting.
58
59      Laptop Products:
60         ABP-480 - Bus-Master CardBus (16 CDB) (2.4 kernel and greater)
61
62      Connectivity Products:
63         ABP510/5150 - Bus-Master ISA (240 CDB)
64         ABP5140 - Bus-Master ISA PnP (16 CDB)
65         ABP5142 - Bus-Master ISA PnP with floppy (16 CDB)
66         ABP902/3902 - Bus-Master PCI (16 CDB)
67         ABP3905 - Bus-Master PCI (16 CDB)
68         ABP915 - Bus-Master PCI (16 CDB)
69         ABP920 - Bus-Master PCI (16 CDB)
70         ABP3922 - Bus-Master PCI (16 CDB)
71         ABP3925 - Bus-Master PCI (16 CDB)
72         ABP930 - Bus-Master PCI (16 CDB)
73         ABP930U - Bus-Master PCI Ultra (16 CDB)
74         ABP930UA - Bus-Master PCI Ultra (16 CDB)
75         ABP960 - Bus-Master PCI MAC/PC (16 CDB)
76         ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
77
78      Single Channel Products:
79         ABP542 - Bus-Master ISA with floppy (240 CDB)
80         ABP742 - Bus-Master EISA (240 CDB)
81         ABP842 - Bus-Master VL (240 CDB)
82         ABP940 - Bus-Master PCI (240 CDB)
83         ABP940U - Bus-Master PCI Ultra (240 CDB)
84         ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB)
85         ABP970 - Bus-Master PCI MAC/PC (240 CDB)
86         ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
87         ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB)
88         ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB)
89         ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB)
90         ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB)
91
92      Multi-Channel Products:
93         ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
94         ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
95         ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
96         ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel)
97         ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
98         ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
99         ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.)
100         ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB)
101         ABP3950U3W - Bus-Master PCI Dual LVD2/Ultra3-Wide (253 CDB)
102
103   C. Linux source files modified by AdvanSys Driver
104
105      This section for historical purposes documents the changes
106      originally made to the Linux kernel source to add the advansys
107      driver. As Linux has changed some of these files have also
108      been modified.
109
110      1. linux/arch/i386/config.in:
111
112           bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
113
114      2. linux/drivers/scsi/hosts.c:
115
116           #ifdef CONFIG_SCSI_ADVANSYS
117           #include "advansys.h"
118           #endif
119
120         and after "static struct scsi_host_template builtin_scsi_hosts[] =":
121
122           #ifdef CONFIG_SCSI_ADVANSYS
123           ADVANSYS,
124           #endif
125
126      3. linux/drivers/scsi/Makefile:
127
128           ifdef CONFIG_SCSI_ADVANSYS
129           SCSI_SRCS := $(SCSI_SRCS) advansys.c
130           SCSI_OBJS := $(SCSI_OBJS) advansys.o
131           else
132           SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
133           endif
134
135      4. linux/init/main.c:
136
137           extern void advansys_setup(char *str, int *ints);
138
139         and add the following lines to the bootsetups[] array.
140
141           #ifdef CONFIG_SCSI_ADVANSYS
142              { "advansys=", advansys_setup },
143           #endif
144
145   D. Source Comments
146
147      1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
148
149      2. This driver should be maintained in multiple files. But to make
150         it easier to include with Linux and to follow Linux conventions,
151         the whole driver is maintained in the source files advansys.h and
152         advansys.c. In this file logical sections of the driver begin with
153         a comment that contains '---'. The following are the logical sections
154         of the driver below.
155
156            --- Linux Version
157            --- Linux Include File
158            --- Driver Options
159            --- Debugging Header
160            --- Asc Library Constants and Macros
161            --- Adv Library Constants and Macros
162            --- Driver Constants and Macros
163            --- Driver Structures
164            --- Driver Data
165            --- Driver Function Prototypes
166            --- Linux 'struct scsi_host_template' and advansys_setup() Functions
167            --- Loadable Driver Support
168            --- Miscellaneous Driver Functions
169            --- Functions Required by the Asc Library
170            --- Functions Required by the Adv Library
171            --- Tracing and Debugging Functions
172            --- Asc Library Functions
173            --- Adv Library Functions
174
175      3. The string 'XXX' is used to flag code that needs to be re-written
176         or that contains a problem that needs to be addressed.
177
178      4. I have stripped comments from and reformatted the source for the
179         Asc Library and Adv Library to reduce the size of this file. This
180         source can be found under the following headings. The Asc Library
181         is used to support Narrow Boards. The Adv Library is used to
182         support Wide Boards.
183
184            --- Asc Library Constants and Macros
185            --- Adv Library Constants and Macros
186            --- Asc Library Functions
187            --- Adv Library Functions
188
189   E. Driver Compile Time Options and Debugging
190
191      In this source file the following constants can be defined. They are
192      defined in the source below. Both of these options are enabled by
193      default.
194
195      1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled)
196
197         Enabling this option adds assertion logic statements to the
198         driver. If an assertion fails a message will be displayed to
199         the console, but the system will continue to operate. Any
200         assertions encountered should be reported to the person
201         responsible for the driver. Assertion statements may proactively
202         detect problems with the driver and facilitate fixing these
203         problems. Enabling assertions will add a small overhead to the
204         execution of the driver.
205
206      2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled)
207
208         Enabling this option adds tracing functions to the driver and
209         the ability to set a driver tracing level at boot time. This
210         option will also export symbols not required outside the driver to
211         the kernel name space. This option is very useful for debugging
212         the driver, but it will add to the size of the driver execution
213         image and add overhead to the execution of the driver.
214
215         The amount of debugging output can be controlled with the global
216         variable 'asc_dbglvl'. The higher the number the more output. By
217         default the debug level is 0.
218
219         If the driver is loaded at boot time and the LILO Driver Option
220         is included in the system, the debug level can be changed by
221         specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
222         first three hex digits of the pseudo I/O Port must be set to
223         'deb' and the fourth hex digit specifies the debug level: 0 - F.
224         The following command line will look for an adapter at 0x330
225         and set the debug level to 2.
226
227            linux advansys=0x330,0,0,0,0xdeb2
228
229         If the driver is built as a loadable module this variable can be
230         defined when the driver is loaded. The following insmod command
231         will set the debug level to one.
232
233            insmod advansys.o asc_dbglvl=1
234
235         Debugging Message Levels:
236            0: Errors Only
237            1: High-Level Tracing
238            2-N: Verbose Tracing
239
240         To enable debug output to console, please make sure that:
241
242         a. System and kernel logging is enabled (syslogd, klogd running).
243         b. Kernel messages are routed to console output. Check
244            /etc/syslog.conf for an entry similar to this:
245
246                 kern.*                  /dev/console
247
248         c. klogd is started with the appropriate -c parameter
249            (e.g. klogd -c 8)
250
251         This will cause printk() messages to be be displayed on the
252         current console. Refer to the klogd(8) and syslogd(8) man pages
253         for details.
254
255         Alternatively you can enable printk() to console with this
256         program. However, this is not the 'official' way to do this.
257         Debug output is logged in /var/log/messages.
258
259           main()
260           {
261                   syscall(103, 7, 0, 0);
262           }
263
264         Increasing LOG_BUF_LEN in kernel/printk.c to something like
265         40960 allows more debug messages to be buffered in the kernel
266         and written to the console or log file.
267
268      3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0)
269
270         Enabling this option adds statistics collection and display
271         through /proc to the driver. The information is useful for
272         monitoring driver and device performance. It will add to the
273         size of the driver execution image and add minor overhead to
274         the execution of the driver.
275
276         Statistics are maintained on a per adapter basis. Driver entry
277         point call counts and transfer size counts are maintained.
278         Statistics are only available for kernels greater than or equal
279         to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured.
280
281         AdvanSys SCSI adapter files have the following path name format:
282
283            /proc/scsi/advansys/{0,1,2,3,...}
284
285         This information can be displayed with cat. For example:
286
287            cat /proc/scsi/advansys/0
288
289         When ADVANSYS_STATS is not defined the AdvanSys /proc files only
290         contain adapter and device configuration information.
291
292   F. Driver LILO Option
293
294      If init/main.c is modified as described in the 'Directions for Adding
295      the AdvanSys Driver to Linux' section (B.4.) above, the driver will
296      recognize the 'advansys' LILO command line and /etc/lilo.conf option.
297      This option can be used to either disable I/O port scanning or to limit
298      scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
299      PCI boards will still be searched for and detected. This option only
300      affects searching for ISA and VL boards.
301
302      Examples:
303        1. Eliminate I/O port scanning:
304             boot: linux advansys=
305               or
306             boot: linux advansys=0x0
307        2. Limit I/O port scanning to one I/O port:
308             boot: linux advansys=0x110
309        3. Limit I/O port scanning to four I/O ports:
310             boot: linux advansys=0x110,0x210,0x230,0x330
311
312      For a loadable module the same effect can be achieved by setting
313      the 'asc_iopflag' variable and 'asc_ioport' array when loading
314      the driver, e.g.
315
316            insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
317
318      If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1)
319      I/O Port may be added to specify the driver debug level. Refer to
320      the 'Driver Compile Time Options and Debugging' section above for
321      more information.
322
323   G. Tests to run before releasing new driver
324
325      1. In the supported kernels verify there are no warning or compile
326         errors when the kernel is built as both a driver and as a module
327         and with the following options:
328
329         ADVANSYS_DEBUG - enabled and disabled
330         CONFIG_SMP - enabled and disabled
331         CONFIG_PROC_FS - enabled and disabled
332
333      2. Run tests on an x86, alpha, and PowerPC with at least one narrow
334         card and one wide card attached to a hard disk and CD-ROM drive:
335         fdisk, mkfs, fsck, bonnie, copy/compare test from the
336         CD-ROM to the hard drive.
337
338   H. Release History
339
340      BETA-1.0 (12/23/95):
341          First Release
342
343      BETA-1.1 (12/28/95):
344          1. Prevent advansys_detect() from being called twice.
345          2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
346
347      1.2 (1/12/96):
348          1. Prevent re-entrancy in the interrupt handler which
349             resulted in the driver hanging Linux.
350          2. Fix problem that prevented ABP-940 cards from being
351             recognized on some PCI motherboards.
352          3. Add support for the ABP-5140 PnP ISA card.
353          4. Fix check condition return status.
354          5. Add conditionally compiled code for Linux v1.3.X.
355
356      1.3 (2/23/96):
357          1. Fix problem in advansys_biosparam() that resulted in the
358             wrong drive geometry being returned for drives > 1GB with
359             extended translation enabled.
360          2. Add additional tracing during device initialization.
361          3. Change code that only applies to ISA PnP adapter.
362          4. Eliminate 'make dep' warning.
363          5. Try to fix problem with handling resets by increasing their
364             timeout value.
365
366      1.4 (5/8/96):
367          1. Change definitions to eliminate conflicts with other subsystems.
368          2. Add versioning code for the shared interrupt changes.
369          3. Eliminate problem in asc_rmqueue() with iterating after removing
370             a request.
371          4. Remove reset request loop problem from the "Known Problems or
372             Issues" section. This problem was isolated and fixed in the
373             mid-level SCSI driver.
374
375      1.5 (8/8/96):
376          1. Add support for ABP-940U (PCI Ultra) adapter.
377          2. Add support for IRQ sharing by setting the IRQF_SHARED flag for
378             request_irq and supplying a dev_id pointer to both request_irq()
379             and free_irq().
380          3. In AscSearchIOPortAddr11() restore a call to check_region() which
381             should be used before I/O port probing.
382          4. Fix bug in asc_prt_hex() which resulted in the displaying
383             the wrong data.
384          5. Incorporate miscellaneous Asc Library bug fixes and new microcode.
385          6. Change driver versioning to be specific to each Linux sub-level.
386          7. Change statistics gathering to be per adapter instead of global
387             to the driver.
388          8. Add more information and statistics to the adapter /proc file:
389             /proc/scsi/advansys[0...].
390          9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list.
391             This problem has been addressed with the SCSI mid-level changes
392             made in v1.3.89. The advansys_select_queue_depths() function
393             was added for the v1.3.89 changes.
394
395      1.6 (9/10/96):
396          1. Incorporate miscellaneous Asc Library bug fixes and new microcode.
397
398      1.7 (9/25/96):
399          1. Enable clustering and optimize the setting of the maximum number
400             of scatter gather elements for any particular board. Clustering
401             increases CPU utilization, but results in a relatively larger
402             increase in I/O throughput.
403          2. Improve the performance of the request queuing functions by
404             adding a last pointer to the queue structure.
405          3. Correct problems with reset and abort request handling that
406             could have hung or crashed Linux.
407          4. Add more information to the adapter /proc file:
408             /proc/scsi/advansys[0...].
409          5. Remove the request timeout issue form the driver issues list.
410          6. Miscellaneous documentation additions and changes.
411
412      1.8 (10/4/96):
413          1. Make changes to handle the new v2.1.0 kernel memory mapping
414             in which a kernel virtual address may not be equivalent to its
415             bus or DMA memory address.
416          2. Change abort and reset request handling to make it yet even
417             more robust.
418          3. Try to mitigate request starvation by sending ordered requests
419             to heavily loaded, tag queuing enabled devices.
420          4. Maintain statistics on request response time.
421          5. Add request response time statistics and other information to
422             the adapter /proc file: /proc/scsi/advansys[0...].
423
424      1.9 (10/21/96):
425          1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to
426             make use of mid-level SCSI driver device queue depth flow
427             control mechanism. This will eliminate aborts caused by a
428             device being unable to keep up with requests and eliminate
429             repeat busy or QUEUE FULL status returned by a device.
430          2. Incorporate miscellaneous Asc Library bug fixes.
431          3. To allow the driver to work in kernels with broken module
432             support set 'cmd_per_lun' if the driver is compiled as a
433             module. This change affects kernels v1.3.89 to present.
434          4. Remove PCI BIOS address from the driver banner. The PCI BIOS
435             is relocated by the motherboard BIOS and its new address can
436             not be determined by the driver.
437          5. Add mid-level SCSI queue depth information to the adapter
438             /proc file: /proc/scsi/advansys[0...].
439
440      2.0 (11/14/96):
441          1. Change allocation of global structures used for device
442             initialization to guarantee they are in DMA-able memory.
443             Previously when the driver was loaded as a module these
444             structures might not have been in DMA-able memory, causing
445             device initialization to fail.
446
447      2.1 (12/30/96):
448          1. In advansys_reset(), if the request is a synchronous reset
449             request, even if the request serial number has changed, then
450             complete the request.
451          2. Add Asc Library bug fixes including new microcode.
452          3. Clear inquiry buffer before using it.
453          4. Correct ifdef typo.
454
455      2.2 (1/15/97):
456          1. Add Asc Library bug fixes including new microcode.
457          2. Add synchronous data transfer rate information to the
458             adapter /proc file: /proc/scsi/advansys[0...].
459          3. Change ADVANSYS_DEBUG to be disabled by default. This
460             will reduce the size of the driver image, eliminate execution
461             overhead, and remove unneeded symbols from the kernel symbol
462             space that were previously added by the driver.
463          4. Add new compile-time option ADVANSYS_ASSERT for assertion
464             code that used to be defined within ADVANSYS_DEBUG. This
465             option is enabled by default.
466
467      2.8 (5/26/97):
468          1. Change version number to 2.8 to synchronize the Linux driver
469             version numbering with other AdvanSys drivers.
470          2. Reformat source files without tabs to present the same view
471             of the file to everyone regardless of the editor tab setting
472             being used.
473          3. Add Asc Library bug fixes.
474
475      3.1A (1/8/98):
476          1. Change version number to 3.1 to indicate that support for
477             Ultra-Wide adapters (ABP-940UW) is included in this release.
478          2. Add Asc Library (Narrow Board) bug fixes.
479          3. Report an underrun condition with the host status byte set
480             to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which
481             causes the underrun condition to be ignored. When Linux defines
482             its own DID_UNDERRUN the constant defined in this file can be
483             removed.
484          4. Add patch to AscWaitTixISRDone().
485          5. Add support for up to 16 different AdvanSys host adapter SCSI
486             channels in one system. This allows four cards with four channels
487             to be used in one system.
488
489      3.1B (1/9/98):
490          1. Handle that PCI register base addresses are not always page
491             aligned even though ioremap() requires that the address argument
492             be page aligned.
493
494      3.1C (1/10/98):
495          1. Update latest BIOS version checked for from the /proc file.
496          2. Don't set microcode SDTR variable at initialization. Instead
497             wait until device capabilities have been detected from an Inquiry
498             command.
499
500      3.1D (1/21/98):
501          1. Improve performance when the driver is compiled as module by
502             allowing up to 64 scatter-gather elements instead of 8.
503
504      3.1E (5/1/98):
505          1. Set time delay in AscWaitTixISRDone() to 1000 ms.
506          2. Include SMP locking changes.
507          3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS
508             access functions.
509          4. Update board serial number printing.
510          5. Try allocating an IRQ both with and without the IRQF_DISABLED
511             flag set to allow IRQ sharing with drivers that do not set
512             the IRQF_DISABLED flag. Also display a more descriptive error
513             message if request_irq() fails.
514          6. Update to latest Asc and Adv Libraries.
515
516      3.2A (7/22/99):
517          1. Update Adv Library to 4.16 which includes support for
518             the ASC38C0800 (Ultra2/LVD) IC.
519
520      3.2B (8/23/99):
521          1. Correct PCI compile time option for v2.1.93 and greater
522             kernels, advansys_info() string, and debug compile time
523             option.
524          2. Correct DvcSleepMilliSecond() for v2.1.0 and greater
525             kernels. This caused an LVD detection/BIST problem problem
526             among other things.
527          3. Sort PCI cards by PCI Bus, Slot, Function ascending order
528             to be consistent with the BIOS.
529          4. Update to Asc Library S121 and Adv Library 5.2.
530
531      3.2C (8/24/99):
532          1. Correct PCI card detection bug introduced in 3.2B that
533             prevented PCI cards from being detected in kernels older
534             than v2.1.93.
535
536      3.2D (8/26/99):
537          1. Correct /proc device synchronous speed information display.
538             Also when re-negotiation is pending for a target device
539             note this condition with an * and footnote.
540          2. Correct initialization problem with Ultra-Wide cards that
541             have a pre-3.2 BIOS. A microcode variable changed locations
542             in 3.2 and greater BIOSes which caused WDTR to be attempted
543             erroneously with drives that don't support WDTR.
544
545      3.2E (8/30/99):
546          1. Fix compile error caused by v2.3.13 PCI structure change.
547          2. Remove field from ASCEEP_CONFIG that resulted in an EEPROM
548             checksum error for ISA cards.
549          3. Remove ASC_QUEUE_FLOW_CONTROL conditional code. The mid-level
550             SCSI changes that it depended on were never included in Linux.
551
552      3.2F (9/3/99):
553          1. Handle new initial function code added in v2.3.16 for all
554             driver versions.
555
556      3.2G (9/8/99):
557          1. Fix PCI board detection in v2.3.13 and greater kernels.
558          2. Fix comiple errors in v2.3.X with debugging enabled.
559
560      3.2H (9/13/99):
561          1. Add 64-bit address, long support for Alpha and UltraSPARC.
562             The driver has been verified to work on an Alpha system.
563          2. Add partial byte order handling support for Power PC and
564             other big-endian platforms. This support has not yet been
565             completed or verified.
566          3. For wide boards replace block zeroing of request and
567             scatter-gather structures with individual field initialization
568             to improve performance.
569          4. Correct and clarify ROM BIOS version detection.
570
571      3.2I (10/8/99):
572          1. Update to Adv Library 5.4.
573          2. Add v2.3.19 underrun reporting to asc_isr_callback() and
574             adv_isr_callback().  Remove DID_UNDERRUN constant and other
575             no longer needed code that previously documented the lack
576             of underrun handling.
577
578      3.2J (10/14/99):
579          1. Eliminate compile errors for v2.0 and earlier kernels.
580
581      3.2K (11/15/99):
582          1. Correct debug compile error in asc_prt_adv_scsi_req_q().
583          2. Update Adv Library to 5.5.
584          3. Add ifdef handling for /proc changes added in v2.3.28.
585          4. Increase Wide board scatter-gather list maximum length to
586             255 when the driver is compiled into the kernel.
587
588      3.2L (11/18/99):
589          1. Fix bug in adv_get_sglist() that caused an assertion failure
590             at line 7475. The reqp->sgblkp pointer must be initialized
591             to NULL in adv_get_sglist().
592
593      3.2M (11/29/99):
594          1. Really fix bug in adv_get_sglist().
595          2. Incorporate v2.3.29 changes into driver.
596
597      3.2N (4/1/00):
598          1. Add CONFIG_ISA ifdef code.
599          2. Include advansys_interrupts_enabled name change patch.
600          3. For >= v2.3.28 use new SCSI error handling with new function
601             advansys_eh_bus_reset(). Don't include an abort function
602             because of base library limitations.
603          4. For >= v2.3.28 use per board lock instead of io_request_lock.
604          5. For >= v2.3.28 eliminate advansys_command() and
605             advansys_command_done().
606          6. Add some changes for PowerPC (Big Endian) support, but it isn't
607             working yet.
608          7. Fix "nonexistent resource free" problem that occurred on a module
609             unload for boards with an I/O space >= 255. The 'n_io_port' field
610             is only one byte and can not be used to hold an ioport length more
611             than 255.
612
613      3.3A (4/4/00):
614          1. Update to Adv Library 5.8.
615          2. For wide cards add support for CDBs up to 16 bytes.
616          3. Eliminate warnings when CONFIG_PROC_FS is not defined.
617
618      3.3B (5/1/00):
619          1. Support for PowerPC (Big Endian) wide cards. Narrow cards
620             still need work.
621          2. Change bitfields to shift and mask access for endian
622             portability.
623
624      3.3C (10/13/00):
625          1. Update for latest 2.4 kernel.
626          2. Test ABP-480 CardBus support in 2.4 kernel - works!
627          3. Update to Asc Library S123.
628          4. Update to Adv Library 5.12.
629
630      3.3D (11/22/00):
631          1. Update for latest 2.4 kernel.
632          2. Create patches for 2.2 and 2.4 kernels.
633
634      3.3E (1/9/01):
635          1. Now that 2.4 is released remove ifdef code for kernel versions
636             less than 2.2. The driver is now only supported in kernels 2.2,
637             2.4, and greater.
638          2. Add code to release and acquire the io_request_lock in
639             the driver entrypoint functions: advansys_detect and
640             advansys_queuecommand. In kernel 2.4 the SCSI mid-level driver
641             still holds the io_request_lock on entry to SCSI low-level drivers.
642             This was supposed to be removed before 2.4 was released but never
643             happened. When the mid-level SCSI driver is changed all references
644             to the io_request_lock should be removed from the driver.
645          3. Simplify error handling by removing advansys_abort(),
646             AscAbortSRB(), AscResetDevice(). SCSI bus reset requests are
647             now handled by resetting the SCSI bus and fully re-initializing
648             the chip. This simple method of error recovery has proven to work
649             most reliably after attempts at different methods. Also now only
650             support the "new" error handling method and remove the obsolete
651             error handling interface.
652          4. Fix debug build errors.
653
654      3.3F (1/24/01):
655          1. Merge with ConnectCom version from Andy Kellner which
656             updates Adv Library to 5.14.
657          2. Make PowerPC (Big Endian) work for narrow cards and
658             fix problems writing EEPROM for wide cards.
659          3. Remove interrupts_enabled assertion function.
660
661      3.3G (2/16/01):
662          1. Return an error from narrow boards if passed a 16 byte
663             CDB. The wide board can already handle 16 byte CDBs.
664
665      3.3GJ (4/15/02):
666          1. hacks for lk 2.5 series (D. Gilbert)
667
668      3.3GJD (10/14/02):
669          1. change select_queue_depths to slave_configure
670          2. make cmd_per_lun be sane again
671
672      3.3K [2004/06/24]:
673          1. continuing cleanup for lk 2.6 series
674          2. Fix problem in lk 2.6.7-bk2 that broke PCI wide cards
675          3. Fix problem that oopsed ISA cards
676
677   I. Known Problems/Fix List (XXX)
678
679      1. Need to add memory mapping workaround. Test the memory mapping.
680         If it doesn't work revert to I/O port access. Can a test be done
681         safely?
682      2. Handle an interrupt not working. Keep an interrupt counter in
683         the interrupt handler. In the timeout function if the interrupt
684         has not occurred then print a message and run in polled mode.
685      3. Allow bus type scanning order to be changed.
686      4. Need to add support for target mode commands, cf. CAM XPT.
687
688   J. Credits (Chronological Order)
689
690      Bob Frey <bfrey@turbolinux.com.cn> wrote the AdvanSys SCSI driver
691      and maintained it up to 3.3F. He continues to answer questions
692      and help maintain the driver.
693
694      Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and
695      basis for the Linux v1.3.X changes which were included in the
696      1.2 release.
697
698      Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug
699      in advansys_biosparam() which was fixed in the 1.3 release.
700
701      Erik Ratcliffe <erik@caldera.com> has done testing of the
702      AdvanSys driver in the Caldera releases.
703
704      Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to
705      AscWaitTixISRDone() which he found necessary to make the
706      driver work with a SCSI-1 disk.
707
708      Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide
709      support in the 3.1A driver.
710
711      Doug Gilbert <dgilbert@interlog.com> has made changes and
712      suggestions to improve the driver and done a lot of testing.
713
714      Ken Mort <ken@mort.net> reported a DEBUG compile bug fixed
715      in 3.2K.
716
717      Tom Rini <trini@kernel.crashing.org> provided the CONFIG_ISA
718      patch and helped with PowerPC wide and narrow board support.
719
720      Philip Blundell <philb@gnu.org> provided an
721      advansys_interrupts_enabled patch.
722
723      Dave Jones <dave@denial.force9.co.uk> reported the compiler
724      warnings generated when CONFIG_PROC_FS was not defined in
725      the 3.2M driver.
726
727      Jerry Quinn <jlquinn@us.ibm.com> fixed PowerPC support (endian
728      problems) for wide cards.
729
730      Bryan Henderson <bryanh@giraffe-data.com> helped debug narrow
731      card error handling.
732
733      Manuel Veloso <veloso@pobox.com> worked hard on PowerPC narrow
734      board support and fixed a bug in AscGetEEPConfig().
735
736      Arnaldo Carvalho de Melo <acme@conectiva.com.br> made
737      save_flags/restore_flags changes.
738
739      Andy Kellner <AKellner@connectcom.net> continues the Advansys SCSI
740      driver development for ConnectCom (Version > 3.3F).
741
742   K. ConnectCom (AdvanSys) Contact Information
743
744      Mail:                   ConnectCom Solutions, Inc.
745                              1150 Ringwood Court
746                              San Jose, CA 95131
747      Operator/Sales:         1-408-383-9400
748      FAX:                    1-408-383-9612
749      Tech Support:           1-408-467-2930
750      Tech Support E-Mail:    linux@connectcom.net
751      FTP Site:               ftp.connectcom.net (login: anonymous)
752      Web Site:               http://www.connectcom.net
753
754 */
755
756 /*
757  * --- Linux Include Files
758  */
759
760 #include <linux/module.h>
761 #include <linux/string.h>
762 #include <linux/kernel.h>
763 #include <linux/types.h>
764 #include <linux/ioport.h>
765 #include <linux/interrupt.h>
766 #include <linux/delay.h>
767 #include <linux/slab.h>
768 #include <linux/mm.h>
769 #include <linux/proc_fs.h>
770 #include <linux/init.h>
771 #include <linux/blkdev.h>
772 #include <linux/isa.h>
773 #include <linux/eisa.h>
774 #include <linux/pci.h>
775 #include <linux/spinlock.h>
776 #include <linux/dma-mapping.h>
777
778 #include <asm/io.h>
779 #include <asm/system.h>
780 #include <asm/dma.h>
781
782 #include <scsi/scsi_cmnd.h>
783 #include <scsi/scsi_device.h>
784 #include <scsi/scsi_tcq.h>
785 #include <scsi/scsi.h>
786 #include <scsi/scsi_host.h>
787
788 /* FIXME: (by jejb@steeleye.com)
789  *
790  * Although all of the necessary command mapping places have the
791  * appropriate dma_map.. APIs, the driver still processes its internal
792  * queue using bus_to_virt() and virt_to_bus() which are illegal under
793  * the API.  The entire queue processing structure will need to be
794  * altered to fix this.
795  */
796 #warning this driver is still not properly converted to the DMA API
797
798 /*
799  * --- Driver Options
800  */
801
802 /* Enable driver assertions. */
803 #define ADVANSYS_ASSERT
804
805 /* Enable driver /proc statistics. */
806 #define ADVANSYS_STATS
807
808 /* Enable driver tracing. */
809 /* #define ADVANSYS_DEBUG */
810
811 /*
812  * --- Asc Library Constants and Macros
813  */
814
815 #define ASC_LIB_VERSION_MAJOR  1
816 #define ASC_LIB_VERSION_MINOR  24
817 #define ASC_LIB_SERIAL_NUMBER  123
818
819 /*
820  * Portable Data Types
821  *
822  * Any instance where a 32-bit long or pointer type is assumed
823  * for precision or HW defined structures, the following define
824  * types must be used. In Linux the char, short, and int types
825  * are all consistent at 8, 16, and 32 bits respectively. Pointers
826  * and long types are 64 bits on Alpha and UltraSPARC.
827  */
828 #define ASC_PADDR __u32         /* Physical/Bus address data type. */
829 #define ASC_VADDR __u32         /* Virtual address data type. */
830 #define ASC_DCNT  __u32         /* Unsigned Data count type. */
831 #define ASC_SDCNT __s32         /* Signed Data count type. */
832
833 /*
834  * These macros are used to convert a virtual address to a
835  * 32-bit value. This currently can be used on Linux Alpha
836  * which uses 64-bit virtual address but a 32-bit bus address.
837  * This is likely to break in the future, but doing this now
838  * will give us time to change the HW and FW to handle 64-bit
839  * addresses.
840  */
841 #define ASC_VADDR_TO_U32   virt_to_bus
842 #define ASC_U32_TO_VADDR   bus_to_virt
843
844 typedef unsigned char uchar;
845
846 #ifndef TRUE
847 #define TRUE     (1)
848 #endif
849 #ifndef FALSE
850 #define FALSE    (0)
851 #endif
852
853 #define EOF      (-1)
854 #define ERR      (-1)
855 #define UW_ERR   (uint)(0xFFFF)
856 #define isodd_word(val)   ((((uint)val) & (uint)0x0001) != 0)
857 #define AscPCIConfigVendorIDRegister      0x0000
858 #define AscPCIConfigDeviceIDRegister      0x0002
859 #define AscPCIConfigCommandRegister       0x0004
860 #define AscPCIConfigStatusRegister        0x0006
861 #define AscPCIConfigRevisionIDRegister    0x0008
862 #define AscPCIConfigCacheSize             0x000C
863 #define AscPCIConfigLatencyTimer          0x000D
864 #define AscPCIIOBaseRegister              0x0010
865 #define AscPCICmdRegBits_IOMemBusMaster   0x0007
866 #define ASC_PCI_ID2FUNC(id)   (((id) >> 8) & 0x7)
867 #define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
868
869 #define  ASC_DVCLIB_CALL_DONE     (1)
870 #define  ASC_DVCLIB_CALL_FAILED   (0)
871 #define  ASC_DVCLIB_CALL_ERROR    (-1)
872
873 #define PCI_VENDOR_ID_ASP               0x10cd
874 #define PCI_DEVICE_ID_ASP_1200A         0x1100
875 #define PCI_DEVICE_ID_ASP_ABP940        0x1200
876 #define PCI_DEVICE_ID_ASP_ABP940U       0x1300
877 #define PCI_DEVICE_ID_ASP_ABP940UW      0x2300
878 #define PCI_DEVICE_ID_38C0800_REV1      0x2500
879 #define PCI_DEVICE_ID_38C1600_REV1      0x2700
880
881 /*
882  * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
883  * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
884  * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
885  * SRB structure.
886  */
887 #define CC_VERY_LONG_SG_LIST 0
888 #define ASC_SRB2SCSIQ(srb_ptr)  (srb_ptr)
889
890 #define PortAddr                 unsigned short /* port address size  */
891 #define inp(port)                inb(port)
892 #define outp(port, byte)         outb((byte), (port))
893
894 #define inpw(port)               inw(port)
895 #define outpw(port, word)        outw((word), (port))
896
897 #define ASC_MAX_SG_QUEUE    7
898 #define ASC_MAX_SG_LIST     255
899
900 #define ASC_CS_TYPE  unsigned short
901
902 #define ASC_IS_ISA          (0x0001)
903 #define ASC_IS_ISAPNP       (0x0081)
904 #define ASC_IS_EISA         (0x0002)
905 #define ASC_IS_PCI          (0x0004)
906 #define ASC_IS_PCI_ULTRA    (0x0104)
907 #define ASC_IS_PCMCIA       (0x0008)
908 #define ASC_IS_MCA          (0x0020)
909 #define ASC_IS_VL           (0x0040)
910 #define ASC_ISA_PNP_PORT_ADDR  (0x279)
911 #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
912 #define ASC_IS_WIDESCSI_16  (0x0100)
913 #define ASC_IS_WIDESCSI_32  (0x0200)
914 #define ASC_IS_BIG_ENDIAN   (0x8000)
915 #define ASC_CHIP_MIN_VER_VL      (0x01)
916 #define ASC_CHIP_MAX_VER_VL      (0x07)
917 #define ASC_CHIP_MIN_VER_PCI     (0x09)
918 #define ASC_CHIP_MAX_VER_PCI     (0x0F)
919 #define ASC_CHIP_VER_PCI_BIT     (0x08)
920 #define ASC_CHIP_MIN_VER_ISA     (0x11)
921 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
922 #define ASC_CHIP_MAX_VER_ISA     (0x27)
923 #define ASC_CHIP_VER_ISA_BIT     (0x30)
924 #define ASC_CHIP_VER_ISAPNP_BIT  (0x20)
925 #define ASC_CHIP_VER_ASYN_BUG    (0x21)
926 #define ASC_CHIP_VER_PCI             0x08
927 #define ASC_CHIP_VER_PCI_ULTRA_3150  (ASC_CHIP_VER_PCI | 0x02)
928 #define ASC_CHIP_VER_PCI_ULTRA_3050  (ASC_CHIP_VER_PCI | 0x03)
929 #define ASC_CHIP_MIN_VER_EISA (0x41)
930 #define ASC_CHIP_MAX_VER_EISA (0x47)
931 #define ASC_CHIP_VER_EISA_BIT (0x40)
932 #define ASC_CHIP_LATEST_VER_EISA   ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
933 #define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER   0x21
934 #define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER   0x0A
935 #define ASC_MAX_VL_DMA_ADDR     (0x07FFFFFFL)
936 #define ASC_MAX_VL_DMA_COUNT    (0x07FFFFFFL)
937 #define ASC_MAX_PCI_DMA_ADDR    (0xFFFFFFFFL)
938 #define ASC_MAX_PCI_DMA_COUNT   (0xFFFFFFFFL)
939 #define ASC_MAX_ISA_DMA_ADDR    (0x00FFFFFFL)
940 #define ASC_MAX_ISA_DMA_COUNT   (0x00FFFFFFL)
941 #define ASC_MAX_EISA_DMA_ADDR   (0x07FFFFFFL)
942 #define ASC_MAX_EISA_DMA_COUNT  (0x07FFFFFFL)
943
944 #define ASC_SCSI_ID_BITS  3
945 #define ASC_SCSI_TIX_TYPE     uchar
946 #define ASC_ALL_DEVICE_BIT_SET  0xFF
947 #define ASC_SCSI_BIT_ID_TYPE  uchar
948 #define ASC_MAX_TID       7
949 #define ASC_MAX_LUN       7
950 #define ASC_SCSI_WIDTH_BIT_SET  0xFF
951 #define ASC_MAX_SENSE_LEN   32
952 #define ASC_MIN_SENSE_LEN   14
953 #define ASC_MAX_CDB_LEN     12
954 #define ASC_SCSI_RESET_HOLD_TIME_US  60
955
956 #define ADV_INQ_CLOCKING_ST_ONLY    0x0
957 #define ADV_INQ_CLOCKING_DT_ONLY    0x1
958 #define ADV_INQ_CLOCKING_ST_AND_DT  0x3
959
960 /*
961  * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
962  * and CmdDt (Command Support Data) field bit definitions.
963  */
964 #define ADV_INQ_RTN_VPD_AND_CMDDT           0x3
965 #define ADV_INQ_RTN_CMDDT_FOR_OP_CODE       0x2
966 #define ADV_INQ_RTN_VPD_FOR_PG_CODE         0x1
967 #define ADV_INQ_RTN_STD_INQUIRY_DATA        0x0
968
969 #define ASC_SCSIDIR_NOCHK    0x00
970 #define ASC_SCSIDIR_T2H      0x08
971 #define ASC_SCSIDIR_H2T      0x10
972 #define ASC_SCSIDIR_NODATA   0x18
973 #define SCSI_ASC_NOMEDIA          0x3A
974 #define ASC_SRB_HOST(x)  ((uchar)((uchar)(x) >> 4))
975 #define ASC_SRB_TID(x)   ((uchar)((uchar)(x) & (uchar)0x0F))
976 #define ASC_SRB_LUN(x)   ((uchar)((uint)(x) >> 13))
977 #define PUT_CDB1(x)   ((uchar)((uint)(x) >> 8))
978 #define MS_CMD_DONE    0x00
979 #define MS_EXTEND      0x01
980 #define MS_SDTR_LEN    0x03
981 #define MS_SDTR_CODE   0x01
982 #define MS_WDTR_LEN    0x02
983 #define MS_WDTR_CODE   0x03
984 #define MS_MDP_LEN    0x05
985 #define MS_MDP_CODE   0x00
986
987 /*
988  * Inquiry data structure and bitfield macros
989  *
990  * Only quantities of more than 1 bit are shifted, since the others are
991  * just tested for true or false. C bitfields aren't portable between big
992  * and little-endian platforms so they are not used.
993  */
994
995 #define ASC_INQ_DVC_TYPE(inq)       ((inq)->periph & 0x1f)
996 #define ASC_INQ_QUALIFIER(inq)      (((inq)->periph & 0xe0) >> 5)
997 #define ASC_INQ_DVC_TYPE_MOD(inq)   ((inq)->devtype & 0x7f)
998 #define ASC_INQ_REMOVABLE(inq)      ((inq)->devtype & 0x80)
999 #define ASC_INQ_ANSI_VER(inq)       ((inq)->ver & 0x07)
1000 #define ASC_INQ_ECMA_VER(inq)       (((inq)->ver & 0x38) >> 3)
1001 #define ASC_INQ_ISO_VER(inq)        (((inq)->ver & 0xc0) >> 6)
1002 #define ASC_INQ_RESPONSE_FMT(inq)   ((inq)->byte3 & 0x0f)
1003 #define ASC_INQ_TERM_IO(inq)        ((inq)->byte3 & 0x40)
1004 #define ASC_INQ_ASYNC_NOTIF(inq)    ((inq)->byte3 & 0x80)
1005 #define ASC_INQ_SOFT_RESET(inq)     ((inq)->flags & 0x01)
1006 #define ASC_INQ_CMD_QUEUE(inq)      ((inq)->flags & 0x02)
1007 #define ASC_INQ_LINK_CMD(inq)       ((inq)->flags & 0x08)
1008 #define ASC_INQ_SYNC(inq)           ((inq)->flags & 0x10)
1009 #define ASC_INQ_WIDE16(inq)         ((inq)->flags & 0x20)
1010 #define ASC_INQ_WIDE32(inq)         ((inq)->flags & 0x40)
1011 #define ASC_INQ_REL_ADDR(inq)       ((inq)->flags & 0x80)
1012 #define ASC_INQ_INFO_UNIT(inq)      ((inq)->info & 0x01)
1013 #define ASC_INQ_QUICK_ARB(inq)      ((inq)->info & 0x02)
1014 #define ASC_INQ_CLOCKING(inq)       (((inq)->info & 0x0c) >> 2)
1015
1016 typedef struct {
1017         uchar periph;
1018         uchar devtype;
1019         uchar ver;
1020         uchar byte3;
1021         uchar add_len;
1022         uchar res1;
1023         uchar res2;
1024         uchar flags;
1025         uchar vendor_id[8];
1026         uchar product_id[16];
1027         uchar product_rev_level[4];
1028 } ASC_SCSI_INQUIRY;
1029
1030 #define ASC_SG_LIST_PER_Q   7
1031 #define QS_FREE        0x00
1032 #define QS_READY       0x01
1033 #define QS_DISC1       0x02
1034 #define QS_DISC2       0x04
1035 #define QS_BUSY        0x08
1036 #define QS_ABORTED     0x40
1037 #define QS_DONE        0x80
1038 #define QC_NO_CALLBACK   0x01
1039 #define QC_SG_SWAP_QUEUE 0x02
1040 #define QC_SG_HEAD       0x04
1041 #define QC_DATA_IN       0x08
1042 #define QC_DATA_OUT      0x10
1043 #define QC_URGENT        0x20
1044 #define QC_MSG_OUT       0x40
1045 #define QC_REQ_SENSE     0x80
1046 #define QCSG_SG_XFER_LIST  0x02
1047 #define QCSG_SG_XFER_MORE  0x04
1048 #define QCSG_SG_XFER_END   0x08
1049 #define QD_IN_PROGRESS       0x00
1050 #define QD_NO_ERROR          0x01
1051 #define QD_ABORTED_BY_HOST   0x02
1052 #define QD_WITH_ERROR        0x04
1053 #define QD_INVALID_REQUEST   0x80
1054 #define QD_INVALID_HOST_NUM  0x81
1055 #define QD_INVALID_DEVICE    0x82
1056 #define QD_ERR_INTERNAL      0xFF
1057 #define QHSTA_NO_ERROR               0x00
1058 #define QHSTA_M_SEL_TIMEOUT          0x11
1059 #define QHSTA_M_DATA_OVER_RUN        0x12
1060 #define QHSTA_M_DATA_UNDER_RUN       0x12
1061 #define QHSTA_M_UNEXPECTED_BUS_FREE  0x13
1062 #define QHSTA_M_BAD_BUS_PHASE_SEQ    0x14
1063 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1064 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET  0x22
1065 #define QHSTA_D_HOST_ABORT_FAILED       0x23
1066 #define QHSTA_D_EXE_SCSI_Q_FAILED       0x24
1067 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1068 #define QHSTA_D_ASPI_NO_BUF_POOL        0x26
1069 #define QHSTA_M_WTM_TIMEOUT         0x41
1070 #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
1071 #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
1072 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1073 #define QHSTA_M_TARGET_STATUS_BUSY  0x45
1074 #define QHSTA_M_BAD_TAG_CODE        0x46
1075 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY  0x47
1076 #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1077 #define QHSTA_D_LRAM_CMP_ERROR        0x81
1078 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1079 #define ASC_FLAG_SCSIQ_REQ        0x01
1080 #define ASC_FLAG_BIOS_SCSIQ_REQ   0x02
1081 #define ASC_FLAG_BIOS_ASYNC_IO    0x04
1082 #define ASC_FLAG_SRB_LINEAR_ADDR  0x08
1083 #define ASC_FLAG_WIN16            0x10
1084 #define ASC_FLAG_WIN32            0x20
1085 #define ASC_FLAG_ISA_OVER_16MB    0x40
1086 #define ASC_FLAG_DOS_VM_CALLBACK  0x80
1087 #define ASC_TAG_FLAG_EXTRA_BYTES               0x10
1088 #define ASC_TAG_FLAG_DISABLE_DISCONNECT        0x04
1089 #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX  0x08
1090 #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1091 #define ASC_SCSIQ_CPY_BEG              4
1092 #define ASC_SCSIQ_SGHD_CPY_BEG         2
1093 #define ASC_SCSIQ_B_FWD                0
1094 #define ASC_SCSIQ_B_BWD                1
1095 #define ASC_SCSIQ_B_STATUS             2
1096 #define ASC_SCSIQ_B_QNO                3
1097 #define ASC_SCSIQ_B_CNTL               4
1098 #define ASC_SCSIQ_B_SG_QUEUE_CNT       5
1099 #define ASC_SCSIQ_D_DATA_ADDR          8
1100 #define ASC_SCSIQ_D_DATA_CNT          12
1101 #define ASC_SCSIQ_B_SENSE_LEN         20
1102 #define ASC_SCSIQ_DONE_INFO_BEG       22
1103 #define ASC_SCSIQ_D_SRBPTR            22
1104 #define ASC_SCSIQ_B_TARGET_IX         26
1105 #define ASC_SCSIQ_B_CDB_LEN           28
1106 #define ASC_SCSIQ_B_TAG_CODE          29
1107 #define ASC_SCSIQ_W_VM_ID             30
1108 #define ASC_SCSIQ_DONE_STATUS         32
1109 #define ASC_SCSIQ_HOST_STATUS         33
1110 #define ASC_SCSIQ_SCSI_STATUS         34
1111 #define ASC_SCSIQ_CDB_BEG             36
1112 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1113 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT  60
1114 #define ASC_SCSIQ_B_FIRST_SG_WK_QP    48
1115 #define ASC_SCSIQ_B_SG_WK_QP          49
1116 #define ASC_SCSIQ_B_SG_WK_IX          50
1117 #define ASC_SCSIQ_W_ALT_DC1           52
1118 #define ASC_SCSIQ_B_LIST_CNT          6
1119 #define ASC_SCSIQ_B_CUR_LIST_CNT      7
1120 #define ASC_SGQ_B_SG_CNTL             4
1121 #define ASC_SGQ_B_SG_HEAD_QP          5
1122 #define ASC_SGQ_B_SG_LIST_CNT         6
1123 #define ASC_SGQ_B_SG_CUR_LIST_CNT     7
1124 #define ASC_SGQ_LIST_BEG              8
1125 #define ASC_DEF_SCSI1_QNG    4
1126 #define ASC_MAX_SCSI1_QNG    4
1127 #define ASC_DEF_SCSI2_QNG    16
1128 #define ASC_MAX_SCSI2_QNG    32
1129 #define ASC_TAG_CODE_MASK    0x23
1130 #define ASC_STOP_REQ_RISC_STOP      0x01
1131 #define ASC_STOP_ACK_RISC_STOP      0x03
1132 #define ASC_STOP_CLEAN_UP_BUSY_Q    0x10
1133 #define ASC_STOP_CLEAN_UP_DISC_Q    0x20
1134 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1135 #define ASC_TIDLUN_TO_IX(tid, lun)  (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1136 #define ASC_TID_TO_TARGET_ID(tid)   (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1137 #define ASC_TIX_TO_TARGET_ID(tix)   (0x01 << ((tix) & ASC_MAX_TID))
1138 #define ASC_TIX_TO_TID(tix)         ((tix) & ASC_MAX_TID)
1139 #define ASC_TID_TO_TIX(tid)         ((tid) & ASC_MAX_TID)
1140 #define ASC_TIX_TO_LUN(tix)         (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1141 #define ASC_QNO_TO_QADDR(q_no)      ((ASC_QADR_BEG)+((int)(q_no) << 6))
1142
1143 typedef struct asc_scsiq_1 {
1144         uchar status;
1145         uchar q_no;
1146         uchar cntl;
1147         uchar sg_queue_cnt;
1148         uchar target_id;
1149         uchar target_lun;
1150         ASC_PADDR data_addr;
1151         ASC_DCNT data_cnt;
1152         ASC_PADDR sense_addr;
1153         uchar sense_len;
1154         uchar extra_bytes;
1155 } ASC_SCSIQ_1;
1156
1157 typedef struct asc_scsiq_2 {
1158         ASC_VADDR srb_ptr;
1159         uchar target_ix;
1160         uchar flag;
1161         uchar cdb_len;
1162         uchar tag_code;
1163         ushort vm_id;
1164 } ASC_SCSIQ_2;
1165
1166 typedef struct asc_scsiq_3 {
1167         uchar done_stat;
1168         uchar host_stat;
1169         uchar scsi_stat;
1170         uchar scsi_msg;
1171 } ASC_SCSIQ_3;
1172
1173 typedef struct asc_scsiq_4 {
1174         uchar cdb[ASC_MAX_CDB_LEN];
1175         uchar y_first_sg_list_qp;
1176         uchar y_working_sg_qp;
1177         uchar y_working_sg_ix;
1178         uchar y_res;
1179         ushort x_req_count;
1180         ushort x_reconnect_rtn;
1181         ASC_PADDR x_saved_data_addr;
1182         ASC_DCNT x_saved_data_cnt;
1183 } ASC_SCSIQ_4;
1184
1185 typedef struct asc_q_done_info {
1186         ASC_SCSIQ_2 d2;
1187         ASC_SCSIQ_3 d3;
1188         uchar q_status;
1189         uchar q_no;
1190         uchar cntl;
1191         uchar sense_len;
1192         uchar extra_bytes;
1193         uchar res;
1194         ASC_DCNT remain_bytes;
1195 } ASC_QDONE_INFO;
1196
1197 typedef struct asc_sg_list {
1198         ASC_PADDR addr;
1199         ASC_DCNT bytes;
1200 } ASC_SG_LIST;
1201
1202 typedef struct asc_sg_head {
1203         ushort entry_cnt;
1204         ushort queue_cnt;
1205         ushort entry_to_copy;
1206         ushort res;
1207         ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1208 } ASC_SG_HEAD;
1209
1210 #define ASC_MIN_SG_LIST   2
1211
1212 typedef struct asc_min_sg_head {
1213         ushort entry_cnt;
1214         ushort queue_cnt;
1215         ushort entry_to_copy;
1216         ushort res;
1217         ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
1218 } ASC_MIN_SG_HEAD;
1219
1220 #define QCX_SORT        (0x0001)
1221 #define QCX_COALEASE    (0x0002)
1222
1223 typedef struct asc_scsi_q {
1224         ASC_SCSIQ_1 q1;
1225         ASC_SCSIQ_2 q2;
1226         uchar *cdbptr;
1227         ASC_SG_HEAD *sg_head;
1228         ushort remain_sg_entry_cnt;
1229         ushort next_sg_index;
1230 } ASC_SCSI_Q;
1231
1232 typedef struct asc_scsi_req_q {
1233         ASC_SCSIQ_1 r1;
1234         ASC_SCSIQ_2 r2;
1235         uchar *cdbptr;
1236         ASC_SG_HEAD *sg_head;
1237         uchar *sense_ptr;
1238         ASC_SCSIQ_3 r3;
1239         uchar cdb[ASC_MAX_CDB_LEN];
1240         uchar sense[ASC_MIN_SENSE_LEN];
1241 } ASC_SCSI_REQ_Q;
1242
1243 typedef struct asc_scsi_bios_req_q {
1244         ASC_SCSIQ_1 r1;
1245         ASC_SCSIQ_2 r2;
1246         uchar *cdbptr;
1247         ASC_SG_HEAD *sg_head;
1248         uchar *sense_ptr;
1249         ASC_SCSIQ_3 r3;
1250         uchar cdb[ASC_MAX_CDB_LEN];
1251         uchar sense[ASC_MIN_SENSE_LEN];
1252 } ASC_SCSI_BIOS_REQ_Q;
1253
1254 typedef struct asc_risc_q {
1255         uchar fwd;
1256         uchar bwd;
1257         ASC_SCSIQ_1 i1;
1258         ASC_SCSIQ_2 i2;
1259         ASC_SCSIQ_3 i3;
1260         ASC_SCSIQ_4 i4;
1261 } ASC_RISC_Q;
1262
1263 typedef struct asc_sg_list_q {
1264         uchar seq_no;
1265         uchar q_no;
1266         uchar cntl;
1267         uchar sg_head_qp;
1268         uchar sg_list_cnt;
1269         uchar sg_cur_list_cnt;
1270 } ASC_SG_LIST_Q;
1271
1272 typedef struct asc_risc_sg_list_q {
1273         uchar fwd;
1274         uchar bwd;
1275         ASC_SG_LIST_Q sg;
1276         ASC_SG_LIST sg_list[7];
1277 } ASC_RISC_SG_LIST_Q;
1278
1279 #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP  0x1000000UL
1280 #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP  1024
1281 #define ASCQ_ERR_NO_ERROR             0
1282 #define ASCQ_ERR_IO_NOT_FOUND         1
1283 #define ASCQ_ERR_LOCAL_MEM            2
1284 #define ASCQ_ERR_CHKSUM               3
1285 #define ASCQ_ERR_START_CHIP           4
1286 #define ASCQ_ERR_INT_TARGET_ID        5
1287 #define ASCQ_ERR_INT_LOCAL_MEM        6
1288 #define ASCQ_ERR_HALT_RISC            7
1289 #define ASCQ_ERR_GET_ASPI_ENTRY       8
1290 #define ASCQ_ERR_CLOSE_ASPI           9
1291 #define ASCQ_ERR_HOST_INQUIRY         0x0A
1292 #define ASCQ_ERR_SAVED_SRB_BAD        0x0B
1293 #define ASCQ_ERR_QCNTL_SG_LIST        0x0C
1294 #define ASCQ_ERR_Q_STATUS             0x0D
1295 #define ASCQ_ERR_WR_SCSIQ             0x0E
1296 #define ASCQ_ERR_PC_ADDR              0x0F
1297 #define ASCQ_ERR_SYN_OFFSET           0x10
1298 #define ASCQ_ERR_SYN_XFER_TIME        0x11
1299 #define ASCQ_ERR_LOCK_DMA             0x12
1300 #define ASCQ_ERR_UNLOCK_DMA           0x13
1301 #define ASCQ_ERR_VDS_CHK_INSTALL      0x14
1302 #define ASCQ_ERR_MICRO_CODE_HALT      0x15
1303 #define ASCQ_ERR_SET_LRAM_ADDR        0x16
1304 #define ASCQ_ERR_CUR_QNG              0x17
1305 #define ASCQ_ERR_SG_Q_LINKS           0x18
1306 #define ASCQ_ERR_SCSIQ_PTR            0x19
1307 #define ASCQ_ERR_ISR_RE_ENTRY         0x1A
1308 #define ASCQ_ERR_CRITICAL_RE_ENTRY    0x1B
1309 #define ASCQ_ERR_ISR_ON_CRITICAL      0x1C
1310 #define ASCQ_ERR_SG_LIST_ODD_ADDRESS  0x1D
1311 #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1312 #define ASCQ_ERR_SCSIQ_NULL_PTR       0x1F
1313 #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR   0x20
1314 #define ASCQ_ERR_GET_NUM_OF_FREE_Q    0x21
1315 #define ASCQ_ERR_SEND_SCSI_Q          0x22
1316 #define ASCQ_ERR_HOST_REQ_RISC_HALT   0x23
1317 #define ASCQ_ERR_RESET_SDTR           0x24
1318
1319 /*
1320  * Warning code values are set in ASC_DVC_VAR  'warn_code'.
1321  */
1322 #define ASC_WARN_NO_ERROR             0x0000
1323 #define ASC_WARN_IO_PORT_ROTATE       0x0001
1324 #define ASC_WARN_EEPROM_CHKSUM        0x0002
1325 #define ASC_WARN_IRQ_MODIFIED         0x0004
1326 #define ASC_WARN_AUTO_CONFIG          0x0008
1327 #define ASC_WARN_CMD_QNG_CONFLICT     0x0010
1328 #define ASC_WARN_EEPROM_RECOVER       0x0020
1329 #define ASC_WARN_CFG_MSW_RECOVER      0x0040
1330 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1331
1332 /*
1333  * Error code values are set in ASC_DVC_VAR  'err_code'.
1334  */
1335 #define ASC_IERR_WRITE_EEPROM         0x0001
1336 #define ASC_IERR_MCODE_CHKSUM         0x0002
1337 #define ASC_IERR_SET_PC_ADDR          0x0004
1338 #define ASC_IERR_START_STOP_CHIP      0x0008
1339 #define ASC_IERR_IRQ_NO               0x0010
1340 #define ASC_IERR_SET_IRQ_NO           0x0020
1341 #define ASC_IERR_CHIP_VERSION         0x0040
1342 #define ASC_IERR_SET_SCSI_ID          0x0080
1343 #define ASC_IERR_GET_PHY_ADDR         0x0100
1344 #define ASC_IERR_BAD_SIGNATURE        0x0200
1345 #define ASC_IERR_NO_BUS_TYPE          0x0400
1346 #define ASC_IERR_SCAM                 0x0800
1347 #define ASC_IERR_SET_SDTR             0x1000
1348 #define ASC_IERR_RW_LRAM              0x8000
1349
1350 #define ASC_DEF_IRQ_NO  10
1351 #define ASC_MAX_IRQ_NO  15
1352 #define ASC_MIN_IRQ_NO  10
1353 #define ASC_MIN_REMAIN_Q        (0x02)
1354 #define ASC_DEF_MAX_TOTAL_QNG   (0xF0)
1355 #define ASC_MIN_TAG_Q_PER_DVC   (0x04)
1356 #define ASC_DEF_TAG_Q_PER_DVC   (0x04)
1357 #define ASC_MIN_FREE_Q        ASC_MIN_REMAIN_Q
1358 #define ASC_MIN_TOTAL_QNG     ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1359 #define ASC_MAX_TOTAL_QNG 240
1360 #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1361 #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG   8
1362 #define ASC_MAX_PCI_INRAM_TOTAL_QNG  20
1363 #define ASC_MAX_INRAM_TAG_QNG   16
1364 #define ASC_IOADR_TABLE_MAX_IX  11
1365 #define ASC_IOADR_GAP   0x10
1366 #define ASC_LIB_SCSIQ_WK_SP        256
1367 #define ASC_MAX_SYN_XFER_NO        16
1368 #define ASC_SYN_MAX_OFFSET         0x0F
1369 #define ASC_DEF_SDTR_OFFSET        0x0F
1370 #define ASC_DEF_SDTR_INDEX         0x00
1371 #define ASC_SDTR_ULTRA_PCI_10MB_INDEX  0x02
1372 #define SYN_XFER_NS_0  25
1373 #define SYN_XFER_NS_1  30
1374 #define SYN_XFER_NS_2  35
1375 #define SYN_XFER_NS_3  40
1376 #define SYN_XFER_NS_4  50
1377 #define SYN_XFER_NS_5  60
1378 #define SYN_XFER_NS_6  70
1379 #define SYN_XFER_NS_7  85
1380 #define SYN_ULTRA_XFER_NS_0    12
1381 #define SYN_ULTRA_XFER_NS_1    19
1382 #define SYN_ULTRA_XFER_NS_2    25
1383 #define SYN_ULTRA_XFER_NS_3    32
1384 #define SYN_ULTRA_XFER_NS_4    38
1385 #define SYN_ULTRA_XFER_NS_5    44
1386 #define SYN_ULTRA_XFER_NS_6    50
1387 #define SYN_ULTRA_XFER_NS_7    57
1388 #define SYN_ULTRA_XFER_NS_8    63
1389 #define SYN_ULTRA_XFER_NS_9    69
1390 #define SYN_ULTRA_XFER_NS_10   75
1391 #define SYN_ULTRA_XFER_NS_11   82
1392 #define SYN_ULTRA_XFER_NS_12   88
1393 #define SYN_ULTRA_XFER_NS_13   94
1394 #define SYN_ULTRA_XFER_NS_14  100
1395 #define SYN_ULTRA_XFER_NS_15  107
1396
1397 typedef struct ext_msg {
1398         uchar msg_type;
1399         uchar msg_len;
1400         uchar msg_req;
1401         union {
1402                 struct {
1403                         uchar sdtr_xfer_period;
1404                         uchar sdtr_req_ack_offset;
1405                 } sdtr;
1406                 struct {
1407                         uchar wdtr_width;
1408                 } wdtr;
1409                 struct {
1410                         uchar mdp_b3;
1411                         uchar mdp_b2;
1412                         uchar mdp_b1;
1413                         uchar mdp_b0;
1414                 } mdp;
1415         } u_ext_msg;
1416         uchar res;
1417 } EXT_MSG;
1418
1419 #define xfer_period     u_ext_msg.sdtr.sdtr_xfer_period
1420 #define req_ack_offset  u_ext_msg.sdtr.sdtr_req_ack_offset
1421 #define wdtr_width      u_ext_msg.wdtr.wdtr_width
1422 #define mdp_b3          u_ext_msg.mdp_b3
1423 #define mdp_b2          u_ext_msg.mdp_b2
1424 #define mdp_b1          u_ext_msg.mdp_b1
1425 #define mdp_b0          u_ext_msg.mdp_b0
1426
1427 typedef struct asc_dvc_cfg {
1428         ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1429         ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1430         ASC_SCSI_BIT_ID_TYPE disc_enable;
1431         ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1432         uchar chip_scsi_id;
1433         uchar isa_dma_speed;
1434         uchar isa_dma_channel;
1435         uchar chip_version;
1436         ushort lib_serial_no;
1437         ushort lib_version;
1438         ushort mcode_date;
1439         ushort mcode_version;
1440         uchar max_tag_qng[ASC_MAX_TID + 1];
1441         uchar *overrun_buf;
1442         uchar sdtr_period_offset[ASC_MAX_TID + 1];
1443         ushort pci_slot_info;
1444         uchar adapter_info[6];
1445         struct device *dev;
1446 } ASC_DVC_CFG;
1447
1448 #define ASC_DEF_DVC_CNTL       0xFFFF
1449 #define ASC_DEF_CHIP_SCSI_ID   7
1450 #define ASC_DEF_ISA_DMA_SPEED  4
1451 #define ASC_INIT_STATE_NULL          0x0000
1452 #define ASC_INIT_STATE_BEG_GET_CFG   0x0001
1453 #define ASC_INIT_STATE_END_GET_CFG   0x0002
1454 #define ASC_INIT_STATE_BEG_SET_CFG   0x0004
1455 #define ASC_INIT_STATE_END_SET_CFG   0x0008
1456 #define ASC_INIT_STATE_BEG_LOAD_MC   0x0010
1457 #define ASC_INIT_STATE_END_LOAD_MC   0x0020
1458 #define ASC_INIT_STATE_BEG_INQUIRY   0x0040
1459 #define ASC_INIT_STATE_END_INQUIRY   0x0080
1460 #define ASC_INIT_RESET_SCSI_DONE     0x0100
1461 #define ASC_INIT_STATE_WITHOUT_EEP   0x8000
1462 #define ASC_BUG_FIX_IF_NOT_DWB       0x0001
1463 #define ASC_BUG_FIX_ASYN_USE_SYN     0x0002
1464 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1465 #define ASC_MIN_TAGGED_CMD  7
1466 #define ASC_MAX_SCSI_RESET_WAIT      30
1467
1468 struct asc_dvc_var;             /* Forward Declaration. */
1469
1470 typedef void (*ASC_ISR_CALLBACK) (struct asc_dvc_var *, ASC_QDONE_INFO *);
1471 typedef int (*ASC_EXE_CALLBACK) (struct asc_dvc_var *, ASC_SCSI_Q *);
1472
1473 typedef struct asc_dvc_var {
1474         PortAddr iop_base;
1475         ushort err_code;
1476         ushort dvc_cntl;
1477         ushort bug_fix_cntl;
1478         ushort bus_type;
1479         ASC_ISR_CALLBACK isr_callback;
1480         ASC_EXE_CALLBACK exe_callback;
1481         ASC_SCSI_BIT_ID_TYPE init_sdtr;
1482         ASC_SCSI_BIT_ID_TYPE sdtr_done;
1483         ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1484         ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1485         ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1486         ASC_SCSI_BIT_ID_TYPE start_motor;
1487         uchar scsi_reset_wait;
1488         uchar chip_no;
1489         char is_in_int;
1490         uchar max_total_qng;
1491         uchar cur_total_qng;
1492         uchar in_critical_cnt;
1493         uchar irq_no;
1494         uchar last_q_shortage;
1495         ushort init_state;
1496         uchar cur_dvc_qng[ASC_MAX_TID + 1];
1497         uchar max_dvc_qng[ASC_MAX_TID + 1];
1498         ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
1499         ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
1500         uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1501         ASC_DVC_CFG *cfg;
1502         ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1503         char redo_scam;
1504         ushort res2;
1505         uchar dos_int13_table[ASC_MAX_TID + 1];
1506         ASC_DCNT max_dma_count;
1507         ASC_SCSI_BIT_ID_TYPE no_scam;
1508         ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1509         uchar max_sdtr_index;
1510         uchar host_init_sdtr_index;
1511         struct asc_board *drv_ptr;
1512         ASC_DCNT uc_break;
1513 } ASC_DVC_VAR;
1514
1515 typedef struct asc_dvc_inq_info {
1516         uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1517 } ASC_DVC_INQ_INFO;
1518
1519 typedef struct asc_cap_info {
1520         ASC_DCNT lba;
1521         ASC_DCNT blk_size;
1522 } ASC_CAP_INFO;
1523
1524 typedef struct asc_cap_info_array {
1525         ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1526 } ASC_CAP_INFO_ARRAY;
1527
1528 #define ASC_MCNTL_NO_SEL_TIMEOUT  (ushort)0x0001
1529 #define ASC_MCNTL_NULL_TARGET     (ushort)0x0002
1530 #define ASC_CNTL_INITIATOR         (ushort)0x0001
1531 #define ASC_CNTL_BIOS_GT_1GB       (ushort)0x0002
1532 #define ASC_CNTL_BIOS_GT_2_DISK    (ushort)0x0004
1533 #define ASC_CNTL_BIOS_REMOVABLE    (ushort)0x0008
1534 #define ASC_CNTL_NO_SCAM           (ushort)0x0010
1535 #define ASC_CNTL_INT_MULTI_Q       (ushort)0x0080
1536 #define ASC_CNTL_NO_LUN_SUPPORT    (ushort)0x0040
1537 #define ASC_CNTL_NO_VERIFY_COPY    (ushort)0x0100
1538 #define ASC_CNTL_RESET_SCSI        (ushort)0x0200
1539 #define ASC_CNTL_INIT_INQUIRY      (ushort)0x0400
1540 #define ASC_CNTL_INIT_VERBOSE      (ushort)0x0800
1541 #define ASC_CNTL_SCSI_PARITY       (ushort)0x1000
1542 #define ASC_CNTL_BURST_MODE        (ushort)0x2000
1543 #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1544 #define ASC_EEP_DVC_CFG_BEG_VL    2
1545 #define ASC_EEP_MAX_DVC_ADDR_VL   15
1546 #define ASC_EEP_DVC_CFG_BEG      32
1547 #define ASC_EEP_MAX_DVC_ADDR     45
1548 #define ASC_EEP_DEFINED_WORDS    10
1549 #define ASC_EEP_MAX_ADDR         63
1550 #define ASC_EEP_RES_WORDS         0
1551 #define ASC_EEP_MAX_RETRY        20
1552 #define ASC_MAX_INIT_BUSY_RETRY   8
1553 #define ASC_EEP_ISA_PNP_WSIZE    16
1554
1555 /*
1556  * These macros keep the chip SCSI id and ISA DMA speed
1557  * bitfields in board order. C bitfields aren't portable
1558  * between big and little-endian platforms so they are
1559  * not used.
1560  */
1561
1562 #define ASC_EEP_GET_CHIP_ID(cfg)    ((cfg)->id_speed & 0x0f)
1563 #define ASC_EEP_GET_DMA_SPD(cfg)    (((cfg)->id_speed & 0xf0) >> 4)
1564 #define ASC_EEP_SET_CHIP_ID(cfg, sid) \
1565    ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
1566 #define ASC_EEP_SET_DMA_SPD(cfg, spd) \
1567    ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
1568
1569 typedef struct asceep_config {
1570         ushort cfg_lsw;
1571         ushort cfg_msw;
1572         uchar init_sdtr;
1573         uchar disc_enable;
1574         uchar use_cmd_qng;
1575         uchar start_motor;
1576         uchar max_total_qng;
1577         uchar max_tag_qng;
1578         uchar bios_scan;
1579         uchar power_up_wait;
1580         uchar no_scam;
1581         uchar id_speed;         /* low order 4 bits is chip scsi id */
1582         /* high order 4 bits is isa dma speed */
1583         uchar dos_int13_table[ASC_MAX_TID + 1];
1584         uchar adapter_info[6];
1585         ushort cntl;
1586         ushort chksum;
1587 } ASCEEP_CONFIG;
1588
1589 #define ASC_PCI_CFG_LSW_SCSI_PARITY  0x0800
1590 #define ASC_PCI_CFG_LSW_BURST_MODE   0x0080
1591 #define ASC_PCI_CFG_LSW_INTR_ABLE    0x0020
1592
1593 #define ASC_EEP_CMD_READ          0x80
1594 #define ASC_EEP_CMD_WRITE         0x40
1595 #define ASC_EEP_CMD_WRITE_ABLE    0x30
1596 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
1597 #define ASC_OVERRUN_BSIZE  0x00000048UL
1598 #define ASC_CTRL_BREAK_ONCE        0x0001
1599 #define ASC_CTRL_BREAK_STAY_IDLE   0x0002
1600 #define ASCV_MSGOUT_BEG         0x0000
1601 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1602 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1603 #define ASCV_BREAK_SAVED_CODE   (ushort)0x0006
1604 #define ASCV_MSGIN_BEG          (ASCV_MSGOUT_BEG+8)
1605 #define ASCV_MSGIN_SDTR_PERIOD  (ASCV_MSGIN_BEG+3)
1606 #define ASCV_MSGIN_SDTR_OFFSET  (ASCV_MSGIN_BEG+4)
1607 #define ASCV_SDTR_DATA_BEG      (ASCV_MSGIN_BEG+8)
1608 #define ASCV_SDTR_DONE_BEG      (ASCV_SDTR_DATA_BEG+8)
1609 #define ASCV_MAX_DVC_QNG_BEG    (ushort)0x0020
1610 #define ASCV_BREAK_ADDR           (ushort)0x0028
1611 #define ASCV_BREAK_NOTIFY_COUNT   (ushort)0x002A
1612 #define ASCV_BREAK_CONTROL        (ushort)0x002C
1613 #define ASCV_BREAK_HIT_COUNT      (ushort)0x002E
1614
1615 #define ASCV_ASCDVC_ERR_CODE_W  (ushort)0x0030
1616 #define ASCV_MCODE_CHKSUM_W   (ushort)0x0032
1617 #define ASCV_MCODE_SIZE_W     (ushort)0x0034
1618 #define ASCV_STOP_CODE_B      (ushort)0x0036
1619 #define ASCV_DVC_ERR_CODE_B   (ushort)0x0037
1620 #define ASCV_OVERRUN_PADDR_D  (ushort)0x0038
1621 #define ASCV_OVERRUN_BSIZE_D  (ushort)0x003C
1622 #define ASCV_HALTCODE_W       (ushort)0x0040
1623 #define ASCV_CHKSUM_W         (ushort)0x0042
1624 #define ASCV_MC_DATE_W        (ushort)0x0044
1625 #define ASCV_MC_VER_W         (ushort)0x0046
1626 #define ASCV_NEXTRDY_B        (ushort)0x0048
1627 #define ASCV_DONENEXT_B       (ushort)0x0049
1628 #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1629 #define ASCV_SCSIBUSY_B       (ushort)0x004B
1630 #define ASCV_Q_DONE_IN_PROGRESS_B  (ushort)0x004C
1631 #define ASCV_CURCDB_B         (ushort)0x004D
1632 #define ASCV_RCLUN_B          (ushort)0x004E
1633 #define ASCV_BUSY_QHEAD_B     (ushort)0x004F
1634 #define ASCV_DISC1_QHEAD_B    (ushort)0x0050
1635 #define ASCV_DISC_ENABLE_B    (ushort)0x0052
1636 #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1637 #define ASCV_HOSTSCSI_ID_B    (ushort)0x0055
1638 #define ASCV_MCODE_CNTL_B     (ushort)0x0056
1639 #define ASCV_NULL_TARGET_B    (ushort)0x0057
1640 #define ASCV_FREE_Q_HEAD_W    (ushort)0x0058
1641 #define ASCV_DONE_Q_TAIL_W    (ushort)0x005A
1642 #define ASCV_FREE_Q_HEAD_B    (ushort)(ASCV_FREE_Q_HEAD_W+1)
1643 #define ASCV_DONE_Q_TAIL_B    (ushort)(ASCV_DONE_Q_TAIL_W+1)
1644 #define ASCV_HOST_FLAG_B      (ushort)0x005D
1645 #define ASCV_TOTAL_READY_Q_B  (ushort)0x0064
1646 #define ASCV_VER_SERIAL_B     (ushort)0x0065
1647 #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1648 #define ASCV_WTM_FLAG_B       (ushort)0x0068
1649 #define ASCV_RISC_FLAG_B      (ushort)0x006A
1650 #define ASCV_REQ_SG_LIST_QP   (ushort)0x006B
1651 #define ASC_HOST_FLAG_IN_ISR        0x01
1652 #define ASC_HOST_FLAG_ACK_INT       0x02
1653 #define ASC_RISC_FLAG_GEN_INT      0x01
1654 #define ASC_RISC_FLAG_REQ_SG_LIST  0x02
1655 #define IOP_CTRL         (0x0F)
1656 #define IOP_STATUS       (0x0E)
1657 #define IOP_INT_ACK      IOP_STATUS
1658 #define IOP_REG_IFC      (0x0D)
1659 #define IOP_SYN_OFFSET    (0x0B)
1660 #define IOP_EXTRA_CONTROL (0x0D)
1661 #define IOP_REG_PC        (0x0C)
1662 #define IOP_RAM_ADDR      (0x0A)
1663 #define IOP_RAM_DATA      (0x08)
1664 #define IOP_EEP_DATA      (0x06)
1665 #define IOP_EEP_CMD       (0x07)
1666 #define IOP_VERSION       (0x03)
1667 #define IOP_CONFIG_HIGH   (0x04)
1668 #define IOP_CONFIG_LOW    (0x02)
1669 #define IOP_SIG_BYTE      (0x01)
1670 #define IOP_SIG_WORD      (0x00)
1671 #define IOP_REG_DC1      (0x0E)
1672 #define IOP_REG_DC0      (0x0C)
1673 #define IOP_REG_SB       (0x0B)
1674 #define IOP_REG_DA1      (0x0A)
1675 #define IOP_REG_DA0      (0x08)
1676 #define IOP_REG_SC       (0x09)
1677 #define IOP_DMA_SPEED    (0x07)
1678 #define IOP_REG_FLAG     (0x07)
1679 #define IOP_FIFO_H       (0x06)
1680 #define IOP_FIFO_L       (0x04)
1681 #define IOP_REG_ID       (0x05)
1682 #define IOP_REG_QP       (0x03)
1683 #define IOP_REG_IH       (0x02)
1684 #define IOP_REG_IX       (0x01)
1685 #define IOP_REG_AX       (0x00)
1686 #define IFC_REG_LOCK      (0x00)
1687 #define IFC_REG_UNLOCK    (0x09)
1688 #define IFC_WR_EN_FILTER  (0x10)
1689 #define IFC_RD_NO_EEPROM  (0x10)
1690 #define IFC_SLEW_RATE     (0x20)
1691 #define IFC_ACT_NEG       (0x40)
1692 #define IFC_INP_FILTER    (0x80)
1693 #define IFC_INIT_DEFAULT  (IFC_ACT_NEG | IFC_REG_UNLOCK)
1694 #define SC_SEL   (uchar)(0x80)
1695 #define SC_BSY   (uchar)(0x40)
1696 #define SC_ACK   (uchar)(0x20)
1697 #define SC_REQ   (uchar)(0x10)
1698 #define SC_ATN   (uchar)(0x08)
1699 #define SC_IO    (uchar)(0x04)
1700 #define SC_CD    (uchar)(0x02)
1701 #define SC_MSG   (uchar)(0x01)
1702 #define SEC_SCSI_CTL         (uchar)(0x80)
1703 #define SEC_ACTIVE_NEGATE    (uchar)(0x40)
1704 #define SEC_SLEW_RATE        (uchar)(0x20)
1705 #define SEC_ENABLE_FILTER    (uchar)(0x10)
1706 #define ASC_HALT_EXTMSG_IN     (ushort)0x8000
1707 #define ASC_HALT_CHK_CONDITION (ushort)0x8100
1708 #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1709 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX  (ushort)0x8300
1710 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX   (ushort)0x8400
1711 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1712 #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1713 #define ASC_MAX_QNO        0xF8
1714 #define ASC_DATA_SEC_BEG   (ushort)0x0080
1715 #define ASC_DATA_SEC_END   (ushort)0x0080
1716 #define ASC_CODE_SEC_BEG   (ushort)0x0080
1717 #define ASC_CODE_SEC_END   (ushort)0x0080
1718 #define ASC_QADR_BEG       (0x4000)
1719 #define ASC_QADR_USED      (ushort)(ASC_MAX_QNO * 64)
1720 #define ASC_QADR_END       (ushort)0x7FFF
1721 #define ASC_QLAST_ADR      (ushort)0x7FC0
1722 #define ASC_QBLK_SIZE      0x40
1723 #define ASC_BIOS_DATA_QBEG 0xF8
1724 #define ASC_MIN_ACTIVE_QNO 0x01
1725 #define ASC_QLINK_END      0xFF
1726 #define ASC_EEPROM_WORDS   0x10
1727 #define ASC_MAX_MGS_LEN    0x10
1728 #define ASC_BIOS_ADDR_DEF  0xDC00
1729 #define ASC_BIOS_SIZE      0x3800
1730 #define ASC_BIOS_RAM_OFF   0x3800
1731 #define ASC_BIOS_RAM_SIZE  0x800
1732 #define ASC_BIOS_MIN_ADDR  0xC000
1733 #define ASC_BIOS_MAX_ADDR  0xEC00
1734 #define ASC_BIOS_BANK_SIZE 0x0400
1735 #define ASC_MCODE_START_ADDR  0x0080
1736 #define ASC_CFG0_HOST_INT_ON    0x0020
1737 #define ASC_CFG0_BIOS_ON        0x0040
1738 #define ASC_CFG0_VERA_BURST_ON  0x0080
1739 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
1740 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
1741 #define ASC_CFG1_LRAM_8BITS_ON  0x0800
1742 #define ASC_CFG_MSW_CLR_MASK    0x3080
1743 #define CSW_TEST1             (ASC_CS_TYPE)0x8000
1744 #define CSW_AUTO_CONFIG       (ASC_CS_TYPE)0x4000
1745 #define CSW_RESERVED1         (ASC_CS_TYPE)0x2000
1746 #define CSW_IRQ_WRITTEN       (ASC_CS_TYPE)0x1000
1747 #define CSW_33MHZ_SELECTED    (ASC_CS_TYPE)0x0800
1748 #define CSW_TEST2             (ASC_CS_TYPE)0x0400
1749 #define CSW_TEST3             (ASC_CS_TYPE)0x0200
1750 #define CSW_RESERVED2         (ASC_CS_TYPE)0x0100
1751 #define CSW_DMA_DONE          (ASC_CS_TYPE)0x0080
1752 #define CSW_FIFO_RDY          (ASC_CS_TYPE)0x0040
1753 #define CSW_EEP_READ_DONE     (ASC_CS_TYPE)0x0020
1754 #define CSW_HALTED            (ASC_CS_TYPE)0x0010
1755 #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1756 #define CSW_PARITY_ERR        (ASC_CS_TYPE)0x0004
1757 #define CSW_SCSI_RESET_LATCH  (ASC_CS_TYPE)0x0002
1758 #define CSW_INT_PENDING       (ASC_CS_TYPE)0x0001
1759 #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1760 #define CIW_INT_ACK      (ASC_CS_TYPE)0x0100
1761 #define CIW_TEST1        (ASC_CS_TYPE)0x0200
1762 #define CIW_TEST2        (ASC_CS_TYPE)0x0400
1763 #define CIW_SEL_33MHZ    (ASC_CS_TYPE)0x0800
1764 #define CIW_IRQ_ACT      (ASC_CS_TYPE)0x1000
1765 #define CC_CHIP_RESET   (uchar)0x80
1766 #define CC_SCSI_RESET   (uchar)0x40
1767 #define CC_HALT         (uchar)0x20
1768 #define CC_SINGLE_STEP  (uchar)0x10
1769 #define CC_DMA_ABLE     (uchar)0x08
1770 #define CC_TEST         (uchar)0x04
1771 #define CC_BANK_ONE     (uchar)0x02
1772 #define CC_DIAG         (uchar)0x01
1773 #define ASC_1000_ID0W      0x04C1
1774 #define ASC_1000_ID0W_FIX  0x00C1
1775 #define ASC_1000_ID1B      0x25
1776 #define ASC_EISA_REV_IOP_MASK  (0x0C83)
1777 #define ASC_EISA_PID_IOP_MASK  (0x0C80)
1778 #define ASC_EISA_CFG_IOP_MASK  (0x0C86)
1779 #define ASC_GET_EISA_SLOT(iop)  (PortAddr)((iop) & 0xF000)
1780 #define INS_HALTINT        (ushort)0x6281
1781 #define INS_HALT           (ushort)0x6280
1782 #define INS_SINT           (ushort)0x6200
1783 #define INS_RFLAG_WTM      (ushort)0x7380
1784 #define ASC_MC_SAVE_CODE_WSIZE  0x500
1785 #define ASC_MC_SAVE_DATA_WSIZE  0x40
1786
1787 typedef struct asc_mc_saved {
1788         ushort data[ASC_MC_SAVE_DATA_WSIZE];
1789         ushort code[ASC_MC_SAVE_CODE_WSIZE];
1790 } ASC_MC_SAVED;
1791
1792 #define AscGetQDoneInProgress(port)         AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1793 #define AscPutQDoneInProgress(port, val)    AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1794 #define AscGetVarFreeQHead(port)            AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1795 #define AscGetVarDoneQTail(port)            AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1796 #define AscPutVarFreeQHead(port, val)       AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1797 #define AscPutVarDoneQTail(port, val)       AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1798 #define AscGetRiscVarFreeQHead(port)        AscReadLramByte((port), ASCV_NEXTRDY_B)
1799 #define AscGetRiscVarDoneQTail(port)        AscReadLramByte((port), ASCV_DONENEXT_B)
1800 #define AscPutRiscVarFreeQHead(port, val)   AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1801 #define AscPutRiscVarDoneQTail(port, val)   AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1802 #define AscPutMCodeSDTRDoneAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1803 #define AscGetMCodeSDTRDoneAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1804 #define AscPutMCodeInitSDTRAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1805 #define AscGetMCodeInitSDTRAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1806 #define AscSynIndexToPeriod(index)        (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1807 #define AscGetChipSignatureByte(port)     (uchar)inp((port)+IOP_SIG_BYTE)
1808 #define AscGetChipSignatureWord(port)     (ushort)inpw((port)+IOP_SIG_WORD)
1809 #define AscGetChipVerNo(port)             (uchar)inp((port)+IOP_VERSION)
1810 #define AscGetChipCfgLsw(port)            (ushort)inpw((port)+IOP_CONFIG_LOW)
1811 #define AscGetChipCfgMsw(port)            (ushort)inpw((port)+IOP_CONFIG_HIGH)
1812 #define AscSetChipCfgLsw(port, data)      outpw((port)+IOP_CONFIG_LOW, data)
1813 #define AscSetChipCfgMsw(port, data)      outpw((port)+IOP_CONFIG_HIGH, data)
1814 #define AscGetChipEEPCmd(port)            (uchar)inp((port)+IOP_EEP_CMD)
1815 #define AscSetChipEEPCmd(port, data)      outp((port)+IOP_EEP_CMD, data)
1816 #define AscGetChipEEPData(port)           (ushort)inpw((port)+IOP_EEP_DATA)
1817 #define AscSetChipEEPData(port, data)     outpw((port)+IOP_EEP_DATA, data)
1818 #define AscGetChipLramAddr(port)          (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1819 #define AscSetChipLramAddr(port, addr)    outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1820 #define AscGetChipLramData(port)          (ushort)inpw((port)+IOP_RAM_DATA)
1821 #define AscSetChipLramData(port, data)    outpw((port)+IOP_RAM_DATA, data)
1822 #define AscGetChipIFC(port)               (uchar)inp((port)+IOP_REG_IFC)
1823 #define AscSetChipIFC(port, data)          outp((port)+IOP_REG_IFC, data)
1824 #define AscGetChipStatus(port)            (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1825 #define AscSetChipStatus(port, cs_val)    outpw((port)+IOP_STATUS, cs_val)
1826 #define AscGetChipControl(port)           (uchar)inp((port)+IOP_CTRL)
1827 #define AscSetChipControl(port, cc_val)   outp((port)+IOP_CTRL, cc_val)
1828 #define AscGetChipSyn(port)               (uchar)inp((port)+IOP_SYN_OFFSET)
1829 #define AscSetChipSyn(port, data)         outp((port)+IOP_SYN_OFFSET, data)
1830 #define AscSetPCAddr(port, data)          outpw((port)+IOP_REG_PC, data)
1831 #define AscGetPCAddr(port)                (ushort)inpw((port)+IOP_REG_PC)
1832 #define AscIsIntPending(port)             (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1833 #define AscGetChipScsiID(port)            ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1834 #define AscGetExtraControl(port)          (uchar)inp((port)+IOP_EXTRA_CONTROL)
1835 #define AscSetExtraControl(port, data)    outp((port)+IOP_EXTRA_CONTROL, data)
1836 #define AscReadChipAX(port)               (ushort)inpw((port)+IOP_REG_AX)
1837 #define AscWriteChipAX(port, data)        outpw((port)+IOP_REG_AX, data)
1838 #define AscReadChipIX(port)               (uchar)inp((port)+IOP_REG_IX)
1839 #define AscWriteChipIX(port, data)        outp((port)+IOP_REG_IX, data)
1840 #define AscReadChipIH(port)               (ushort)inpw((port)+IOP_REG_IH)
1841 #define AscWriteChipIH(port, data)        outpw((port)+IOP_REG_IH, data)
1842 #define AscReadChipQP(port)               (uchar)inp((port)+IOP_REG_QP)
1843 #define AscWriteChipQP(port, data)        outp((port)+IOP_REG_QP, data)
1844 #define AscReadChipFIFO_L(port)           (ushort)inpw((port)+IOP_REG_FIFO_L)
1845 #define AscWriteChipFIFO_L(port, data)    outpw((port)+IOP_REG_FIFO_L, data)
1846 #define AscReadChipFIFO_H(port)           (ushort)inpw((port)+IOP_REG_FIFO_H)
1847 #define AscWriteChipFIFO_H(port, data)    outpw((port)+IOP_REG_FIFO_H, data)
1848 #define AscReadChipDmaSpeed(port)         (uchar)inp((port)+IOP_DMA_SPEED)
1849 #define AscWriteChipDmaSpeed(port, data)  outp((port)+IOP_DMA_SPEED, data)
1850 #define AscReadChipDA0(port)              (ushort)inpw((port)+IOP_REG_DA0)
1851 #define AscWriteChipDA0(port)             outpw((port)+IOP_REG_DA0, data)
1852 #define AscReadChipDA1(port)              (ushort)inpw((port)+IOP_REG_DA1)
1853 #define AscWriteChipDA1(port)             outpw((port)+IOP_REG_DA1, data)
1854 #define AscReadChipDC0(port)              (ushort)inpw((port)+IOP_REG_DC0)
1855 #define AscWriteChipDC0(port)             outpw((port)+IOP_REG_DC0, data)
1856 #define AscReadChipDC1(port)              (ushort)inpw((port)+IOP_REG_DC1)
1857 #define AscWriteChipDC1(port)             outpw((port)+IOP_REG_DC1, data)
1858 #define AscReadChipDvcID(port)            (uchar)inp((port)+IOP_REG_ID)
1859 #define AscWriteChipDvcID(port, data)     outp((port)+IOP_REG_ID, data)
1860
1861 static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1862 static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1863 static void AscWaitEEPRead(void);
1864 static void AscWaitEEPWrite(void);
1865 static ushort AscReadEEPWord(PortAddr, uchar);
1866 static ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1867 static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1868 static int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1869 static int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1870 static int AscStartChip(PortAddr);
1871 static int AscStopChip(PortAddr);
1872 static void AscSetChipIH(PortAddr, ushort);
1873 static int AscIsChipHalted(PortAddr);
1874 static void AscAckInterrupt(PortAddr);
1875 static void AscDisableInterrupt(PortAddr);
1876 static void AscEnableInterrupt(PortAddr);
1877 static void AscSetBank(PortAddr, uchar);
1878 static int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1879 #ifdef CONFIG_ISA
1880 static ushort AscGetIsaDmaChannel(PortAddr);
1881 static ushort AscSetIsaDmaChannel(PortAddr, ushort);
1882 static uchar AscSetIsaDmaSpeed(PortAddr, uchar);
1883 static uchar AscGetIsaDmaSpeed(PortAddr);
1884 #endif /* CONFIG_ISA */
1885 static uchar AscReadLramByte(PortAddr, ushort);
1886 static ushort AscReadLramWord(PortAddr, ushort);
1887 #if CC_VERY_LONG_SG_LIST
1888 static ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1889 #endif /* CC_VERY_LONG_SG_LIST */
1890 static void AscWriteLramWord(PortAddr, ushort, ushort);
1891 static void AscWriteLramByte(PortAddr, ushort, uchar);
1892 static ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
1893 static void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1894 static void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1895 static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1896 static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
1897 static ushort AscInitAscDvcVar(ASC_DVC_VAR *);
1898 static ushort AscInitFromEEP(ASC_DVC_VAR *);
1899 static ushort AscInitFromAscDvcVar(ASC_DVC_VAR *);
1900 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1901 static int AscTestExternalLram(ASC_DVC_VAR *);
1902 static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1903 static uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1904 static void AscSetChipSDTR(PortAddr, uchar, uchar);
1905 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1906 static uchar AscAllocFreeQueue(PortAddr, uchar);
1907 static uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1908 static int AscHostReqRiscHalt(PortAddr);
1909 static int AscStopQueueExe(PortAddr);
1910 static int AscSendScsiQueue(ASC_DVC_VAR *,
1911                             ASC_SCSI_Q *scsiq, uchar n_q_required);
1912 static int AscPutReadyQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1913 static int AscPutReadySgListQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1914 static int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1915 static int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1916 static ushort AscInitLram(ASC_DVC_VAR *);
1917 static ushort AscInitQLinkVar(ASC_DVC_VAR *);
1918 static int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1919 static int AscIsrChipHalted(ASC_DVC_VAR *);
1920 static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1921                                    ASC_QDONE_INFO *, ASC_DCNT);
1922 static int AscIsrQDone(ASC_DVC_VAR *);
1923 static int AscCompareString(uchar *, uchar *, int);
1924 #ifdef CONFIG_ISA
1925 static ushort AscGetEisaChipCfg(PortAddr);
1926 #endif /* CONFIG_ISA */
1927 static uchar AscGetChipScsiCtrl(PortAddr);
1928 static uchar AscSetChipScsiID(PortAddr, uchar);
1929 static uchar AscGetChipVersion(PortAddr, ushort);
1930 static ushort AscGetChipBusType(PortAddr);
1931 static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
1932 static int AscFindSignature(PortAddr);
1933 static void AscToggleIRQAct(PortAddr);
1934 static uchar AscGetChipIRQ(PortAddr, ushort);
1935 static uchar AscSetChipIRQ(PortAddr, uchar, ushort);
1936 static ushort AscGetChipBiosAddress(PortAddr, ushort);
1937 static inline ulong DvcEnterCritical(void);
1938 static inline void DvcLeaveCritical(ulong);
1939 #ifdef CONFIG_PCI
1940 static uchar DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort);
1941 static void DvcWritePCIConfigByte(ASC_DVC_VAR *, ushort, uchar);
1942 #endif /* CONFIG_PCI */
1943 static ushort AscGetChipBiosAddress(PortAddr, ushort);
1944 static void DvcSleepMilliSecond(ASC_DCNT);
1945 static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
1946 static void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1947 static void DvcGetQinfo(PortAddr, ushort, uchar *, int);
1948 static ushort AscInitGetConfig(ASC_DVC_VAR *);
1949 static ushort AscInitSetConfig(ASC_DVC_VAR *);
1950 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
1951 static void AscAsyncFix(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *);
1952 static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
1953 static void AscInquiryHandling(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *);
1954 static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
1955 static int AscISR(ASC_DVC_VAR *);
1956 static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar);
1957 static int AscSgListToQueue(int);
1958 #ifdef CONFIG_ISA
1959 static void AscEnableIsaDma(uchar);
1960 #endif /* CONFIG_ISA */
1961 static ASC_DCNT AscGetMaxDmaCount(ushort);
1962 static const char *advansys_info(struct Scsi_Host *shost);
1963
1964 /*
1965  * --- Adv Library Constants and Macros
1966  */
1967
1968 #define ADV_LIB_VERSION_MAJOR  5
1969 #define ADV_LIB_VERSION_MINOR  14
1970
1971 /*
1972  * Define Adv Library required special types.
1973  */
1974
1975 /*
1976  * Portable Data Types
1977  *
1978  * Any instance where a 32-bit long or pointer type is assumed
1979  * for precision or HW defined structures, the following define
1980  * types must be used. In Linux the char, short, and int types
1981  * are all consistent at 8, 16, and 32 bits respectively. Pointers
1982  * and long types are 64 bits on Alpha and UltraSPARC.
1983  */
1984 #define ADV_PADDR __u32         /* Physical address data type. */
1985 #define ADV_VADDR __u32         /* Virtual address data type. */
1986 #define ADV_DCNT  __u32         /* Unsigned Data count type. */
1987 #define ADV_SDCNT __s32         /* Signed Data count type. */
1988
1989 /*
1990  * These macros are used to convert a virtual address to a
1991  * 32-bit value. This currently can be used on Linux Alpha
1992  * which uses 64-bit virtual address but a 32-bit bus address.
1993  * This is likely to break in the future, but doing this now
1994  * will give us time to change the HW and FW to handle 64-bit
1995  * addresses.
1996  */
1997 #define ADV_VADDR_TO_U32   virt_to_bus
1998 #define ADV_U32_TO_VADDR   bus_to_virt
1999
2000 #define AdvPortAddr  void __iomem *     /* Virtual memory address size */
2001
2002 /*
2003  * Define Adv Library required memory access macros.
2004  */
2005 #define ADV_MEM_READB(addr) readb(addr)
2006 #define ADV_MEM_READW(addr) readw(addr)
2007 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
2008 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
2009 #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
2010
2011 #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
2012
2013 /*
2014  * For wide  boards a CDB length maximum of 16 bytes
2015  * is supported.
2016  */
2017 #define ADV_MAX_CDB_LEN     16
2018
2019 /*
2020  * Define total number of simultaneous maximum element scatter-gather
2021  * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
2022  * maximum number of outstanding commands per wide host adapter. Each
2023  * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
2024  * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
2025  * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
2026  * structures or 255 scatter-gather elements.
2027  *
2028  */
2029 #define ADV_TOT_SG_BLOCK        ASC_DEF_MAX_HOST_QNG
2030
2031 /*
2032  * Define Adv Library required maximum number of scatter-gather
2033  * elements per request.
2034  */
2035 #define ADV_MAX_SG_LIST         255
2036
2037 /* Number of SG blocks needed. */
2038 #define ADV_NUM_SG_BLOCK \
2039     ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
2040
2041 /* Total contiguous memory needed for SG blocks. */
2042 #define ADV_SG_TOTAL_MEM_SIZE \
2043     (sizeof(ADV_SG_BLOCK) *  ADV_NUM_SG_BLOCK)
2044
2045 #define ADV_PAGE_SIZE PAGE_SIZE
2046
2047 #define ADV_NUM_PAGE_CROSSING \
2048     ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2049
2050 #define ADV_EEP_DVC_CFG_BEGIN           (0x00)
2051 #define ADV_EEP_DVC_CFG_END             (0x15)
2052 #define ADV_EEP_DVC_CTL_BEGIN           (0x16)  /* location of OEM name */
2053 #define ADV_EEP_MAX_WORD_ADDR           (0x1E)
2054
2055 #define ADV_EEP_DELAY_MS                100
2056
2057 #define ADV_EEPROM_BIG_ENDIAN          0x8000   /* EEPROM Bit 15 */
2058 #define ADV_EEPROM_BIOS_ENABLE         0x4000   /* EEPROM Bit 14 */
2059 /*
2060  * For the ASC3550 Bit 13 is Termination Polarity control bit.
2061  * For later ICs Bit 13 controls whether the CIS (Card Information
2062  * Service Section) is loaded from EEPROM.
2063  */
2064 #define ADV_EEPROM_TERM_POL            0x2000   /* EEPROM Bit 13 */
2065 #define ADV_EEPROM_CIS_LD              0x2000   /* EEPROM Bit 13 */
2066 /*
2067  * ASC38C1600 Bit 11
2068  *
2069  * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
2070  * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
2071  * Function 0 will specify INT B.
2072  *
2073  * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
2074  * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
2075  * Function 1 will specify INT A.
2076  */
2077 #define ADV_EEPROM_INTAB               0x0800   /* EEPROM Bit 11 */
2078
2079 typedef struct adveep_3550_config {
2080         /* Word Offset, Description */
2081
2082         ushort cfg_lsw;         /* 00 power up initialization */
2083         /*  bit 13 set - Term Polarity Control */
2084         /*  bit 14 set - BIOS Enable */
2085         /*  bit 15 set - Big Endian Mode */
2086         ushort cfg_msw;         /* 01 unused      */
2087         ushort disc_enable;     /* 02 disconnect enable */
2088         ushort wdtr_able;       /* 03 Wide DTR able */
2089         ushort sdtr_able;       /* 04 Synchronous DTR able */
2090         ushort start_motor;     /* 05 send start up motor */
2091         ushort tagqng_able;     /* 06 tag queuing able */
2092         ushort bios_scan;       /* 07 BIOS device control */
2093         ushort scam_tolerant;   /* 08 no scam */
2094
2095         uchar adapter_scsi_id;  /* 09 Host Adapter ID */
2096         uchar bios_boot_delay;  /*    power up wait */
2097
2098         uchar scsi_reset_delay; /* 10 reset delay */
2099         uchar bios_id_lun;      /*    first boot device scsi id & lun */
2100         /*    high nibble is lun */
2101         /*    low nibble is scsi id */
2102
2103         uchar termination;      /* 11 0 - automatic */
2104         /*    1 - low off / high off */
2105         /*    2 - low off / high on */
2106         /*    3 - low on  / high on */
2107         /*    There is no low on  / high off */
2108
2109         uchar reserved1;        /*    reserved byte (not used) */
2110
2111         ushort bios_ctrl;       /* 12 BIOS control bits */
2112         /*  bit 0  BIOS don't act as initiator. */
2113         /*  bit 1  BIOS > 1 GB support */
2114         /*  bit 2  BIOS > 2 Disk Support */
2115         /*  bit 3  BIOS don't support removables */
2116         /*  bit 4  BIOS support bootable CD */
2117         /*  bit 5  BIOS scan enabled */
2118         /*  bit 6  BIOS support multiple LUNs */
2119         /*  bit 7  BIOS display of message */
2120         /*  bit 8  SCAM disabled */
2121         /*  bit 9  Reset SCSI bus during init. */
2122         /*  bit 10 */
2123         /*  bit 11 No verbose initialization. */
2124         /*  bit 12 SCSI parity enabled */
2125         /*  bit 13 */
2126         /*  bit 14 */
2127         /*  bit 15 */
2128         ushort ultra_able;      /* 13 ULTRA speed able */
2129         ushort reserved2;       /* 14 reserved */
2130         uchar max_host_qng;     /* 15 maximum host queuing */
2131         uchar max_dvc_qng;      /*    maximum per device queuing */
2132         ushort dvc_cntl;        /* 16 control bit for driver */
2133         ushort bug_fix;         /* 17 control bit for bug fix */
2134         ushort serial_number_word1;     /* 18 Board serial number word 1 */
2135         ushort serial_number_word2;     /* 19 Board serial number word 2 */
2136         ushort serial_number_word3;     /* 20 Board serial number word 3 */
2137         ushort check_sum;       /* 21 EEP check sum */
2138         uchar oem_name[16];     /* 22 OEM name */
2139         ushort dvc_err_code;    /* 30 last device driver error code */
2140         ushort adv_err_code;    /* 31 last uc and Adv Lib error code */
2141         ushort adv_err_addr;    /* 32 last uc error address */
2142         ushort saved_dvc_err_code;      /* 33 saved last dev. driver error code   */
2143         ushort saved_adv_err_code;      /* 34 saved last uc and Adv Lib error code */
2144         ushort saved_adv_err_addr;      /* 35 saved last uc error address         */
2145         ushort num_of_err;      /* 36 number of error */
2146 } ADVEEP_3550_CONFIG;
2147
2148 typedef struct adveep_38C0800_config {
2149         /* Word Offset, Description */
2150
2151         ushort cfg_lsw;         /* 00 power up initialization */
2152         /*  bit 13 set - Load CIS */
2153         /*  bit 14 set - BIOS Enable */
2154         /*  bit 15 set - Big Endian Mode */
2155         ushort cfg_msw;         /* 01 unused      */
2156         ushort disc_enable;     /* 02 disconnect enable */
2157         ushort wdtr_able;       /* 03 Wide DTR able */
2158         ushort sdtr_speed1;     /* 04 SDTR Speed TID 0-3 */
2159         ushort start_motor;     /* 05 send start up motor */
2160         ushort tagqng_able;     /* 06 tag queuing able */
2161         ushort bios_scan;       /* 07 BIOS device control */
2162         ushort scam_tolerant;   /* 08 no scam */
2163
2164         uchar adapter_scsi_id;  /* 09 Host Adapter ID */
2165         uchar bios_boot_delay;  /*    power up wait */
2166
2167         uchar scsi_reset_delay; /* 10 reset delay */
2168         uchar bios_id_lun;      /*    first boot device scsi id & lun */
2169         /*    high nibble is lun */
2170         /*    low nibble is scsi id */
2171
2172         uchar termination_se;   /* 11 0 - automatic */
2173         /*    1 - low off / high off */
2174         /*    2 - low off / high on */
2175         /*    3 - low on  / high on */
2176         /*    There is no low on  / high off */
2177
2178         uchar termination_lvd;  /* 11 0 - automatic */
2179         /*    1 - low off / high off */
2180         /*    2 - low off / high on */
2181         /*    3 - low on  / high on */
2182         /*    There is no low on  / high off */
2183
2184         ushort bios_ctrl;       /* 12 BIOS control bits */
2185         /*  bit 0  BIOS don't act as initiator. */
2186         /*  bit 1  BIOS > 1 GB support */
2187         /*  bit 2  BIOS > 2 Disk Support */
2188         /*  bit 3  BIOS don't support removables */
2189         /*  bit 4  BIOS support bootable CD */
2190         /*  bit 5  BIOS scan enabled */
2191         /*  bit 6  BIOS support multiple LUNs */
2192         /*  bit 7  BIOS display of message */
2193         /*  bit 8  SCAM disabled */
2194         /*  bit 9  Reset SCSI bus during init. */
2195         /*  bit 10 */
2196         /*  bit 11 No verbose initialization. */
2197         /*  bit 12 SCSI parity enabled */
2198         /*  bit 13 */
2199         /*  bit 14 */
2200         /*  bit 15 */
2201         ushort sdtr_speed2;     /* 13 SDTR speed TID 4-7 */
2202         ushort sdtr_speed3;     /* 14 SDTR speed TID 8-11 */
2203         uchar max_host_qng;     /* 15 maximum host queueing */
2204         uchar max_dvc_qng;      /*    maximum per device queuing */
2205         ushort dvc_cntl;        /* 16 control bit for driver */
2206         ushort sdtr_speed4;     /* 17 SDTR speed 4 TID 12-15 */
2207         ushort serial_number_word1;     /* 18 Board serial number word 1 */
2208         ushort serial_number_word2;     /* 19 Board serial number word 2 */
2209         ushort serial_number_word3;     /* 20 Board serial number word 3 */
2210         ushort check_sum;       /* 21 EEP check sum */
2211         uchar oem_name[16];     /* 22 OEM name */
2212         ushort dvc_err_code;    /* 30 last device driver error code */
2213         ushort adv_err_code;    /* 31 last uc and Adv Lib error code */
2214         ushort adv_err_addr;    /* 32 last uc error address */
2215         ushort saved_dvc_err_code;      /* 33 saved last dev. driver error code   */
2216         ushort saved_adv_err_code;      /* 34 saved last uc and Adv Lib error code */
2217         ushort saved_adv_err_addr;      /* 35 saved last uc error address         */
2218         ushort reserved36;      /* 36 reserved */
2219         ushort reserved37;      /* 37 reserved */
2220         ushort reserved38;      /* 38 reserved */
2221         ushort reserved39;      /* 39 reserved */
2222         ushort reserved40;      /* 40 reserved */
2223         ushort reserved41;      /* 41 reserved */
2224         ushort reserved42;      /* 42 reserved */
2225         ushort reserved43;      /* 43 reserved */
2226         ushort reserved44;      /* 44 reserved */
2227         ushort reserved45;      /* 45 reserved */
2228         ushort reserved46;      /* 46 reserved */
2229         ushort reserved47;      /* 47 reserved */
2230         ushort reserved48;      /* 48 reserved */
2231         ushort reserved49;      /* 49 reserved */
2232         ushort reserved50;      /* 50 reserved */
2233         ushort reserved51;      /* 51 reserved */
2234         ushort reserved52;      /* 52 reserved */
2235         ushort reserved53;      /* 53 reserved */
2236         ushort reserved54;      /* 54 reserved */
2237         ushort reserved55;      /* 55 reserved */
2238         ushort cisptr_lsw;      /* 56 CIS PTR LSW */
2239         ushort cisprt_msw;      /* 57 CIS PTR MSW */
2240         ushort subsysvid;       /* 58 SubSystem Vendor ID */
2241         ushort subsysid;        /* 59 SubSystem ID */
2242         ushort reserved60;      /* 60 reserved */
2243         ushort reserved61;      /* 61 reserved */
2244         ushort reserved62;      /* 62 reserved */
2245         ushort reserved63;      /* 63 reserved */
2246 } ADVEEP_38C0800_CONFIG;
2247
2248 typedef struct adveep_38C1600_config {
2249         /* Word Offset, Description */
2250
2251         ushort cfg_lsw;         /* 00 power up initialization */
2252         /*  bit 11 set - Func. 0 INTB, Func. 1 INTA */
2253         /*       clear - Func. 0 INTA, Func. 1 INTB */
2254         /*  bit 13 set - Load CIS */
2255         /*  bit 14 set - BIOS Enable */
2256         /*  bit 15 set - Big Endian Mode */
2257         ushort cfg_msw;         /* 01 unused */
2258         ushort disc_enable;     /* 02 disconnect enable */
2259         ushort wdtr_able;       /* 03 Wide DTR able */
2260         ushort sdtr_speed1;     /* 04 SDTR Speed TID 0-3 */
2261         ushort start_motor;     /* 05 send start up motor */
2262         ushort tagqng_able;     /* 06 tag queuing able */
2263         ushort bios_scan;       /* 07 BIOS device control */
2264         ushort scam_tolerant;   /* 08 no scam */
2265
2266         uchar adapter_scsi_id;  /* 09 Host Adapter ID */
2267         uchar bios_boot_delay;  /*    power up wait */
2268
2269         uchar scsi_reset_delay; /* 10 reset delay */
2270         uchar bios_id_lun;      /*    first boot device scsi id & lun */
2271         /*    high nibble is lun */
2272         /*    low nibble is scsi id */
2273
2274         uchar termination_se;   /* 11 0 - automatic */
2275         /*    1 - low off / high off */
2276         /*    2 - low off / high on */
2277         /*    3 - low on  / high on */
2278         /*    There is no low on  / high off */
2279
2280         uchar termination_lvd;  /* 11 0 - automatic */
2281         /*    1 - low off / high off */
2282         /*    2 - low off / high on */
2283         /*    3 - low on  / high on */
2284         /*    There is no low on  / high off */
2285
2286         ushort bios_ctrl;       /* 12 BIOS control bits */
2287         /*  bit 0  BIOS don't act as initiator. */
2288         /*  bit 1  BIOS > 1 GB support */
2289         /*  bit 2  BIOS > 2 Disk Support */
2290         /*  bit 3  BIOS don't support removables */
2291         /*  bit 4  BIOS support bootable CD */
2292         /*  bit 5  BIOS scan enabled */
2293         /*  bit 6  BIOS support multiple LUNs */
2294         /*  bit 7  BIOS display of message */
2295         /*  bit 8  SCAM disabled */
2296         /*  bit 9  Reset SCSI bus during init. */
2297         /*  bit 10 Basic Integrity Checking disabled */
2298         /*  bit 11 No verbose initialization. */
2299         /*  bit 12 SCSI parity enabled */
2300         /*  bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
2301         /*  bit 14 */
2302         /*  bit 15 */
2303         ushort sdtr_speed2;     /* 13 SDTR speed TID 4-7 */
2304         ushort sdtr_speed3;     /* 14 SDTR speed TID 8-11 */
2305         uchar max_host_qng;     /* 15 maximum host queueing */
2306         uchar max_dvc_qng;      /*    maximum per device queuing */
2307         ushort dvc_cntl;        /* 16 control bit for driver */
2308         ushort sdtr_speed4;     /* 17 SDTR speed 4 TID 12-15 */
2309         ushort serial_number_word1;     /* 18 Board serial number word 1 */
2310         ushort serial_number_word2;     /* 19 Board serial number word 2 */
2311         ushort serial_number_word3;     /* 20 Board serial number word 3 */
2312         ushort check_sum;       /* 21 EEP check sum */
2313         uchar oem_name[16];     /* 22 OEM name */
2314         ushort dvc_err_code;    /* 30 last device driver error code */
2315         ushort adv_err_code;    /* 31 last uc and Adv Lib error code */
2316         ushort adv_err_addr;    /* 32 last uc error address */
2317         ushort saved_dvc_err_code;      /* 33 saved last dev. driver error code   */
2318         ushort saved_adv_err_code;      /* 34 saved last uc and Adv Lib error code */
2319         ushort saved_adv_err_addr;      /* 35 saved last uc error address         */
2320         ushort reserved36;      /* 36 reserved */
2321         ushort reserved37;      /* 37 reserved */
2322         ushort reserved38;      /* 38 reserved */
2323         ushort reserved39;      /* 39 reserved */
2324         ushort reserved40;      /* 40 reserved */
2325         ushort reserved41;      /* 41 reserved */
2326         ushort reserved42;      /* 42 reserved */
2327         ushort reserved43;      /* 43 reserved */
2328         ushort reserved44;      /* 44 reserved */
2329         ushort reserved45;      /* 45 reserved */
2330         ushort reserved46;      /* 46 reserved */
2331         ushort reserved47;      /* 47 reserved */
2332         ushort reserved48;      /* 48 reserved */
2333         ushort reserved49;      /* 49 reserved */
2334         ushort reserved50;      /* 50 reserved */
2335         ushort reserved51;      /* 51 reserved */
2336         ushort reserved52;      /* 52 reserved */
2337         ushort reserved53;      /* 53 reserved */
2338         ushort reserved54;      /* 54 reserved */
2339         ushort reserved55;      /* 55 reserved */
2340         ushort cisptr_lsw;      /* 56 CIS PTR LSW */
2341         ushort cisprt_msw;      /* 57 CIS PTR MSW */
2342         ushort subsysvid;       /* 58 SubSystem Vendor ID */
2343         ushort subsysid;        /* 59 SubSystem ID */
2344         ushort reserved60;      /* 60 reserved */
2345         ushort reserved61;      /* 61 reserved */
2346         ushort reserved62;      /* 62 reserved */
2347         ushort reserved63;      /* 63 reserved */
2348 } ADVEEP_38C1600_CONFIG;
2349
2350 /*
2351  * EEPROM Commands
2352  */
2353 #define ASC_EEP_CMD_DONE             0x0200
2354 #define ASC_EEP_CMD_DONE_ERR         0x0001
2355
2356 /* cfg_word */
2357 #define EEP_CFG_WORD_BIG_ENDIAN      0x8000
2358
2359 /* bios_ctrl */
2360 #define BIOS_CTRL_BIOS               0x0001
2361 #define BIOS_CTRL_EXTENDED_XLAT      0x0002
2362 #define BIOS_CTRL_GT_2_DISK          0x0004
2363 #define BIOS_CTRL_BIOS_REMOVABLE     0x0008
2364 #define BIOS_CTRL_BOOTABLE_CD        0x0010
2365 #define BIOS_CTRL_MULTIPLE_LUN       0x0040
2366 #define BIOS_CTRL_DISPLAY_MSG        0x0080
2367 #define BIOS_CTRL_NO_SCAM            0x0100
2368 #define BIOS_CTRL_RESET_SCSI_BUS     0x0200
2369 #define BIOS_CTRL_INIT_VERBOSE       0x0800
2370 #define BIOS_CTRL_SCSI_PARITY        0x1000
2371 #define BIOS_CTRL_AIPP_DIS           0x2000
2372
2373 #define ADV_3550_MEMSIZE   0x2000       /* 8 KB Internal Memory */
2374 #define ADV_3550_IOLEN     0x40 /* I/O Port Range in bytes */
2375
2376 #define ADV_38C0800_MEMSIZE  0x4000     /* 16 KB Internal Memory */
2377 #define ADV_38C0800_IOLEN    0x100      /* I/O Port Range in bytes */
2378
2379 /*
2380  * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
2381  * a special 16K Adv Library and Microcode version. After the issue is
2382  * resolved, should restore 32K support.
2383  *
2384  * #define ADV_38C1600_MEMSIZE  0x8000L   * 32 KB Internal Memory *
2385  */
2386 #define ADV_38C1600_MEMSIZE  0x4000     /* 16 KB Internal Memory */
2387 #define ADV_38C1600_IOLEN    0x100      /* I/O Port Range 256 bytes */
2388 #define ADV_38C1600_MEMLEN   0x1000     /* Memory Range 4KB bytes */
2389
2390 /*
2391  * Byte I/O register address from base of 'iop_base'.
2392  */
2393 #define IOPB_INTR_STATUS_REG    0x00
2394 #define IOPB_CHIP_ID_1          0x01
2395 #define IOPB_INTR_ENABLES       0x02
2396 #define IOPB_CHIP_TYPE_REV      0x03
2397 #define IOPB_RES_ADDR_4         0x04
2398 #define IOPB_RES_ADDR_5         0x05
2399 #define IOPB_RAM_DATA           0x06
2400 #define IOPB_RES_ADDR_7         0x07
2401 #define IOPB_FLAG_REG           0x08
2402 #define IOPB_RES_ADDR_9         0x09
2403 #define IOPB_RISC_CSR           0x0A
2404 #define IOPB_RES_ADDR_B         0x0B
2405 #define IOPB_RES_ADDR_C         0x0C
2406 #define IOPB_RES_ADDR_D         0x0D
2407 #define IOPB_SOFT_OVER_WR       0x0E
2408 #define IOPB_RES_ADDR_F         0x0F
2409 #define IOPB_MEM_CFG            0x10
2410 #define IOPB_RES_ADDR_11        0x11
2411 #define IOPB_GPIO_DATA          0x12
2412 #define IOPB_RES_ADDR_13        0x13
2413 #define IOPB_FLASH_PAGE         0x14
2414 #define IOPB_RES_ADDR_15        0x15
2415 #define IOPB_GPIO_CNTL          0x16
2416 #define IOPB_RES_ADDR_17        0x17
2417 #define IOPB_FLASH_DATA         0x18
2418 #define IOPB_RES_ADDR_19        0x19
2419 #define IOPB_RES_ADDR_1A        0x1A
2420 #define IOPB_RES_ADDR_1B        0x1B
2421 #define IOPB_RES_ADDR_1C        0x1C
2422 #define IOPB_RES_ADDR_1D        0x1D
2423 #define IOPB_RES_ADDR_1E        0x1E
2424 #define IOPB_RES_ADDR_1F        0x1F
2425 #define IOPB_DMA_CFG0           0x20
2426 #define IOPB_DMA_CFG1           0x21
2427 #define IOPB_TICKLE             0x22
2428 #define IOPB_DMA_REG_WR         0x23
2429 #define IOPB_SDMA_STATUS        0x24
2430 #define IOPB_SCSI_BYTE_CNT      0x25
2431 #define IOPB_HOST_BYTE_CNT      0x26
2432 #define IOPB_BYTE_LEFT_TO_XFER  0x27
2433 #define IOPB_BYTE_TO_XFER_0     0x28
2434 #define IOPB_BYTE_TO_XFER_1     0x29
2435 #define IOPB_BYTE_TO_XFER_2     0x2A
2436 #define IOPB_BYTE_TO_XFER_3     0x2B
2437 #define IOPB_ACC_GRP            0x2C
2438 #define IOPB_RES_ADDR_2D        0x2D
2439 #define IOPB_DEV_ID             0x2E
2440 #define IOPB_RES_ADDR_2F        0x2F
2441 #define IOPB_SCSI_DATA          0x30
2442 #define IOPB_RES_ADDR_31        0x31
2443 #define IOPB_RES_ADDR_32        0x32
2444 #define IOPB_SCSI_DATA_HSHK     0x33
2445 #define IOPB_SCSI_CTRL          0x34
2446 #define IOPB_RES_ADDR_35        0x35
2447 #define IOPB_RES_ADDR_36        0x36
2448 #define IOPB_RES_ADDR_37        0x37
2449 #define IOPB_RAM_BIST           0x38
2450 #define IOPB_PLL_TEST           0x39
2451 #define IOPB_PCI_INT_CFG        0x3A
2452 #define IOPB_RES_ADDR_3B        0x3B
2453 #define IOPB_RFIFO_CNT          0x3C
2454 #define IOPB_RES_ADDR_3D        0x3D
2455 #define IOPB_RES_ADDR_3E        0x3E
2456 #define IOPB_RES_ADDR_3F        0x3F
2457
2458 /*
2459  * Word I/O register address from base of 'iop_base'.
2460  */
2461 #define IOPW_CHIP_ID_0          0x00    /* CID0  */
2462 #define IOPW_CTRL_REG           0x02    /* CC    */
2463 #define IOPW_RAM_ADDR           0x04    /* LA    */
2464 #define IOPW_RAM_DATA           0x06    /* LD    */
2465 #define IOPW_RES_ADDR_08        0x08
2466 #define IOPW_RISC_CSR           0x0A    /* CSR   */
2467 #define IOPW_SCSI_CFG0          0x0C    /* CFG0  */
2468 #define IOPW_SCSI_CFG1          0x0E    /* CFG1  */
2469 #define IOPW_RES_ADDR_10        0x10
2470 #define IOPW_SEL_MASK           0x12    /* SM    */
2471 #define IOPW_RES_ADDR_14        0x14
2472 #define IOPW_FLASH_ADDR         0x16    /* FA    */
2473 #define IOPW_RES_ADDR_18        0x18
2474 #define IOPW_EE_CMD             0x1A    /* EC    */
2475 #define IOPW_EE_DATA            0x1C    /* ED    */
2476 #define IOPW_SFIFO_CNT          0x1E    /* SFC   */
2477 #define IOPW_RES_ADDR_20        0x20
2478 #define IOPW_Q_BASE             0x22    /* QB    */
2479 #define IOPW_QP                 0x24    /* QP    */
2480 #define IOPW_IX                 0x26    /* IX    */
2481 #define IOPW_SP                 0x28    /* SP    */
2482 #define IOPW_PC                 0x2A    /* PC    */
2483 #define IOPW_RES_ADDR_2C        0x2C
2484 #define IOPW_RES_ADDR_2E        0x2E
2485 #define IOPW_SCSI_DATA          0x30    /* SD    */
2486 #define IOPW_SCSI_DATA_HSHK     0x32    /* SDH   */
2487 #define IOPW_SCSI_CTRL          0x34    /* SC    */
2488 #define IOPW_HSHK_CFG           0x36    /* HCFG  */
2489 #define IOPW_SXFR_STATUS        0x36    /* SXS   */
2490 #define IOPW_SXFR_CNTL          0x38    /* SXL   */
2491 #define IOPW_SXFR_CNTH          0x3A    /* SXH   */
2492 #define IOPW_RES_ADDR_3C        0x3C
2493 #define IOPW_RFIFO_DATA         0x3E    /* RFD   */
2494
2495 /*
2496  * Doubleword I/O register address from base of 'iop_base'.
2497  */
2498 #define IOPDW_RES_ADDR_0         0x00
2499 #define IOPDW_RAM_DATA           0x04
2500 #define IOPDW_RES_ADDR_8         0x08
2501 #define IOPDW_RES_ADDR_C         0x0C
2502 #define IOPDW_RES_ADDR_10        0x10
2503 #define IOPDW_COMMA              0x14
2504 #define IOPDW_COMMB              0x18
2505 #define IOPDW_RES_ADDR_1C        0x1C
2506 #define IOPDW_SDMA_ADDR0         0x20
2507 #define IOPDW_SDMA_ADDR1         0x24
2508 #define IOPDW_SDMA_COUNT         0x28
2509 #define IOPDW_SDMA_ERROR         0x2C
2510 #define IOPDW_RDMA_ADDR0         0x30
2511 #define IOPDW_RDMA_ADDR1         0x34
2512 #define IOPDW_RDMA_COUNT         0x38
2513 #define IOPDW_RDMA_ERROR         0x3C
2514
2515 #define ADV_CHIP_ID_BYTE         0x25
2516 #define ADV_CHIP_ID_WORD         0x04C1
2517
2518 #define ADV_SC_SCSI_BUS_RESET    0x2000
2519
2520 #define ADV_INTR_ENABLE_HOST_INTR                   0x01
2521 #define ADV_INTR_ENABLE_SEL_INTR                    0x02
2522 #define ADV_INTR_ENABLE_DPR_INTR                    0x04
2523 #define ADV_INTR_ENABLE_RTA_INTR                    0x08
2524 #define ADV_INTR_ENABLE_RMA_INTR                    0x10
2525 #define ADV_INTR_ENABLE_RST_INTR                    0x20
2526 #define ADV_INTR_ENABLE_DPE_INTR                    0x40
2527 #define ADV_INTR_ENABLE_GLOBAL_INTR                 0x80
2528
2529 #define ADV_INTR_STATUS_INTRA            0x01
2530 #define ADV_INTR_STATUS_INTRB            0x02
2531 #define ADV_INTR_STATUS_INTRC            0x04
2532
2533 #define ADV_RISC_CSR_STOP           (0x0000)
2534 #define ADV_RISC_TEST_COND          (0x2000)
2535 #define ADV_RISC_CSR_RUN            (0x4000)
2536 #define ADV_RISC_CSR_SINGLE_STEP    (0x8000)
2537
2538 #define ADV_CTRL_REG_HOST_INTR      0x0100
2539 #define ADV_CTRL_REG_SEL_INTR       0x0200
2540 #define ADV_CTRL_REG_DPR_INTR       0x0400
2541 #define ADV_CTRL_REG_RTA_INTR       0x0800
2542 #define ADV_CTRL_REG_RMA_INTR       0x1000
2543 #define ADV_CTRL_REG_RES_BIT14      0x2000
2544 #define ADV_CTRL_REG_DPE_INTR       0x4000
2545 #define ADV_CTRL_REG_POWER_DONE     0x8000
2546 #define ADV_CTRL_REG_ANY_INTR       0xFF00
2547
2548 #define ADV_CTRL_REG_CMD_RESET             0x00C6
2549 #define ADV_CTRL_REG_CMD_WR_IO_REG         0x00C5
2550 #define ADV_CTRL_REG_CMD_RD_IO_REG         0x00C4
2551 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE  0x00C3
2552 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE  0x00C2
2553
2554 #define ADV_TICKLE_NOP                      0x00
2555 #define ADV_TICKLE_A                        0x01
2556 #define ADV_TICKLE_B                        0x02
2557 #define ADV_TICKLE_C                        0x03
2558
2559 #define ADV_SCSI_CTRL_RSTOUT        0x2000
2560
2561 #define AdvIsIntPending(port) \
2562     (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2563
2564 /*
2565  * SCSI_CFG0 Register bit definitions
2566  */
2567 #define TIMER_MODEAB    0xC000  /* Watchdog, Second, and Select. Timer Ctrl. */
2568 #define PARITY_EN       0x2000  /* Enable SCSI Parity Error detection */
2569 #define EVEN_PARITY     0x1000  /* Select Even Parity */
2570 #define WD_LONG         0x0800  /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2571 #define QUEUE_128       0x0400  /* Queue Size, 1: 128 byte, 0: 64 byte */
2572 #define PRIM_MODE       0x0100  /* Primitive SCSI mode */
2573 #define SCAM_EN         0x0080  /* Enable SCAM selection */
2574 #define SEL_TMO_LONG    0x0040  /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2575 #define CFRM_ID         0x0020  /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2576 #define OUR_ID_EN       0x0010  /* Enable OUR_ID bits */
2577 #define OUR_ID          0x000F  /* SCSI ID */
2578
2579 /*
2580  * SCSI_CFG1 Register bit definitions
2581  */
2582 #define BIG_ENDIAN      0x8000  /* Enable Big Endian Mode MIO:15, EEP:15 */
2583 #define TERM_POL        0x2000  /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2584 #define SLEW_RATE       0x1000  /* SCSI output buffer slew rate */
2585 #define FILTER_SEL      0x0C00  /* Filter Period Selection */
2586 #define  FLTR_DISABLE    0x0000 /* Input Filtering Disabled */
2587 #define  FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
2588 #define  FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
2589 #define ACTIVE_DBL      0x0200  /* Disable Active Negation */
2590 #define DIFF_MODE       0x0100  /* SCSI differential Mode (Read-Only) */
2591 #define DIFF_SENSE      0x0080  /* 1: No SE cables, 0: SE cable (Read-Only) */
2592 #define TERM_CTL_SEL    0x0040  /* Enable TERM_CTL_H and TERM_CTL_L */
2593 #define TERM_CTL        0x0030  /* External SCSI Termination Bits */
2594 #define  TERM_CTL_H      0x0020 /* Enable External SCSI Upper Termination */
2595 #define  TERM_CTL_L      0x0010 /* Enable External SCSI Lower Termination */
2596 #define CABLE_DETECT    0x000F  /* External SCSI Cable Connection Status */
2597
2598 /*
2599  * Addendum for ASC-38C0800 Chip
2600  *
2601  * The ASC-38C1600 Chip uses the same definitions except that the
2602  * bus mode override bits [12:10] have been moved to byte register
2603  * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
2604  * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
2605  * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
2606  * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
2607  * and [1:0]. Bits [14], [7:6], [3:2] are unused.
2608  */
2609 #define DIS_TERM_DRV    0x4000  /* 1: Read c_det[3:0], 0: cannot read */
2610 #define HVD_LVD_SE      0x1C00  /* Device Detect Bits */
2611 #define  HVD             0x1000 /* HVD Device Detect */
2612 #define  LVD             0x0800 /* LVD Device Detect */
2613 #define  SE              0x0400 /* SE Device Detect */
2614 #define TERM_LVD        0x00C0  /* LVD Termination Bits */
2615 #define  TERM_LVD_HI     0x0080 /* Enable LVD Upper Termination */
2616 #define  TERM_LVD_LO     0x0040 /* Enable LVD Lower Termination */
2617 #define TERM_SE         0x0030  /* SE Termination Bits */
2618 #define  TERM_SE_HI      0x0020 /* Enable SE Upper Termination */
2619 #define  TERM_SE_LO      0x0010 /* Enable SE Lower Termination */
2620 #define C_DET_LVD       0x000C  /* LVD Cable Detect Bits */
2621 #define  C_DET3          0x0008 /* Cable Detect for LVD External Wide */
2622 #define  C_DET2          0x0004 /* Cable Detect for LVD Internal Wide */
2623 #define C_DET_SE        0x0003  /* SE Cable Detect Bits */
2624 #define  C_DET1          0x0002 /* Cable Detect for SE Internal Wide */
2625 #define  C_DET0          0x0001 /* Cable Detect for SE Internal Narrow */
2626
2627 #define CABLE_ILLEGAL_A 0x7
2628     /* x 0 0 0  | on  on | Illegal (all 3 connectors are used) */
2629
2630 #define CABLE_ILLEGAL_B 0xB
2631     /* 0 x 0 0  | on  on | Illegal (all 3 connectors are used) */
2632
2633 /*
2634  * MEM_CFG Register bit definitions
2635  */
2636 #define BIOS_EN         0x40    /* BIOS Enable MIO:14,EEP:14 */
2637 #define FAST_EE_CLK     0x20    /* Diagnostic Bit */
2638 #define RAM_SZ          0x1C    /* Specify size of RAM to RISC */
2639 #define  RAM_SZ_2KB      0x00   /* 2 KB */
2640 #define  RAM_SZ_4KB      0x04   /* 4 KB */
2641 #define  RAM_SZ_8KB      0x08   /* 8 KB */
2642 #define  RAM_SZ_16KB     0x0C   /* 16 KB */
2643 #define  RAM_SZ_32KB     0x10   /* 32 KB */
2644 #define  RAM_SZ_64KB     0x14   /* 64 KB */
2645
2646 /*
2647  * DMA_CFG0 Register bit definitions
2648  *
2649  * This register is only accessible to the host.
2650  */
2651 #define BC_THRESH_ENB   0x80    /* PCI DMA Start Conditions */
2652 #define FIFO_THRESH     0x70    /* PCI DMA FIFO Threshold */
2653 #define  FIFO_THRESH_16B  0x00  /* 16 bytes */
2654 #define  FIFO_THRESH_32B  0x20  /* 32 bytes */
2655 #define  FIFO_THRESH_48B  0x30  /* 48 bytes */
2656 #define  FIFO_THRESH_64B  0x40  /* 64 bytes */
2657 #define  FIFO_THRESH_80B  0x50  /* 80 bytes (default) */
2658 #define  FIFO_THRESH_96B  0x60  /* 96 bytes */
2659 #define  FIFO_THRESH_112B 0x70  /* 112 bytes */
2660 #define START_CTL       0x0C    /* DMA start conditions */
2661 #define  START_CTL_TH    0x00   /* Wait threshold level (default) */
2662 #define  START_CTL_ID    0x04   /* Wait SDMA/SBUS idle */
2663 #define  START_CTL_THID  0x08   /* Wait threshold and SDMA/SBUS idle */
2664 #define  START_CTL_EMFU  0x0C   /* Wait SDMA FIFO empty/full */
2665 #define READ_CMD        0x03    /* Memory Read Method */
2666 #define  READ_CMD_MR     0x00   /* Memory Read */
2667 #define  READ_CMD_MRL    0x02   /* Memory Read Long */
2668 #define  READ_CMD_MRM    0x03   /* Memory Read Multiple (default) */
2669
2670 /*
2671  * ASC-38C0800 RAM BIST Register bit definitions
2672  */
2673 #define RAM_TEST_MODE         0x80
2674 #define PRE_TEST_MODE         0x40
2675 #define NORMAL_MODE           0x00
2676 #define RAM_TEST_DONE         0x10
2677 #define RAM_TEST_STATUS       0x0F
2678 #define  RAM_TEST_HOST_ERROR   0x08
2679 #define  RAM_TEST_INTRAM_ERROR 0x04
2680 #define  RAM_TEST_RISC_ERROR   0x02
2681 #define  RAM_TEST_SCSI_ERROR   0x01
2682 #define  RAM_TEST_SUCCESS      0x00
2683 #define PRE_TEST_VALUE        0x05
2684 #define NORMAL_VALUE          0x00
2685
2686 /*
2687  * ASC38C1600 Definitions
2688  *
2689  * IOPB_PCI_INT_CFG Bit Field Definitions
2690  */
2691
2692 #define INTAB_LD        0x80    /* Value loaded from EEPROM Bit 11. */
2693
2694 /*
2695  * Bit 1 can be set to change the interrupt for the Function to operate in
2696  * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
2697  * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
2698  * mode, otherwise the operating mode is undefined.
2699  */
2700 #define TOTEMPOLE       0x02
2701
2702 /*
2703  * Bit 0 can be used to change the Int Pin for the Function. The value is
2704  * 0 by default for both Functions with Function 0 using INT A and Function
2705  * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
2706  * INT A is used.
2707  *
2708  * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
2709  * value specified in the PCI Configuration Space.
2710  */
2711 #define INTAB           0x01
2712
2713 /* a_advlib.h */
2714
2715 /*
2716  * Adv Library Status Definitions
2717  */
2718 #define ADV_TRUE        1
2719 #define ADV_FALSE       0
2720 #define ADV_NOERROR     1
2721 #define ADV_SUCCESS     1
2722 #define ADV_BUSY        0
2723 #define ADV_ERROR       (-1)
2724
2725 /*
2726  * ADV_DVC_VAR 'warn_code' values
2727  */
2728 #define ASC_WARN_BUSRESET_ERROR         0x0001  /* SCSI Bus Reset error */
2729 #define ASC_WARN_EEPROM_CHKSUM          0x0002  /* EEP check sum error */
2730 #define ASC_WARN_EEPROM_TERMINATION     0x0004  /* EEP termination bad field */
2731 #define ASC_WARN_SET_PCI_CONFIG_SPACE   0x0080  /* PCI config space set error */
2732 #define ASC_WARN_ERROR                  0xFFFF  /* ADV_ERROR return */
2733
2734 #define ADV_MAX_TID                     15      /* max. target identifier */
2735 #define ADV_MAX_LUN                     7       /* max. logical unit number */
2736
2737 /*
2738  * Error code values are set in ADV_DVC_VAR 'err_code'.
2739  */
2740 #define ASC_IERR_WRITE_EEPROM       0x0001      /* write EEPROM error */
2741 #define ASC_IERR_MCODE_CHKSUM       0x0002      /* micro code check sum error */
2742 #define ASC_IERR_NO_CARRIER         0x0004      /* No more carrier memory. */
2743 #define ASC_IERR_START_STOP_CHIP    0x0008      /* start/stop chip failed */
2744 #define ASC_IERR_CHIP_VERSION       0x0040      /* wrong chip version */
2745 #define ASC_IERR_SET_SCSI_ID        0x0080      /* set SCSI ID failed */
2746 #define ASC_IERR_HVD_DEVICE         0x0100      /* HVD attached to LVD connector. */
2747 #define ASC_IERR_BAD_SIGNATURE      0x0200      /* signature not found */
2748 #define ASC_IERR_ILLEGAL_CONNECTION 0x0400      /* Illegal cable connection */
2749 #define ASC_IERR_SINGLE_END_DEVICE  0x0800      /* Single-end used w/differential */
2750 #define ASC_IERR_REVERSED_CABLE     0x1000      /* Narrow flat cable reversed */
2751 #define ASC_IERR_BIST_PRE_TEST      0x2000      /* BIST pre-test error */
2752 #define ASC_IERR_BIST_RAM_TEST      0x4000      /* BIST RAM test error */
2753 #define ASC_IERR_BAD_CHIPTYPE       0x8000      /* Invalid 'chip_type' setting. */
2754
2755 /*
2756  * Fixed locations of microcode operating variables.
2757  */
2758 #define ASC_MC_CODE_BEGIN_ADDR          0x0028  /* microcode start address */
2759 #define ASC_MC_CODE_END_ADDR            0x002A  /* microcode end address */
2760 #define ASC_MC_CODE_CHK_SUM             0x002C  /* microcode code checksum */
2761 #define ASC_MC_VERSION_DATE             0x0038  /* microcode version */
2762 #define ASC_MC_VERSION_NUM              0x003A  /* microcode number */
2763 #define ASC_MC_BIOSMEM                  0x0040  /* BIOS RISC Memory Start */
2764 #define ASC_MC_BIOSLEN                  0x0050  /* BIOS RISC Memory Length */
2765 #define ASC_MC_BIOS_SIGNATURE           0x0058  /* BIOS Signature 0x55AA */
2766 #define ASC_MC_BIOS_VERSION             0x005A  /* BIOS Version (2 bytes) */
2767 #define ASC_MC_SDTR_SPEED1              0x0090  /* SDTR Speed for TID 0-3 */
2768 #define ASC_MC_SDTR_SPEED2              0x0092  /* SDTR Speed for TID 4-7 */
2769 #define ASC_MC_SDTR_SPEED3              0x0094  /* SDTR Speed for TID 8-11 */
2770 #define ASC_MC_SDTR_SPEED4              0x0096  /* SDTR Speed for TID 12-15 */
2771 #define ASC_MC_CHIP_TYPE                0x009A
2772 #define ASC_MC_INTRB_CODE               0x009B
2773 #define ASC_MC_WDTR_ABLE                0x009C
2774 #define ASC_MC_SDTR_ABLE                0x009E
2775 #define ASC_MC_TAGQNG_ABLE              0x00A0
2776 #define ASC_MC_DISC_ENABLE              0x00A2
2777 #define ASC_MC_IDLE_CMD_STATUS          0x00A4
2778 #define ASC_MC_IDLE_CMD                 0x00A6
2779 #define ASC_MC_IDLE_CMD_PARAMETER       0x00A8
2780 #define ASC_MC_DEFAULT_SCSI_CFG0        0x00AC
2781 #define ASC_MC_DEFAULT_SCSI_CFG1        0x00AE
2782 #define ASC_MC_DEFAULT_MEM_CFG          0x00B0
2783 #define ASC_MC_DEFAULT_SEL_MASK         0x00B2
2784 #define ASC_MC_SDTR_DONE                0x00B6
2785 #define ASC_MC_NUMBER_OF_QUEUED_CMD     0x00C0
2786 #define ASC_MC_NUMBER_OF_MAX_CMD        0x00D0
2787 #define ASC_MC_DEVICE_HSHK_CFG_TABLE    0x0100
2788 #define ASC_MC_CONTROL_FLAG             0x0122  /* Microcode control flag. */
2789 #define ASC_MC_WDTR_DONE                0x0124
2790 #define ASC_MC_CAM_MODE_MASK            0x015E  /* CAM mode TID bitmask. */
2791 #define ASC_MC_ICQ                      0x0160
2792 #define ASC_MC_IRQ                      0x0164
2793 #define ASC_MC_PPR_ABLE                 0x017A
2794
2795 /*
2796  * BIOS LRAM variable absolute offsets.
2797  */
2798 #define BIOS_CODESEG    0x54
2799 #define BIOS_CODELEN    0x56
2800 #define BIOS_SIGNATURE  0x58
2801 #define BIOS_VERSION    0x5A
2802
2803 /*
2804  * Microcode Control Flags
2805  *
2806  * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2807  * and handled by the microcode.
2808  */
2809 #define CONTROL_FLAG_IGNORE_PERR        0x0001  /* Ignore DMA Parity Errors */
2810 #define CONTROL_FLAG_ENABLE_AIPP        0x0002  /* Enabled AIPP checking. */
2811
2812 /*
2813  * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2814  */
2815 #define HSHK_CFG_WIDE_XFR       0x8000
2816 #define HSHK_CFG_RATE           0x0F00
2817 #define HSHK_CFG_OFFSET         0x001F
2818
2819 #define ASC_DEF_MAX_HOST_QNG    0xFD    /* Max. number of host commands (253) */
2820 #define ASC_DEF_MIN_HOST_QNG    0x10    /* Min. number of host commands (16) */
2821 #define ASC_DEF_MAX_DVC_QNG     0x3F    /* Max. number commands per device (63) */
2822 #define ASC_DEF_MIN_DVC_QNG     0x04    /* Min. number commands per device (4) */
2823
2824 #define ASC_QC_DATA_CHECK  0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2825 #define ASC_QC_DATA_OUT    0x02 /* Data out DMA transfer. */
2826 #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2827 #define ASC_QC_NO_OVERRUN  0x08 /* Don't report overrun. */
2828 #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2829
2830 #define ASC_QSC_NO_DISC     0x01        /* Don't allow disconnect for request. */
2831 #define ASC_QSC_NO_TAGMSG   0x02        /* Don't allow tag queuing for request. */
2832 #define ASC_QSC_NO_SYNC     0x04        /* Don't use Synch. transfer on request. */
2833 #define ASC_QSC_NO_WIDE     0x08        /* Don't use Wide transfer on request. */
2834 #define ASC_QSC_REDO_DTR    0x10        /* Renegotiate WDTR/SDTR before request. */
2835 /*
2836  * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
2837  * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
2838  */
2839 #define ASC_QSC_HEAD_TAG    0x40        /* Use Head Tag Message (0x21). */
2840 #define ASC_QSC_ORDERED_TAG 0x80        /* Use Ordered Tag Message (0x22). */
2841
2842 /*
2843  * All fields here are accessed by the board microcode and need to be
2844  * little-endian.
2845  */
2846 typedef struct adv_carr_t {
2847         ADV_VADDR carr_va;      /* Carrier Virtual Address */
2848         ADV_PADDR carr_pa;      /* Carrier Physical Address */
2849         ADV_VADDR areq_vpa;     /* ASC_SCSI_REQ_Q Virtual or Physical Address */
2850         /*
2851          * next_vpa [31:4]            Carrier Virtual or Physical Next Pointer
2852          *
2853          * next_vpa [3:1]             Reserved Bits
2854          * next_vpa [0]               Done Flag set in Response Queue.
2855          */
2856         ADV_VADDR next_vpa;
2857 } ADV_CARR_T;
2858
2859 /*
2860  * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2861  */
2862 #define ASC_NEXT_VPA_MASK       0xFFFFFFF0
2863
2864 #define ASC_RQ_DONE             0x00000001
2865 #define ASC_RQ_GOOD             0x00000002
2866 #define ASC_CQ_STOPPER          0x00000000
2867
2868 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2869
2870 #define ADV_CARRIER_NUM_PAGE_CROSSING \
2871     (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2872         (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2873
2874 #define ADV_CARRIER_BUFSIZE \
2875     ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2876
2877 /*
2878  * ASC_SCSI_REQ_Q 'a_flag' definitions
2879  *
2880  * The Adv Library should limit use to the lower nibble (4 bits) of
2881  * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2882  */
2883 #define ADV_POLL_REQUEST                0x01    /* poll for request completion */
2884 #define ADV_SCSIQ_DONE                  0x02    /* request done */
2885 #define ADV_DONT_RETRY                  0x08    /* don't do retry */
2886
2887 #define ADV_CHIP_ASC3550          0x01  /* Ultra-Wide IC */
2888 #define ADV_CHIP_ASC38C0800       0x02  /* Ultra2-Wide/LVD IC */
2889 #define ADV_CHIP_ASC38C1600       0x03  /* Ultra3-Wide/LVD2 IC */
2890
2891 /*
2892  * Adapter temporary configuration structure
2893  *
2894  * This structure can be discarded after initialization. Don't add
2895  * fields here needed after initialization.
2896  *
2897  * Field naming convention:
2898  *
2899  *  *_enable indicates the field enables or disables a feature. The
2900  *  value of the field is never reset.
2901  */
2902 typedef struct adv_dvc_cfg {
2903         ushort disc_enable;     /* enable disconnection */
2904         uchar chip_version;     /* chip version */
2905         uchar termination;      /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2906         ushort lib_version;     /* Adv Library version number */
2907         ushort control_flag;    /* Microcode Control Flag */
2908         ushort mcode_date;      /* Microcode date */
2909         ushort mcode_version;   /* Microcode version */
2910         ushort pci_slot_info;   /* high byte device/function number */
2911         /* bits 7-3 device num., bits 2-0 function num. */
2912         /* low byte bus num. */
2913         ushort serial1;         /* EEPROM serial number word 1 */
2914         ushort serial2;         /* EEPROM serial number word 2 */
2915         ushort serial3;         /* EEPROM serial number word 3 */
2916         struct device *dev;     /* pointer to the pci dev structure for this board */
2917 } ADV_DVC_CFG;
2918
2919 struct adv_dvc_var;
2920 struct adv_scsi_req_q;
2921
2922 typedef void (*ADV_ISR_CALLBACK)
2923  (struct adv_dvc_var *, struct adv_scsi_req_q *);
2924
2925 typedef void (*ADV_ASYNC_CALLBACK)
2926  (struct adv_dvc_var *, uchar);
2927
2928 /*
2929  * Adapter operation variable structure.
2930  *
2931  * One structure is required per host adapter.
2932  *
2933  * Field naming convention:
2934  *
2935  *  *_able indicates both whether a feature should be enabled or disabled
2936  *  and whether a device isi capable of the feature. At initialization
2937  *  this field may be set, but later if a device is found to be incapable
2938  *  of the feature, the field is cleared.
2939  */
2940 typedef struct adv_dvc_var {
2941         AdvPortAddr iop_base;   /* I/O port address */
2942         ushort err_code;        /* fatal error code */
2943         ushort bios_ctrl;       /* BIOS control word, EEPROM word 12 */
2944         ADV_ISR_CALLBACK isr_callback;
2945         ADV_ASYNC_CALLBACK async_callback;
2946         ushort wdtr_able;       /* try WDTR for a device */
2947         ushort sdtr_able;       /* try SDTR for a device */
2948         ushort ultra_able;      /* try SDTR Ultra speed for a device */
2949         ushort sdtr_speed1;     /* EEPROM SDTR Speed for TID 0-3   */
2950         ushort sdtr_speed2;     /* EEPROM SDTR Speed for TID 4-7   */
2951         ushort sdtr_speed3;     /* EEPROM SDTR Speed for TID 8-11  */
2952         ushort sdtr_speed4;     /* EEPROM SDTR Speed for TID 12-15 */
2953         ushort tagqng_able;     /* try tagged queuing with a device */
2954         ushort ppr_able;        /* PPR message capable per TID bitmask. */
2955         uchar max_dvc_qng;      /* maximum number of tagged commands per device */
2956         ushort start_motor;     /* start motor command allowed */
2957         uchar scsi_reset_wait;  /* delay in seconds after scsi bus reset */
2958         uchar chip_no;          /* should be assigned by caller */
2959         uchar max_host_qng;     /* maximum number of Q'ed command allowed */
2960         uchar irq_no;           /* IRQ number */
2961         ushort no_scam;         /* scam_tolerant of EEPROM */
2962         struct asc_board *drv_ptr;      /* driver pointer to private structure */
2963         uchar chip_scsi_id;     /* chip SCSI target ID */
2964         uchar chip_type;
2965         uchar bist_err_code;
2966         ADV_CARR_T *carrier_buf;
2967         ADV_CARR_T *carr_freelist;      /* Carrier free list. */
2968         ADV_CARR_T *icq_sp;     /* Initiator command queue stopper pointer. */
2969         ADV_CARR_T *irq_sp;     /* Initiator response queue stopper pointer. */
2970         ushort carr_pending_cnt;        /* Count of pending carriers. */
2971         /*
2972          * Note: The following fields will not be used after initialization. The
2973          * driver may discard the buffer after initialization is done.
2974          */
2975         ADV_DVC_CFG *cfg;       /* temporary configuration structure  */
2976 } ADV_DVC_VAR;
2977
2978 #define NO_OF_SG_PER_BLOCK              15
2979
2980 typedef struct asc_sg_block {
2981         uchar reserved1;
2982         uchar reserved2;
2983         uchar reserved3;
2984         uchar sg_cnt;           /* Valid entries in block. */
2985         ADV_PADDR sg_ptr;       /* Pointer to next sg block. */
2986         struct {
2987                 ADV_PADDR sg_addr;      /* SG element address. */
2988                 ADV_DCNT sg_count;      /* SG element count. */
2989         } sg_list[NO_OF_SG_PER_BLOCK];
2990 } ADV_SG_BLOCK;
2991
2992 /*
2993  * ADV_SCSI_REQ_Q - microcode request structure
2994  *
2995  * All fields in this structure up to byte 60 are used by the microcode.
2996  * The microcode makes assumptions about the size and ordering of fields
2997  * in this structure. Do not change the structure definition here without
2998  * coordinating the change with the microcode.
2999  *
3000  * All fields accessed by microcode must be maintained in little_endian
3001  * order.
3002  */
3003 typedef struct adv_scsi_req_q {
3004         uchar cntl;             /* Ucode flags and state (ASC_MC_QC_*). */
3005         uchar target_cmd;
3006         uchar target_id;        /* Device target identifier. */
3007         uchar target_lun;       /* Device target logical unit number. */
3008         ADV_PADDR data_addr;    /* Data buffer physical address. */
3009         ADV_DCNT data_cnt;      /* Data count. Ucode sets to residual. */
3010         ADV_PADDR sense_addr;
3011         ADV_PADDR carr_pa;
3012         uchar mflag;
3013         uchar sense_len;
3014         uchar cdb_len;          /* SCSI CDB length. Must <= 16 bytes. */
3015         uchar scsi_cntl;
3016         uchar done_status;      /* Completion status. */
3017         uchar scsi_status;      /* SCSI status byte. */
3018         uchar host_status;      /* Ucode host status. */
3019         uchar sg_working_ix;
3020         uchar cdb[12];          /* SCSI CDB bytes 0-11. */
3021         ADV_PADDR sg_real_addr; /* SG list physical address. */
3022         ADV_PADDR scsiq_rptr;
3023         uchar cdb16[4];         /* SCSI CDB bytes 12-15. */
3024         ADV_VADDR scsiq_ptr;
3025         ADV_VADDR carr_va;
3026         /*
3027          * End of microcode structure - 60 bytes. The rest of the structure
3028          * is used by the Adv Library and ignored by the microcode.
3029          */
3030         ADV_VADDR srb_ptr;
3031         ADV_SG_BLOCK *sg_list_ptr;      /* SG list virtual address. */
3032         char *vdata_addr;       /* Data buffer virtual address. */
3033         uchar a_flag;
3034         uchar pad[2];           /* Pad out to a word boundary. */
3035 } ADV_SCSI_REQ_Q;
3036
3037 /*
3038  * Microcode idle loop commands
3039  */
3040 #define IDLE_CMD_COMPLETED           0
3041 #define IDLE_CMD_STOP_CHIP           0x0001
3042 #define IDLE_CMD_STOP_CHIP_SEND_INT  0x0002
3043 #define IDLE_CMD_SEND_INT            0x0004
3044 #define IDLE_CMD_ABORT               0x0008
3045 #define IDLE_CMD_DEVICE_RESET        0x0010
3046 #define IDLE_CMD_SCSI_RESET_START    0x0020     /* Assert SCSI Bus Reset */
3047 #define IDLE_CMD_SCSI_RESET_END      0x0040     /* Deassert SCSI Bus Reset */
3048 #define IDLE_CMD_SCSIREQ             0x0080
3049
3050 #define IDLE_CMD_STATUS_SUCCESS      0x0001
3051 #define IDLE_CMD_STATUS_FAILURE      0x0002
3052
3053 /*
3054  * AdvSendIdleCmd() flag definitions.
3055  */
3056 #define ADV_NOWAIT     0x01
3057
3058 /*
3059  * Wait loop time out values.
3060  */
3061 #define SCSI_WAIT_10_SEC             10UL       /* 10 seconds */
3062 #define SCSI_WAIT_100_MSEC           100UL      /* 100 milliseconds */
3063 #define SCSI_US_PER_MSEC             1000       /* microseconds per millisecond */
3064 #define SCSI_MS_PER_SEC              1000UL     /* milliseconds per second */
3065 #define SCSI_MAX_RETRY               10 /* retry count */
3066
3067 #define ADV_ASYNC_RDMA_FAILURE          0x01    /* Fatal RDMA failure. */
3068 #define ADV_ASYNC_SCSI_BUS_RESET_DET    0x02    /* Detected SCSI Bus Reset. */
3069 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03    /* Carrier Ready failure. */
3070 #define ADV_RDMA_IN_CARR_AND_Q_INVALID  0x04    /* RDMAed-in data invalid. */
3071
3072 #define ADV_HOST_SCSI_BUS_RESET      0x80       /* Host Initiated SCSI Bus Reset. */
3073
3074 /*
3075  * Device drivers must define the following functions.
3076  */
3077 static inline ulong DvcEnterCritical(void);
3078 static inline void DvcLeaveCritical(ulong);
3079 static void DvcSleepMilliSecond(ADV_DCNT);
3080 static uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
3081 static void DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
3082 static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
3083                                uchar *, ASC_SDCNT *, int);
3084 static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
3085
3086 /*
3087  * Adv Library functions available to drivers.
3088  */
3089 static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3090 static int AdvISR(ADV_DVC_VAR *);
3091 static int AdvInitGetConfig(ADV_DVC_VAR *);
3092 static int AdvInitAsc3550Driver(ADV_DVC_VAR *);
3093 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
3094 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
3095 static int AdvResetChipAndSB(ADV_DVC_VAR *);
3096 static int AdvResetSB(ADV_DVC_VAR *asc_dvc);
3097
3098 /*
3099  * Internal Adv Library functions.
3100  */
3101 static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
3102 static void AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3103 static int AdvInitFrom3550EEP(ADV_DVC_VAR *);
3104 static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
3105 static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
3106 static ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3107 static void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3108 static ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3109 static void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3110 static ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3111 static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3112 static void AdvWaitEEPCmd(AdvPortAddr);
3113 static ushort AdvReadEEPWord(AdvPortAddr, int);
3114
3115 /*
3116  * PCI Bus Definitions
3117  */
3118 #define AscPCICmdRegBits_BusMastering     0x0007
3119 #define AscPCICmdRegBits_ParErrRespCtrl   0x0040
3120
3121 /* Read byte from a register. */
3122 #define AdvReadByteRegister(iop_base, reg_off) \
3123      (ADV_MEM_READB((iop_base) + (reg_off)))
3124
3125 /* Write byte to a register. */
3126 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
3127      (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3128
3129 /* Read word (2 bytes) from a register. */
3130 #define AdvReadWordRegister(iop_base, reg_off) \
3131      (ADV_MEM_READW((iop_base) + (reg_off)))
3132
3133 /* Write word (2 bytes) to a register. */
3134 #define AdvWriteWordRegister(iop_base, reg_off, word) \
3135      (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
3136
3137 /* Write dword (4 bytes) to a register. */
3138 #define AdvWriteDWordRegister(iop_base, reg_off, dword) \
3139      (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
3140
3141 /* Read byte from LRAM. */
3142 #define AdvReadByteLram(iop_base, addr, byte) \
3143 do { \
3144     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3145     (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3146 } while (0)
3147
3148 /* Write byte to LRAM. */
3149 #define AdvWriteByteLram(iop_base, addr, byte) \
3150     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3151      ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3152
3153 /* Read word (2 bytes) from LRAM. */
3154 #define AdvReadWordLram(iop_base, addr, word) \
3155 do { \
3156     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3157     (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3158 } while (0)
3159
3160 /* Write word (2 bytes) to LRAM. */
3161 #define AdvWriteWordLram(iop_base, addr, word) \
3162     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3163      ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3164
3165 /* Write little-endian double word (4 bytes) to LRAM */
3166 /* Because of unspecified C language ordering don't use auto-increment. */
3167 #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
3168     ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3169       ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3170                      cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3171      (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3172       ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3173                      cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3174
3175 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
3176 #define AdvReadWordAutoIncLram(iop_base) \
3177      (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3178
3179 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
3180 #define AdvWriteWordAutoIncLram(iop_base, word) \
3181      (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3182
3183 /*
3184  * Define macro to check for Condor signature.
3185  *
3186  * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3187  * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3188  */
3189 #define AdvFindSignature(iop_base) \
3190     (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3191     ADV_CHIP_ID_BYTE) && \
3192      (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3193     ADV_CHIP_ID_WORD)) ?  ADV_TRUE : ADV_FALSE)
3194
3195 /*
3196  * Define macro to Return the version number of the chip at 'iop_base'.
3197  *
3198  * The second parameter 'bus_type' is currently unused.
3199  */
3200 #define AdvGetChipVersion(iop_base, bus_type) \
3201     AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3202
3203 /*
3204  * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3205  * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3206  *
3207  * If the request has not yet been sent to the device it will simply be
3208  * aborted from RISC memory. If the request is disconnected it will be
3209  * aborted on reselection by sending an Abort Message to the target ID.
3210  *
3211  * Return value:
3212  *      ADV_TRUE(1) - Queue was successfully aborted.
3213  *      ADV_FALSE(0) - Queue was not found on the active queue list.
3214  */
3215 #define AdvAbortQueue(asc_dvc, scsiq) \
3216         AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3217                        (ADV_DCNT) (scsiq))
3218
3219 /*
3220  * Send a Bus Device Reset Message to the specified target ID.
3221  *
3222  * All outstanding commands will be purged if sending the
3223  * Bus Device Reset Message is successful.
3224  *
3225  * Return Value:
3226  *      ADV_TRUE(1) - All requests on the target are purged.
3227  *      ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3228  *                     are not purged.
3229  */
3230 #define AdvResetDevice(asc_dvc, target_id) \
3231         AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3232                     (ADV_DCNT) (target_id))
3233
3234 /*
3235  * SCSI Wide Type definition.
3236  */
3237 #define ADV_SCSI_BIT_ID_TYPE   ushort
3238
3239 /*
3240  * AdvInitScsiTarget() 'cntl_flag' options.
3241  */
3242 #define ADV_SCAN_LUN           0x01
3243 #define ADV_CAPINFO_NOLUN      0x02
3244
3245 /*
3246  * Convert target id to target id bit mask.
3247  */
3248 #define ADV_TID_TO_TIDMASK(tid)   (0x01 << ((tid) & ADV_MAX_TID))
3249
3250 /*
3251  * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3252  */
3253
3254 #define QD_NO_STATUS         0x00       /* Request not completed yet. */
3255 #define QD_NO_ERROR          0x01
3256 #define QD_ABORTED_BY_HOST   0x02
3257 #define QD_WITH_ERROR        0x04
3258
3259 #define QHSTA_NO_ERROR              0x00
3260 #define QHSTA_M_SEL_TIMEOUT         0x11
3261 #define QHSTA_M_DATA_OVER_RUN       0x12
3262 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3263 #define QHSTA_M_QUEUE_ABORTED       0x15
3264 #define QHSTA_M_SXFR_SDMA_ERR       0x16        /* SXFR_STATUS SCSI DMA Error */
3265 #define QHSTA_M_SXFR_SXFR_PERR      0x17        /* SXFR_STATUS SCSI Bus Parity Error */
3266 #define QHSTA_M_RDMA_PERR           0x18        /* RISC PCI DMA parity error */
3267 #define QHSTA_M_SXFR_OFF_UFLW       0x19        /* SXFR_STATUS Offset Underflow */
3268 #define QHSTA_M_SXFR_OFF_OFLW       0x20        /* SXFR_STATUS Offset Overflow */
3269 #define QHSTA_M_SXFR_WD_TMO         0x21        /* SXFR_STATUS Watchdog Timeout */
3270 #define QHSTA_M_SXFR_DESELECTED     0x22        /* SXFR_STATUS Deselected */
3271 /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
3272 #define QHSTA_M_SXFR_XFR_OFLW       0x12        /* SXFR_STATUS Transfer Overflow */
3273 #define QHSTA_M_SXFR_XFR_PH_ERR     0x24        /* SXFR_STATUS Transfer Phase Error */
3274 #define QHSTA_M_SXFR_UNKNOWN_ERROR  0x25        /* SXFR_STATUS Unknown Error */
3275 #define QHSTA_M_SCSI_BUS_RESET      0x30        /* Request aborted from SBR */
3276 #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31       /* Request aborted from unsol. SBR */
3277 #define QHSTA_M_BUS_DEVICE_RESET    0x32        /* Request aborted from BDR */
3278 #define QHSTA_M_DIRECTION_ERR       0x35        /* Data Phase mismatch */
3279 #define QHSTA_M_DIRECTION_ERR_HUNG  0x36        /* Data Phase mismatch and bus hang */
3280 #define QHSTA_M_WTM_TIMEOUT         0x41
3281 #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
3282 #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
3283 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
3284 #define QHSTA_M_INVALID_DEVICE      0x45        /* Bad target ID */
3285 #define QHSTA_M_FROZEN_TIDQ         0x46        /* TID Queue frozen. */
3286 #define QHSTA_M_SGBACKUP_ERROR      0x47        /* Scatter-Gather backup error */
3287
3288 /*
3289  * Default EEPROM Configuration structure defined in a_init.c.
3290  */
3291 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
3292 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
3293 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
3294
3295 /*
3296  * DvcGetPhyAddr() flag arguments
3297  */
3298 #define ADV_IS_SCSIQ_FLAG       0x01    /* 'addr' is ASC_SCSI_REQ_Q pointer */
3299 #define ADV_ASCGETSGLIST_VADDR  0x02    /* 'addr' is AscGetSGList() virtual addr */
3300 #define ADV_IS_SENSE_FLAG       0x04    /* 'addr' is sense virtual pointer */
3301 #define ADV_IS_DATA_FLAG        0x08    /* 'addr' is data virtual pointer */
3302 #define ADV_IS_SGLIST_FLAG      0x10    /* 'addr' is sglist virtual pointer */
3303 #define ADV_IS_CARRIER_FLAG     0x20    /* 'addr' is ADV_CARR_T pointer */
3304
3305 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
3306 #define ADV_8BALIGN(addr)      (((ulong) (addr) + 0x7) & ~0x7)
3307 #define ADV_16BALIGN(addr)     (((ulong) (addr) + 0xF) & ~0xF)
3308 #define ADV_32BALIGN(addr)     (((ulong) (addr) + 0x1F) & ~0x1F)
3309
3310 /*
3311  * Total contiguous memory needed for driver SG blocks.
3312  *
3313  * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3314  * number of scatter-gather elements the driver supports in a
3315  * single request.
3316  */
3317
3318 #define ADV_SG_LIST_MAX_BYTE_SIZE \
3319          (sizeof(ADV_SG_BLOCK) * \
3320           ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3321
3322 /*
3323  * Inquiry data structure and bitfield macros
3324  *
3325  * Using bitfields to access the subchar data isn't portable across
3326  * endianness, so instead mask and shift. Only quantities of more
3327  * than 1 bit are shifted, since the others are just tested for true
3328  * or false.
3329  */
3330
3331 #define ADV_INQ_DVC_TYPE(inq)       ((inq)->periph & 0x1f)
3332 #define ADV_INQ_QUALIFIER(inq)      (((inq)->periph & 0xe0) >> 5)
3333 #define ADV_INQ_DVC_TYPE_MOD(inq)   ((inq)->devtype & 0x7f)
3334 #define ADV_INQ_REMOVABLE(inq)      ((inq)->devtype & 0x80)
3335 #define ADV_INQ_ANSI_VER(inq)       ((inq)->ver & 0x07)
3336 #define ADV_INQ_ECMA_VER(inq)       (((inq)->ver & 0x38) >> 3)
3337 #define ADV_INQ_ISO_VER(inq)        (((inq)->ver & 0xc0) >> 6)
3338 #define ADV_INQ_RESPONSE_FMT(inq)   ((inq)->byte3 & 0x0f)
3339 #define ADV_INQ_TERM_IO(inq)        ((inq)->byte3 & 0x40)
3340 #define ADV_INQ_ASYNC_NOTIF(inq)    ((inq)->byte3 & 0x80)
3341 #define ADV_INQ_SOFT_RESET(inq)     ((inq)->flags & 0x01)
3342 #define ADV_INQ_CMD_QUEUE(inq)      ((inq)->flags & 0x02)
3343 #define ADV_INQ_LINK_CMD(inq)       ((inq)->flags & 0x08)
3344 #define ADV_INQ_SYNC(inq)           ((inq)->flags & 0x10)
3345 #define ADV_INQ_WIDE16(inq)         ((inq)->flags & 0x20)
3346 #define ADV_INQ_WIDE32(inq)         ((inq)->flags & 0x40)
3347 #define ADV_INQ_REL_ADDR(inq)       ((inq)->flags & 0x80)
3348 #define ADV_INQ_INFO_UNIT(inq)      ((inq)->info & 0x01)
3349 #define ADV_INQ_QUICK_ARB(inq)      ((inq)->info & 0x02)
3350 #define ADV_INQ_CLOCKING(inq)       (((inq)->info & 0x0c) >> 2)
3351
3352 typedef struct {
3353         uchar periph;           /* peripheral device type [0:4] */
3354         /* peripheral qualifier [5:7] */
3355         uchar devtype;          /* device type modifier (for SCSI I) [0:6] */
3356         /* RMB - removable medium bit [7] */
3357         uchar ver;              /* ANSI approved version [0:2] */
3358         /* ECMA version [3:5] */
3359         /* ISO version [6:7] */
3360         uchar byte3;            /* response data format [0:3] */
3361         /* 0 SCSI 1 */
3362         /* 1 CCS */
3363         /* 2 SCSI-2 */
3364         /* 3-F reserved */
3365         /* reserved [4:5] */
3366         /* terminate I/O process bit (see 5.6.22) [6] */
3367         /* asynch. event notification (processor) [7] */
3368         uchar add_len;          /* additional length */
3369         uchar res1;             /* reserved */
3370         uchar res2;             /* reserved */
3371         uchar flags;            /* soft reset implemented [0] */
3372         /* command queuing [1] */
3373         /* reserved [2] */
3374         /* linked command for this logical unit [3] */
3375         /* synchronous data transfer [4] */
3376         /* wide bus 16 bit data transfer [5] */
3377         /* wide bus 32 bit data transfer [6] */
3378         /* relative addressing mode [7] */
3379         uchar vendor_id[8];     /* vendor identification */
3380         uchar product_id[16];   /* product identification */
3381         uchar product_rev_level[4];     /* product revision level */
3382         uchar vendor_specific[20];      /* vendor specific */
3383         uchar info;             /* information unit supported [0] */
3384         /* quick arbitrate supported [1] */
3385         /* clocking field [2:3] */
3386         /* reserved [4:7] */
3387         uchar res3;             /* reserved */
3388 } ADV_SCSI_INQUIRY;             /* 58 bytes */
3389
3390 /*
3391  * --- Driver Constants and Macros
3392  */
3393
3394 /* Reference Scsi_Host hostdata */
3395 #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3396
3397 /* asc_board_t flags */
3398 #define ASC_HOST_IN_RESET       0x01
3399 #define ASC_IS_WIDE_BOARD       0x04    /* AdvanSys Wide Board */
3400 #define ASC_SELECT_QUEUE_DEPTHS 0x08
3401
3402 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3403 #define ASC_WIDE_BOARD(boardp)   ((boardp)->flags & ASC_IS_WIDE_BOARD)
3404
3405 #define NO_ISA_DMA              0xff    /* No ISA DMA Channel Used */
3406
3407 #define ASC_INFO_SIZE           128     /* advansys_info() line size */
3408
3409 #ifdef CONFIG_PROC_FS
3410 /* /proc/scsi/advansys/[0...] related definitions */
3411 #define ASC_PRTBUF_SIZE         2048
3412 #define ASC_PRTLINE_SIZE        160
3413
3414 #define ASC_PRT_NEXT() \
3415     if (cp) { \
3416         totlen += len; \
3417         leftlen -= len; \
3418         if (leftlen == 0) { \
3419             return totlen; \
3420         } \
3421         cp += len; \
3422     }
3423 #endif /* CONFIG_PROC_FS */
3424
3425 /* Asc Library return codes */
3426 #define ASC_TRUE        1
3427 #define ASC_FALSE       0
3428 #define ASC_NOERROR     1
3429 #define ASC_BUSY        0
3430 #define ASC_ERROR       (-1)
3431
3432 /* struct scsi_cmnd function return codes */
3433 #define STATUS_BYTE(byte)   (byte)
3434 #define MSG_BYTE(byte)      ((byte) << 8)
3435 #define HOST_BYTE(byte)     ((byte) << 16)
3436 #define DRIVER_BYTE(byte)   ((byte) << 24)
3437
3438 /*
3439  * The following definitions and macros are OS independent interfaces to
3440  * the queue functions:
3441  *  REQ - SCSI request structure
3442  *  REQP - pointer to SCSI request structure
3443  *  REQPTID(reqp) - reqp's target id
3444  *  REQPNEXT(reqp) - reqp's next pointer
3445  *  REQPNEXTP(reqp) - pointer to reqp's next pointer
3446  *  REQPTIME(reqp) - reqp's time stamp value
3447  *  REQTIMESTAMP() - system time stamp value
3448  */
3449 typedef struct scsi_cmnd REQ, *REQP;
3450 #define REQPNEXT(reqp)       ((REQP) ((reqp)->host_scribble))
3451 #define REQPNEXTP(reqp)      ((REQP *) &((reqp)->host_scribble))
3452 #define REQPTID(reqp)        ((reqp)->device->id)
3453 #define REQPTIME(reqp)       ((reqp)->SCp.this_residual)
3454 #define REQTIMESTAMP()       (jiffies)
3455
3456 #define REQTIMESTAT(function, ascq, reqp, tid) \
3457 { \
3458     /*
3459      * If the request time stamp is less than the system time stamp, then \
3460      * maybe the system time stamp wrapped. Set the request time to zero.\
3461      */ \
3462     if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3463         REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3464     } else { \
3465         /* Indicate an error occurred with the assertion. */ \
3466         ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3467         REQPTIME(reqp) = 0; \
3468     } \
3469     /* Handle first minimum time case without external initialization. */ \
3470     if (((ascq)->q_tot_cnt[tid] == 1) ||  \
3471         (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3472             (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3473             ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3474                 (function), (tid), (ascq)->q_min_tim[tid]); \
3475         } \
3476     if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3477         (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3478         ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3479             (function), tid, (ascq)->q_max_tim[tid]); \
3480     } \
3481     (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3482     /* Reset the time stamp field. */ \
3483     REQPTIME(reqp) = 0; \
3484 }
3485
3486 /* asc_enqueue() flags */
3487 #define ASC_FRONT       1
3488 #define ASC_BACK        2
3489
3490 /* asc_dequeue_list() argument */
3491 #define ASC_TID_ALL        (-1)
3492
3493 /* Return non-zero, if the queue is empty. */
3494 #define ASC_QUEUE_EMPTY(ascq)    ((ascq)->q_tidmask == 0)
3495
3496 #ifndef ADVANSYS_STATS
3497 #define ASC_STATS(shost, counter)
3498 #define ASC_STATS_ADD(shost, counter, count)
3499 #else /* ADVANSYS_STATS */
3500 #define ASC_STATS(shost, counter) \
3501     (ASC_BOARDP(shost)->asc_stats.counter++)
3502
3503 #define ASC_STATS_ADD(shost, counter, count) \
3504     (ASC_BOARDP(shost)->asc_stats.counter += (count))
3505 #endif /* ADVANSYS_STATS */
3506
3507 #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3508
3509 /* If the result wraps when calculating tenths, return 0. */
3510 #define ASC_TENTHS(num, den) \
3511     (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3512     0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3513
3514 /*
3515  * Display a message to the console.
3516  */
3517 #define ASC_PRINT(s) \
3518     { \
3519         printk("advansys: "); \
3520         printk(s); \
3521     }
3522
3523 #define ASC_PRINT1(s, a1) \
3524     { \
3525         printk("advansys: "); \
3526         printk((s), (a1)); \
3527     }
3528
3529 #define ASC_PRINT2(s, a1, a2) \
3530     { \
3531         printk("advansys: "); \
3532         printk((s), (a1), (a2)); \
3533     }
3534
3535 #define ASC_PRINT3(s, a1, a2, a3) \
3536     { \
3537         printk("advansys: "); \
3538         printk((s), (a1), (a2), (a3)); \
3539     }
3540
3541 #define ASC_PRINT4(s, a1, a2, a3, a4) \
3542     { \
3543         printk("advansys: "); \
3544         printk((s), (a1), (a2), (a3), (a4)); \
3545     }
3546
3547 #ifndef ADVANSYS_DEBUG
3548
3549 #define ASC_DBG(lvl, s)
3550 #define ASC_DBG1(lvl, s, a1)
3551 #define ASC_DBG2(lvl, s, a1, a2)
3552 #define ASC_DBG3(lvl, s, a1, a2, a3)
3553 #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3554 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3555 #define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3556 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3557 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3558 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3559 #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3560 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
3561 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
3562 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
3563 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3564
3565 #else /* ADVANSYS_DEBUG */
3566
3567 /*
3568  * Debugging Message Levels:
3569  * 0: Errors Only
3570  * 1: High-Level Tracing
3571  * 2-N: Verbose Tracing
3572  */
3573
3574 #define ASC_DBG(lvl, s) \
3575     { \
3576         if (asc_dbglvl >= (lvl)) { \
3577             printk(s); \
3578         } \
3579     }
3580
3581 #define ASC_DBG1(lvl, s, a1) \
3582     { \
3583         if (asc_dbglvl >= (lvl)) { \
3584             printk((s), (a1)); \
3585         } \
3586     }
3587
3588 #define ASC_DBG2(lvl, s, a1, a2) \
3589     { \
3590         if (asc_dbglvl >= (lvl)) { \
3591             printk((s), (a1), (a2)); \
3592         } \
3593     }
3594
3595 #define ASC_DBG3(lvl, s, a1, a2, a3) \
3596     { \
3597         if (asc_dbglvl >= (lvl)) { \
3598             printk((s), (a1), (a2), (a3)); \
3599         } \
3600     }
3601
3602 #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3603     { \
3604         if (asc_dbglvl >= (lvl)) { \
3605             printk((s), (a1), (a2), (a3), (a4)); \
3606         } \
3607     }
3608
3609 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3610     { \
3611         if (asc_dbglvl >= (lvl)) { \
3612             asc_prt_scsi_host(s); \
3613         } \
3614     }
3615
3616 #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3617     { \
3618         if (asc_dbglvl >= (lvl)) { \
3619             asc_prt_scsi_cmnd(s); \
3620         } \
3621     }
3622
3623 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3624     { \
3625         if (asc_dbglvl >= (lvl)) { \
3626             asc_prt_asc_scsi_q(scsiqp); \
3627         } \
3628     }
3629
3630 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3631     { \
3632         if (asc_dbglvl >= (lvl)) { \
3633             asc_prt_asc_qdone_info(qdone); \
3634         } \
3635     }
3636
3637 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3638     { \
3639         if (asc_dbglvl >= (lvl)) { \
3640             asc_prt_adv_scsi_req_q(scsiqp); \
3641         } \
3642     }
3643
3644 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3645     { \
3646         if (asc_dbglvl >= (lvl)) { \
3647             asc_prt_hex((name), (start), (length)); \
3648         } \
3649     }
3650
3651 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3652         ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3653
3654 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3655         ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3656
3657 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3658         ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3659 #endif /* ADVANSYS_DEBUG */
3660
3661 #ifndef ADVANSYS_ASSERT
3662 #define ASC_ASSERT(a)
3663 #else /* ADVANSYS_ASSERT */
3664
3665 #define ASC_ASSERT(a) \
3666     { \
3667         if (!(a)) { \
3668             printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3669                 __FILE__, __LINE__); \
3670         } \
3671     }
3672
3673 #endif /* ADVANSYS_ASSERT */
3674
3675 /*
3676  * --- Driver Structures
3677  */
3678
3679 #ifdef ADVANSYS_STATS
3680
3681 /* Per board statistics structure */
3682 struct asc_stats {
3683         /* Driver Entrypoint Statistics */
3684         ADV_DCNT queuecommand;  /* # calls to advansys_queuecommand() */
3685         ADV_DCNT reset;         /* # calls to advansys_eh_bus_reset() */
3686         ADV_DCNT biosparam;     /* # calls to advansys_biosparam() */
3687         ADV_DCNT interrupt;     /* # advansys_interrupt() calls */
3688         ADV_DCNT callback;      /* # calls to asc/adv_isr_callback() */
3689         ADV_DCNT done;          /* # calls to request's scsi_done function */
3690         ADV_DCNT build_error;   /* # asc/adv_build_req() ASC_ERROR returns. */
3691         ADV_DCNT adv_build_noreq;       /* # adv_build_req() adv_req_t alloc. fail. */
3692         ADV_DCNT adv_build_nosg;        /* # adv_build_req() adv_sgblk_t alloc. fail. */
3693         /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3694         ADV_DCNT exe_noerror;   /* # ASC_NOERROR returns. */
3695         ADV_DCNT exe_busy;      /* # ASC_BUSY returns. */
3696         ADV_DCNT exe_error;     /* # ASC_ERROR returns. */
3697         ADV_DCNT exe_unknown;   /* # unknown returns. */
3698         /* Data Transfer Statistics */
3699         ADV_DCNT cont_cnt;      /* # non-scatter-gather I/O requests received */
3700         ADV_DCNT cont_xfer;     /* # contiguous transfer 512-bytes */
3701         ADV_DCNT sg_cnt;        /* # scatter-gather I/O requests received */
3702         ADV_DCNT sg_elem;       /* # scatter-gather elements */
3703         ADV_DCNT sg_xfer;       /* # scatter-gather transfer 512-bytes */
3704 };
3705 #endif /* ADVANSYS_STATS */
3706
3707 /*
3708  * Request queuing structure
3709  */
3710 typedef struct asc_queue {
3711         ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */
3712         REQP q_first[ADV_MAX_TID + 1];  /* first queued request */
3713         REQP q_last[ADV_MAX_TID + 1];   /* last queued request */
3714 #ifdef ADVANSYS_STATS
3715         short q_cur_cnt[ADV_MAX_TID + 1];       /* current queue count */
3716         short q_max_cnt[ADV_MAX_TID + 1];       /* maximum queue count */
3717         ADV_DCNT q_tot_cnt[ADV_MAX_TID + 1];    /* total enqueue count */
3718         ADV_DCNT q_tot_tim[ADV_MAX_TID + 1];    /* total time queued */
3719         ushort q_max_tim[ADV_MAX_TID + 1];      /* maximum time queued */
3720         ushort q_min_tim[ADV_MAX_TID + 1];      /* minimum time queued */
3721 #endif                          /* ADVANSYS_STATS */
3722 } asc_queue_t;
3723
3724 /*
3725  * Adv Library Request Structures
3726  *
3727  * The following two structures are used to process Wide Board requests.
3728  *
3729  * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
3730  * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
3731  * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
3732  * Mid-Level SCSI request structure.
3733  *
3734  * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
3735  * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
3736  * up to 255 scatter-gather elements may be used per request or
3737  * ADV_SCSI_REQ_Q.
3738  *
3739  * Both structures must be 32 byte aligned.
3740  */
3741 typedef struct adv_sgblk {
3742         ADV_SG_BLOCK sg_block;  /* Sgblock structure. */
3743         uchar align[32];        /* Sgblock structure padding. */
3744         struct adv_sgblk *next_sgblkp;  /* Next scatter-gather structure. */
3745 } adv_sgblk_t;
3746
3747 typedef struct adv_req {
3748         ADV_SCSI_REQ_Q scsi_req_q;      /* Adv Library request structure. */
3749         uchar align[32];        /* Request structure padding. */
3750         struct scsi_cmnd *cmndp;        /* Mid-Level SCSI command pointer. */
3751         adv_sgblk_t *sgblkp;    /* Adv Library scatter-gather pointer. */
3752         struct adv_req *next_reqp;      /* Next Request Structure. */
3753 } adv_req_t;
3754
3755 /*
3756  * Structure allocated for each board.
3757  *
3758  * This structure is allocated by scsi_host_alloc() at the end
3759  * of the 'Scsi_Host' structure starting at the 'hostdata'
3760  * field. It is guaranteed to be allocated from DMA-able memory.
3761  */
3762 typedef struct asc_board {
3763         int id;                 /* Board Id */
3764         uint flags;             /* Board flags */
3765         union {
3766                 ASC_DVC_VAR asc_dvc_var;        /* Narrow board */
3767                 ADV_DVC_VAR adv_dvc_var;        /* Wide board */
3768         } dvc_var;
3769         union {
3770                 ASC_DVC_CFG asc_dvc_cfg;        /* Narrow board */
3771                 ADV_DVC_CFG adv_dvc_cfg;        /* Wide board */
3772         } dvc_cfg;
3773         ushort asc_n_io_port;   /* Number I/O ports. */
3774         asc_queue_t active;     /* Active command queue */
3775         asc_queue_t waiting;    /* Waiting command queue */
3776         asc_queue_t done;       /* Done command queue */
3777         ADV_SCSI_BIT_ID_TYPE init_tidmask;      /* Target init./valid mask */
3778         struct scsi_device *device[ADV_MAX_TID + 1];    /* Mid-Level Scsi Device */
3779         ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
3780         ADV_SCSI_BIT_ID_TYPE queue_full;        /* Queue full mask */
3781         ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
3782         union {
3783                 ASCEEP_CONFIG asc_eep;  /* Narrow EEPROM config. */
3784                 ADVEEP_3550_CONFIG adv_3550_eep;        /* 3550 EEPROM config. */
3785                 ADVEEP_38C0800_CONFIG adv_38C0800_eep;  /* 38C0800 EEPROM config. */
3786                 ADVEEP_38C1600_CONFIG adv_38C1600_eep;  /* 38C1600 EEPROM config. */
3787         } eep_config;
3788         ulong last_reset;       /* Saved last reset time */
3789         spinlock_t lock;        /* Board spinlock */
3790         /* /proc/scsi/advansys/[0...] */
3791         char *prtbuf;           /* /proc print buffer */
3792 #ifdef ADVANSYS_STATS
3793         struct asc_stats asc_stats;     /* Board statistics */
3794 #endif                          /* ADVANSYS_STATS */
3795         /*
3796          * The following fields are used only for Narrow Boards.
3797          */
3798         /* The following three structures must be in DMA-able memory. */
3799         ASC_SCSI_REQ_Q scsireqq;
3800         ASC_CAP_INFO cap_info;
3801         ASC_SCSI_INQUIRY inquiry;
3802         uchar sdtr_data[ASC_MAX_TID + 1];       /* SDTR information */
3803         /*
3804          * The following fields are used only for Wide Boards.
3805          */
3806         void __iomem *ioremap_addr;     /* I/O Memory remap address. */
3807         ushort ioport;          /* I/O Port address. */
3808         ADV_CARR_T *carrp;      /* ADV_CARR_T memory block. */
3809         adv_req_t *orig_reqp;   /* adv_req_t memory block. */
3810         adv_req_t *adv_reqp;    /* Request structures. */
3811         adv_sgblk_t *adv_sgblkp;        /* Scatter-gather structures. */
3812         ushort bios_signature;  /* BIOS Signature. */
3813         ushort bios_version;    /* BIOS Version. */
3814         ushort bios_codeseg;    /* BIOS Code Segment. */
3815         ushort bios_codelen;    /* BIOS Code Segment Length. */
3816 } asc_board_t;
3817
3818 /* Number of boards detected in system. */
3819 static int asc_board_count;
3820
3821 /* Overrun buffer used by all narrow boards. */
3822 static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
3823
3824 /*
3825  * Global structures required to issue a command.
3826  */
3827 static ASC_SCSI_Q asc_scsi_q = { {0} };
3828 static ASC_SG_HEAD asc_sg_head = { 0 };
3829
3830 #ifdef ADVANSYS_DEBUG
3831 static int asc_dbglvl = 3;
3832 #endif /* ADVANSYS_DEBUG */
3833
3834 /*
3835  * --- Driver Function Prototypes
3836  *
3837  * advansys.h contains function prototypes for functions global to Linux.
3838  */
3839
3840 static int advansys_slave_configure(struct scsi_device *);
3841 static void asc_scsi_done_list(struct scsi_cmnd *);
3842 static int asc_execute_scsi_cmnd(struct scsi_cmnd *);
3843 static int asc_build_req(asc_board_t *, struct scsi_cmnd *);
3844 static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
3845 static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
3846 static void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
3847 static void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3848 static void adv_async_callback(ADV_DVC_VAR *, uchar);
3849 static void asc_enqueue(asc_queue_t *, REQP, int);
3850 static REQP asc_dequeue(asc_queue_t *, int);
3851 static REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
3852 static int asc_rmqueue(asc_queue_t *, REQP);
3853 static void asc_execute_queue(asc_queue_t *);
3854 #ifdef CONFIG_PROC_FS
3855 static int asc_proc_copy(off_t, off_t, char *, int, char *, int);
3856 static int asc_prt_board_devices(struct Scsi_Host *, char *, int);
3857 static int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
3858 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
3859 static int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
3860 static int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
3861 static int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
3862 static int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
3863 static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
3864 static int asc_prt_line(char *, int, char *fmt, ...);
3865 #endif /* CONFIG_PROC_FS */
3866
3867 /* Declaration for Asc Library internal functions referenced by driver. */
3868 static int AscFindSignature(PortAddr);
3869 static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
3870
3871 /* Statistics function prototypes. */
3872 #ifdef ADVANSYS_STATS
3873 #ifdef CONFIG_PROC_FS
3874 static int asc_prt_board_stats(struct Scsi_Host *, char *, int);
3875 static int asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
3876 #endif /* CONFIG_PROC_FS */
3877 #endif /* ADVANSYS_STATS */
3878
3879 /* Debug function prototypes. */
3880 #ifdef ADVANSYS_DEBUG
3881 static void asc_prt_scsi_host(struct Scsi_Host *);
3882 static void asc_prt_scsi_cmnd(struct scsi_cmnd *);
3883 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
3884 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
3885 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
3886 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
3887 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
3888 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
3889 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
3890 static void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
3891 static void asc_prt_hex(char *f, uchar *, int);
3892 #endif /* ADVANSYS_DEBUG */
3893
3894 #ifdef CONFIG_PROC_FS
3895 /*
3896  * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
3897  *
3898  * *buffer: I/O buffer
3899  * **start: if inout == FALSE pointer into buffer where user read should start
3900  * offset: current offset into a /proc/scsi/advansys/[0...] file
3901  * length: length of buffer
3902  * hostno: Scsi_Host host_no
3903  * inout: TRUE - user is writing; FALSE - user is reading
3904  *
3905  * Return the number of bytes read from or written to a
3906  * /proc/scsi/advansys/[0...] file.
3907  *
3908  * Note: This function uses the per board buffer 'prtbuf' which is
3909  * allocated when the board is initialized in advansys_detect(). The
3910  * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
3911  * used to write to the buffer. The way asc_proc_copy() is written
3912  * if 'prtbuf' is too small it will not be overwritten. Instead the
3913  * user just won't get all the available statistics.
3914  */
3915 static int
3916 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
3917                    off_t offset, int length, int inout)
3918 {
3919         asc_board_t *boardp;
3920         char *cp;
3921         int cplen;
3922         int cnt;
3923         int totcnt;
3924         int leftlen;
3925         char *curbuf;
3926         off_t advoffset;
3927 #ifdef ADVANSYS_STATS
3928         int tgt_id;
3929 #endif /* ADVANSYS_STATS */
3930
3931         ASC_DBG(1, "advansys_proc_info: begin\n");
3932
3933         /*
3934          * User write not supported.
3935          */
3936         if (inout == TRUE) {
3937                 return (-ENOSYS);
3938         }
3939
3940         /*
3941          * User read of /proc/scsi/advansys/[0...] file.
3942          */
3943
3944         boardp = ASC_BOARDP(shost);
3945
3946         /* Copy read data starting at the beginning of the buffer. */
3947         *start = buffer;
3948         curbuf = buffer;
3949         advoffset = 0;
3950         totcnt = 0;
3951         leftlen = length;
3952
3953         /*
3954          * Get board configuration information.
3955          *
3956          * advansys_info() returns the board string from its own static buffer.
3957          */
3958         cp = (char *)advansys_info(shost);
3959         strcat(cp, "\n");
3960         cplen = strlen(cp);
3961         /* Copy board information. */
3962         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3963         totcnt += cnt;
3964         leftlen -= cnt;
3965         if (leftlen == 0) {
3966                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3967                 return totcnt;
3968         }
3969         advoffset += cplen;
3970         curbuf += cnt;
3971
3972         /*
3973          * Display Wide Board BIOS Information.
3974          */
3975         if (ASC_WIDE_BOARD(boardp)) {
3976                 cp = boardp->prtbuf;
3977                 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
3978                 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3979                 cnt =
3980                     asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
3981                                   cplen);
3982                 totcnt += cnt;
3983                 leftlen -= cnt;
3984                 if (leftlen == 0) {
3985                         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3986                         return totcnt;
3987                 }
3988                 advoffset += cplen;
3989                 curbuf += cnt;
3990         }
3991
3992         /*
3993          * Display driver information for each device attached to the board.
3994          */
3995         cp = boardp->prtbuf;
3996         cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
3997         ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3998         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3999         totcnt += cnt;
4000         leftlen -= cnt;
4001         if (leftlen == 0) {
4002                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4003                 return totcnt;
4004         }
4005         advoffset += cplen;
4006         curbuf += cnt;
4007
4008         /*
4009          * Display EEPROM configuration for the board.
4010          */
4011         cp = boardp->prtbuf;
4012         if (ASC_NARROW_BOARD(boardp)) {
4013                 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
4014         } else {
4015                 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
4016         }
4017         ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4018         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4019         totcnt += cnt;
4020         leftlen -= cnt;
4021         if (leftlen == 0) {
4022                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4023                 return totcnt;
4024         }
4025         advoffset += cplen;
4026         curbuf += cnt;
4027
4028         /*
4029          * Display driver configuration and information for the board.
4030          */
4031         cp = boardp->prtbuf;
4032         cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
4033         ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4034         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4035         totcnt += cnt;
4036         leftlen -= cnt;
4037         if (leftlen == 0) {
4038                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4039                 return totcnt;
4040         }
4041         advoffset += cplen;
4042         curbuf += cnt;
4043
4044 #ifdef ADVANSYS_STATS
4045         /*
4046          * Display driver statistics for the board.
4047          */
4048         cp = boardp->prtbuf;
4049         cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
4050         ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4051         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4052         totcnt += cnt;
4053         leftlen -= cnt;
4054         if (leftlen == 0) {
4055                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4056                 return totcnt;
4057         }
4058         advoffset += cplen;
4059         curbuf += cnt;
4060
4061         /*
4062          * Display driver statistics for each target.
4063          */
4064         for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
4065                 cp = boardp->prtbuf;
4066                 cplen = asc_prt_target_stats(shost, tgt_id, cp,
4067                                                         ASC_PRTBUF_SIZE);
4068                 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4069                 cnt =
4070                     asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
4071                                   cplen);
4072                 totcnt += cnt;
4073                 leftlen -= cnt;
4074                 if (leftlen == 0) {
4075                         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4076                         return totcnt;
4077                 }
4078                 advoffset += cplen;
4079                 curbuf += cnt;
4080         }
4081 #endif /* ADVANSYS_STATS */
4082
4083         /*
4084          * Display Asc Library dynamic configuration information
4085          * for the board.
4086          */
4087         cp = boardp->prtbuf;
4088         if (ASC_NARROW_BOARD(boardp)) {
4089                 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
4090         } else {
4091                 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
4092         }
4093         ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4094         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4095         totcnt += cnt;
4096         leftlen -= cnt;
4097         if (leftlen == 0) {
4098                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4099                 return totcnt;
4100         }
4101         advoffset += cplen;
4102         curbuf += cnt;
4103
4104         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4105
4106         return totcnt;
4107 }
4108 #endif /* CONFIG_PROC_FS */
4109
4110 /*
4111  * advansys_info()
4112  *
4113  * Return suitable for printing on the console with the argument
4114  * adapter's configuration information.
4115  *
4116  * Note: The information line should not exceed ASC_INFO_SIZE bytes,
4117  * otherwise the static 'info' array will be overrun.
4118  */
4119 static const char *advansys_info(struct Scsi_Host *shost)
4120 {
4121         static char info[ASC_INFO_SIZE];
4122         asc_board_t *boardp;
4123         ASC_DVC_VAR *asc_dvc_varp;
4124         ADV_DVC_VAR *adv_dvc_varp;
4125         char *busname;
4126         int iolen;
4127         char *widename = NULL;
4128
4129         boardp = ASC_BOARDP(shost);
4130         if (ASC_NARROW_BOARD(boardp)) {
4131                 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4132                 ASC_DBG(1, "advansys_info: begin\n");
4133                 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
4134                         if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
4135                             ASC_IS_ISAPNP) {
4136                                 busname = "ISA PnP";
4137                         } else {
4138                                 busname = "ISA";
4139                         }
4140                         /* Don't reference 'shost->n_io_port'; It may be truncated. */
4141                         sprintf(info,
4142                                 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
4143                                 ASC_VERSION, busname,
4144                                 (ulong)shost->io_port,
4145                                 (ulong)shost->io_port + boardp->asc_n_io_port -
4146                                 1, shost->irq, shost->dma_channel);
4147                 } else {
4148                         if (asc_dvc_varp->bus_type & ASC_IS_VL) {
4149                                 busname = "VL";
4150                         } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
4151                                 busname = "EISA";
4152                         } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
4153                                 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
4154                                     == ASC_IS_PCI_ULTRA) {
4155                                         busname = "PCI Ultra";
4156                                 } else {
4157                                         busname = "PCI";
4158                                 }
4159                         } else {
4160                                 busname = "?";
4161                                 ASC_PRINT2
4162                                     ("advansys_info: board %d: unknown bus type %d\n",
4163                                      boardp->id, asc_dvc_varp->bus_type);
4164                         }
4165                         /* Don't reference 'shost->n_io_port'; It may be truncated. */
4166                         sprintf(info,
4167                                 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
4168                                 ASC_VERSION, busname,
4169                                 (ulong)shost->io_port,
4170                                 (ulong)shost->io_port + boardp->asc_n_io_port -
4171                                 1, shost->irq);
4172                 }
4173         } else {
4174                 /*
4175                  * Wide Adapter Information
4176                  *
4177                  * Memory-mapped I/O is used instead of I/O space to access
4178                  * the adapter, but display the I/O Port range. The Memory
4179                  * I/O address is displayed through the driver /proc file.
4180                  */
4181                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4182                 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4183                         iolen = ADV_3550_IOLEN;
4184                         widename = "Ultra-Wide";
4185                 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4186                         iolen = ADV_38C0800_IOLEN;
4187                         widename = "Ultra2-Wide";
4188                 } else {
4189                         iolen = ADV_38C1600_IOLEN;
4190                         widename = "Ultra3-Wide";
4191                 }
4192                 sprintf(info,
4193                         "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
4194                         ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
4195                         (ulong)adv_dvc_varp->iop_base + iolen - 1, shost->irq);
4196         }
4197         ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
4198         ASC_DBG(1, "advansys_info: end\n");
4199         return info;
4200 }
4201
4202 /*
4203  * advansys_queuecommand() - interrupt-driven I/O entrypoint.
4204  *
4205  * This function always returns 0. Command return status is saved
4206  * in the 'scp' result field.
4207  */
4208 static int
4209 advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *))
4210 {
4211         struct Scsi_Host *shost;
4212         asc_board_t *boardp;
4213         ulong flags;
4214         struct scsi_cmnd *done_scp;
4215
4216         shost = scp->device->host;
4217         boardp = ASC_BOARDP(shost);
4218         ASC_STATS(shost, queuecommand);
4219
4220         /* host_lock taken by mid-level prior to call but need to protect */
4221         /* against own ISR */
4222         spin_lock_irqsave(&boardp->lock, flags);
4223
4224         /*
4225          * Block new commands while handling a reset or abort request.
4226          */
4227         if (boardp->flags & ASC_HOST_IN_RESET) {
4228                 ASC_DBG1(1,
4229                          "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
4230                          (ulong)scp);
4231                 scp->result = HOST_BYTE(DID_RESET);
4232
4233                 /*
4234                  * Add blocked requests to the board's 'done' queue. The queued
4235                  * requests will be completed at the end of the abort or reset
4236                  * handling.
4237                  */
4238                 asc_enqueue(&boardp->done, scp, ASC_BACK);
4239                 spin_unlock_irqrestore(&boardp->lock, flags);
4240                 return 0;
4241         }
4242
4243         /*
4244          * Attempt to execute any waiting commands for the board.
4245          */
4246         if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4247                 ASC_DBG(1,
4248                         "advansys_queuecommand: before asc_execute_queue() waiting\n");
4249                 asc_execute_queue(&boardp->waiting);
4250         }
4251
4252         /*
4253          * Save the function pointer to Linux mid-level 'done' function
4254          * and attempt to execute the command.
4255          *
4256          * If ASC_NOERROR is returned the request has been added to the
4257          * board's 'active' queue and will be completed by the interrupt
4258          * handler.
4259          *
4260          * If ASC_BUSY is returned add the request to the board's per
4261          * target waiting list. This is the first time the request has
4262          * been tried. Add it to the back of the waiting list. It will be
4263          * retried later.
4264          *
4265          * If an error occurred, the request will have been placed on the
4266          * board's 'done' queue and must be completed before returning.
4267          */
4268         scp->scsi_done = done;
4269         switch (asc_execute_scsi_cmnd(scp)) {
4270         case ASC_NOERROR:
4271                 break;
4272         case ASC_BUSY:
4273                 asc_enqueue(&boardp->waiting, scp, ASC_BACK);
4274                 break;
4275         case ASC_ERROR:
4276         default:
4277                 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
4278                 /* Interrupts could be enabled here. */
4279                 asc_scsi_done_list(done_scp);
4280                 break;
4281         }
4282         spin_unlock_irqrestore(&boardp->lock, flags);
4283
4284         return 0;
4285 }
4286
4287 /*
4288  * advansys_reset()
4289  *
4290  * Reset the bus associated with the command 'scp'.
4291  *
4292  * This function runs its own thread. Interrupts must be blocked but
4293  * sleeping is allowed and no locking other than for host structures is
4294  * required. Returns SUCCESS or FAILED.
4295  */
4296 static int advansys_reset(struct scsi_cmnd *scp)
4297 {
4298         struct Scsi_Host *shost;
4299         asc_board_t *boardp;
4300         ASC_DVC_VAR *asc_dvc_varp;
4301         ADV_DVC_VAR *adv_dvc_varp;
4302         ulong flags;
4303         struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4304         struct scsi_cmnd *tscp, *new_last_scp;
4305         int status;
4306         int ret = SUCCESS;
4307
4308         ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp);
4309
4310 #ifdef ADVANSYS_STATS
4311         if (scp->device->host != NULL) {
4312                 ASC_STATS(scp->device->host, reset);
4313         }
4314 #endif /* ADVANSYS_STATS */
4315
4316         if ((shost = scp->device->host) == NULL) {
4317                 scp->result = HOST_BYTE(DID_ERROR);
4318                 return FAILED;
4319         }
4320
4321         boardp = ASC_BOARDP(shost);
4322
4323         ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
4324                    boardp->id);
4325         /*
4326          * Check for re-entrancy.
4327          */
4328         spin_lock_irqsave(&boardp->lock, flags);
4329         if (boardp->flags & ASC_HOST_IN_RESET) {
4330                 spin_unlock_irqrestore(&boardp->lock, flags);
4331                 return FAILED;
4332         }
4333         boardp->flags |= ASC_HOST_IN_RESET;
4334         spin_unlock_irqrestore(&boardp->lock, flags);
4335
4336         if (ASC_NARROW_BOARD(boardp)) {
4337                 /*
4338                  * Narrow Board
4339                  */
4340                 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4341
4342                 /*
4343                  * Reset the chip and SCSI bus.
4344                  */
4345                 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
4346                 status = AscInitAsc1000Driver(asc_dvc_varp);
4347
4348                 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
4349                 if (asc_dvc_varp->err_code) {
4350                         ASC_PRINT2
4351                             ("advansys_reset: board %d: SCSI bus reset error: 0x%x\n",
4352                              boardp->id, asc_dvc_varp->err_code);
4353                         ret = FAILED;
4354                 } else if (status) {
4355                         ASC_PRINT2
4356                             ("advansys_reset: board %d: SCSI bus reset warning: 0x%x\n",
4357                              boardp->id, status);
4358                 } else {
4359                         ASC_PRINT1
4360                             ("advansys_reset: board %d: SCSI bus reset successful.\n",
4361                              boardp->id);
4362                 }
4363
4364                 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
4365                 spin_lock_irqsave(&boardp->lock, flags);
4366
4367         } else {
4368                 /*
4369                  * Wide Board
4370                  *
4371                  * If the suggest reset bus flags are set, then reset the bus.
4372                  * Otherwise only reset the device.
4373                  */
4374                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4375
4376                 /*
4377                  * Reset the target's SCSI bus.
4378                  */
4379                 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
4380                 switch (AdvResetChipAndSB(adv_dvc_varp)) {
4381                 case ASC_TRUE:
4382                         ASC_PRINT1
4383                             ("advansys_reset: board %d: SCSI bus reset successful.\n",
4384                              boardp->id);
4385                         break;
4386                 case ASC_FALSE:
4387                 default:
4388                         ASC_PRINT1
4389                             ("advansys_reset: board %d: SCSI bus reset error.\n",
4390                              boardp->id);
4391                         ret = FAILED;
4392                         break;
4393                 }
4394                 spin_lock_irqsave(&boardp->lock, flags);
4395                 (void)AdvISR(adv_dvc_varp);
4396         }
4397         /* Board lock is held. */
4398
4399         /*
4400          * Dequeue all board 'done' requests. A pointer to the last request
4401          * is returned in 'last_scp'.
4402          */
4403         done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
4404
4405         /*
4406          * Dequeue all board 'active' requests for all devices and set
4407          * the request status to DID_RESET. A pointer to the last request
4408          * is returned in 'last_scp'.
4409          */
4410         if (done_scp == NULL) {
4411                 done_scp =
4412                     asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL);
4413                 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4414                         tscp->result = HOST_BYTE(DID_RESET);
4415                 }
4416         } else {
4417                 /* Append to 'done_scp' at the end with 'last_scp'. */
4418                 ASC_ASSERT(last_scp != NULL);
4419                 last_scp->host_scribble =
4420                     (unsigned char *)asc_dequeue_list(&boardp->active,
4421                                                       &new_last_scp,
4422                                                       ASC_TID_ALL);
4423                 if (new_last_scp != NULL) {
4424                         ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4425                         for (tscp = REQPNEXT(last_scp); tscp;
4426                              tscp = REQPNEXT(tscp)) {
4427                                 tscp->result = HOST_BYTE(DID_RESET);
4428                         }
4429                         last_scp = new_last_scp;
4430                 }
4431         }
4432
4433         /*
4434          * Dequeue all 'waiting' requests and set the request status
4435          * to DID_RESET.
4436          */
4437         if (done_scp == NULL) {
4438                 done_scp =
4439                     asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL);
4440                 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4441                         tscp->result = HOST_BYTE(DID_RESET);
4442                 }
4443         } else {
4444                 /* Append to 'done_scp' at the end with 'last_scp'. */
4445                 ASC_ASSERT(last_scp != NULL);
4446                 last_scp->host_scribble =
4447                     (unsigned char *)asc_dequeue_list(&boardp->waiting,
4448                                                       &new_last_scp,
4449                                                       ASC_TID_ALL);
4450                 if (new_last_scp != NULL) {
4451                         ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4452                         for (tscp = REQPNEXT(last_scp); tscp;
4453                              tscp = REQPNEXT(tscp)) {
4454                                 tscp->result = HOST_BYTE(DID_RESET);
4455                         }
4456                         last_scp = new_last_scp;
4457                 }
4458         }
4459
4460         /* Save the time of the most recently completed reset. */
4461         boardp->last_reset = jiffies;
4462
4463         /* Clear reset flag. */
4464         boardp->flags &= ~ASC_HOST_IN_RESET;
4465         spin_unlock_irqrestore(&boardp->lock, flags);
4466
4467         /*
4468          * Complete all the 'done_scp' requests.
4469          */
4470         if (done_scp != NULL) {
4471                 asc_scsi_done_list(done_scp);
4472         }
4473
4474         ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
4475
4476         return ret;
4477 }
4478
4479 /*
4480  * advansys_biosparam()
4481  *
4482  * Translate disk drive geometry if the "BIOS greater than 1 GB"
4483  * support is enabled for a drive.
4484  *
4485  * ip (information pointer) is an int array with the following definition:
4486  * ip[0]: heads
4487  * ip[1]: sectors
4488  * ip[2]: cylinders
4489  */
4490 static int
4491 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
4492                    sector_t capacity, int ip[])
4493 {
4494         asc_board_t *boardp;
4495
4496         ASC_DBG(1, "advansys_biosparam: begin\n");
4497         ASC_STATS(sdev->host, biosparam);
4498         boardp = ASC_BOARDP(sdev->host);
4499         if (ASC_NARROW_BOARD(boardp)) {
4500                 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
4501                      ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
4502                         ip[0] = 255;
4503                         ip[1] = 63;
4504                 } else {
4505                         ip[0] = 64;
4506                         ip[1] = 32;
4507                 }
4508         } else {
4509                 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
4510                      BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
4511                         ip[0] = 255;
4512                         ip[1] = 63;
4513                 } else {
4514                         ip[0] = 64;
4515                         ip[1] = 32;
4516                 }
4517         }
4518         ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
4519         ASC_DBG(1, "advansys_biosparam: end\n");
4520         return 0;
4521 }
4522
4523 static struct scsi_host_template advansys_template = {
4524         .proc_name = "advansys",
4525 #ifdef CONFIG_PROC_FS
4526         .proc_info = advansys_proc_info,
4527 #endif
4528         .name = "advansys",
4529         .info = advansys_info,
4530         .queuecommand = advansys_queuecommand,
4531         .eh_bus_reset_handler = advansys_reset,
4532         .bios_param = advansys_biosparam,
4533         .slave_configure = advansys_slave_configure,
4534         /*
4535          * Because the driver may control an ISA adapter 'unchecked_isa_dma'
4536          * must be set. The flag will be cleared in advansys_board_found
4537          * for non-ISA adapters.
4538          */
4539         .unchecked_isa_dma = 1,
4540         /*
4541          * All adapters controlled by this driver are capable of large
4542          * scatter-gather lists. According to the mid-level SCSI documentation
4543          * this obviates any performance gain provided by setting
4544          * 'use_clustering'. But empirically while CPU utilization is increased
4545          * by enabling clustering, I/O throughput increases as well.
4546          */
4547         .use_clustering = ENABLE_CLUSTERING,
4548 };
4549
4550 /*
4551  * --- Miscellaneous Driver Functions
4552  */
4553
4554 /*
4555  * First-level interrupt handler.
4556  *
4557  * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
4558  * all boards are currently checked for interrupts on each interrupt, 'dev_id'
4559  * is not referenced. 'dev_id' could be used to identify an interrupt passed
4560  * to the AdvanSys driver which is for a device sharing an interrupt with
4561  * an AdvanSys adapter.
4562  */
4563 static irqreturn_t advansys_interrupt(int irq, void *dev_id)
4564 {
4565         unsigned long flags;
4566         struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4567         struct scsi_cmnd *new_last_scp;
4568         struct Scsi_Host *shost = dev_id;
4569         asc_board_t *boardp = ASC_BOARDP(shost);
4570         irqreturn_t result = IRQ_NONE;
4571
4572         ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp);
4573         spin_lock_irqsave(&boardp->lock, flags);
4574         if (ASC_NARROW_BOARD(boardp)) {
4575                 /*
4576                  * Narrow Board
4577                  */
4578                 if (AscIsIntPending(shost->io_port)) {
4579                         result = IRQ_HANDLED;
4580                         ASC_STATS(shost, interrupt);
4581                         ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
4582                         AscISR(&boardp->dvc_var.asc_dvc_var);
4583                 }
4584         } else {
4585                 /*
4586                  * Wide Board
4587                  */
4588                 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
4589                 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
4590                         result = IRQ_HANDLED;
4591                         ASC_STATS(shost, interrupt);
4592                 }
4593         }
4594
4595         /*
4596          * Start waiting requests and create a list of completed requests.
4597          *
4598          * If a reset request is being performed for the board, the reset
4599          * handler will complete pending requests after it has completed.
4600          */
4601         if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
4602                 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%p, "
4603                          "last_scp 0x%p\n", done_scp, last_scp);
4604
4605                 /* Start any waiting commands for the board. */
4606                 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4607                         ASC_DBG(1, "advansys_interrupt: before "
4608                                 "asc_execute_queue()\n");
4609                         asc_execute_queue(&boardp->waiting);
4610                 }
4611
4612                 /*
4613                  * Add to the list of requests that must be completed.
4614                  *
4615                  * 'done_scp' will always be NULL on the first iteration of
4616                  * this loop. 'last_scp' is set at the same time as 'done_scp'.
4617                  */
4618                 if (done_scp == NULL) {
4619                         done_scp = asc_dequeue_list(&boardp->done,
4620                                                 &last_scp, ASC_TID_ALL);
4621                 } else {
4622                         ASC_ASSERT(last_scp != NULL);
4623                         last_scp->host_scribble =
4624                             (unsigned char *)asc_dequeue_list(&boardp->
4625                                                               done,
4626                                                               &new_last_scp,
4627                                                               ASC_TID_ALL);
4628                         if (new_last_scp != NULL) {
4629                                 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4630                                 last_scp = new_last_scp;
4631                         }
4632                 }
4633         }
4634         spin_unlock_irqrestore(&boardp->lock, flags);
4635
4636         /*
4637          * If interrupts were enabled on entry, then they
4638          * are now enabled here.
4639          *
4640          * Complete all requests on the done list.
4641          */
4642
4643         asc_scsi_done_list(done_scp);
4644
4645         ASC_DBG(1, "advansys_interrupt: end\n");
4646         return result;
4647 }
4648
4649 /*
4650  * Set the number of commands to queue per device for the
4651  * specified host adapter.
4652  */
4653 static int advansys_slave_configure(struct scsi_device *device)
4654 {
4655         asc_board_t *boardp;
4656
4657         boardp = ASC_BOARDP(device->host);
4658         boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
4659         /*
4660          * Save a pointer to the device and set its initial/maximum
4661          * queue depth.  Only save the pointer for a lun0 dev though.
4662          */
4663         if (device->lun == 0)
4664                 boardp->device[device->id] = device;
4665         if (device->tagged_supported) {
4666                 if (ASC_NARROW_BOARD(boardp)) {
4667                         scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
4668                                                 boardp->dvc_var.asc_dvc_var.
4669                                                 max_dvc_qng[device->id]);
4670                 } else {
4671                         scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
4672                                                 boardp->dvc_var.adv_dvc_var.
4673                                                 max_dvc_qng);
4674                 }
4675         } else {
4676                 scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun);
4677         }
4678         ASC_DBG4(1,
4679                  "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n",
4680                  (ulong)device, (ulong)boardp, device->id, device->queue_depth);
4681         return 0;
4682 }
4683
4684 /*
4685  * Complete all requests on the singly linked list pointed
4686  * to by 'scp'.
4687  *
4688  * Interrupts can be enabled on entry.
4689  */
4690 static void asc_scsi_done_list(struct scsi_cmnd *scp)
4691 {
4692         struct scsi_cmnd *tscp;
4693
4694         ASC_DBG(2, "asc_scsi_done_list: begin\n");
4695         while (scp != NULL) {
4696                 asc_board_t *boardp;
4697                 struct device *dev;
4698
4699                 ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp);
4700                 tscp = REQPNEXT(scp);
4701                 scp->host_scribble = NULL;
4702
4703                 boardp = ASC_BOARDP(scp->device->host);
4704
4705                 if (ASC_NARROW_BOARD(boardp))
4706                         dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
4707                 else
4708                         dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
4709
4710                 if (scp->use_sg)
4711                         dma_unmap_sg(dev,
4712                                      (struct scatterlist *)scp->request_buffer,
4713                                      scp->use_sg, scp->sc_data_direction);
4714                 else if (scp->request_bufflen)
4715                         dma_unmap_single(dev, scp->SCp.dma_handle,
4716                                          scp->request_bufflen,
4717                                          scp->sc_data_direction);
4718
4719                 ASC_STATS(scp->device->host, done);
4720                 ASC_ASSERT(scp->scsi_done != NULL);
4721
4722                 scp->scsi_done(scp);
4723
4724                 scp = tscp;
4725         }
4726         ASC_DBG(2, "asc_scsi_done_list: done\n");
4727         return;
4728 }
4729
4730 /*
4731  * Execute a single 'Scsi_Cmnd'.
4732  *
4733  * The function 'done' is called when the request has been completed.
4734  *
4735  * Scsi_Cmnd:
4736  *
4737  *  host - board controlling device
4738  *  device - device to send command
4739  *  target - target of device
4740  *  lun - lun of device
4741  *  cmd_len - length of SCSI CDB
4742  *  cmnd - buffer for SCSI 8, 10, or 12 byte CDB
4743  *  use_sg - if non-zero indicates scatter-gather request with use_sg elements
4744  *
4745  *  if (use_sg == 0) {
4746  *    request_buffer - buffer address for request
4747  *    request_bufflen - length of request buffer
4748  *  } else {
4749  *    request_buffer - pointer to scatterlist structure
4750  *  }
4751  *
4752  *  sense_buffer - sense command buffer
4753  *
4754  *  result (4 bytes of an int):
4755  *    Byte Meaning
4756  *    0 SCSI Status Byte Code
4757  *    1 SCSI One Byte Message Code
4758  *    2 Host Error Code
4759  *    3 Mid-Level Error Code
4760  *
4761  *  host driver fields:
4762  *    SCp - Scsi_Pointer used for command processing status
4763  *    scsi_done - used to save caller's done function
4764  *    host_scribble - used for pointer to another struct scsi_cmnd
4765  *
4766  * If this function returns ASC_NOERROR the request has been enqueued
4767  * on the board's 'active' queue and will be completed from the
4768  * interrupt handler.
4769  *
4770  * If this function returns ASC_NOERROR the request has been enqueued
4771  * on the board's 'done' queue and must be completed by the caller.
4772  *
4773  * If ASC_BUSY is returned the request will be enqueued by the
4774  * caller on the target's waiting queue and re-tried later.
4775  */
4776 static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
4777 {
4778         asc_board_t *boardp;
4779         ASC_DVC_VAR *asc_dvc_varp;
4780         ADV_DVC_VAR *adv_dvc_varp;
4781         ADV_SCSI_REQ_Q *adv_scsiqp;
4782         struct scsi_device *device;
4783         int ret;
4784
4785         ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
4786                  (ulong)scp, (ulong)scp->scsi_done);
4787
4788         boardp = ASC_BOARDP(scp->device->host);
4789         device = boardp->device[scp->device->id];
4790
4791         if (ASC_NARROW_BOARD(boardp)) {
4792                 /*
4793                  * Build and execute Narrow Board request.
4794                  */
4795
4796                 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4797
4798                 /*
4799                  * Build Asc Library request structure using the
4800                  * global structures 'asc_scsi_req' and 'asc_sg_head'.
4801                  *
4802                  * If an error is returned, then the request has been
4803                  * queued on the board done queue. It will be completed
4804                  * by the caller.
4805                  *
4806                  * asc_build_req() can not return ASC_BUSY.
4807                  */
4808                 if (asc_build_req(boardp, scp) == ASC_ERROR) {
4809                         ASC_STATS(scp->device->host, build_error);
4810                         return ASC_ERROR;
4811                 }
4812
4813                 /*
4814                  * Execute the command. If there is no error, add the command
4815                  * to the active queue.
4816                  */
4817                 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
4818                 case ASC_NOERROR:
4819                         ASC_STATS(scp->device->host, exe_noerror);
4820                         /*
4821                          * Increment monotonically increasing per device successful
4822                          * request counter. Wrapping doesn't matter.
4823                          */
4824                         boardp->reqcnt[scp->device->id]++;
4825                         asc_enqueue(&boardp->active, scp, ASC_BACK);
4826                         ASC_DBG(1,
4827                                 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
4828                         break;
4829                 case ASC_BUSY:
4830                         /*
4831                          * Caller will enqueue request on the target's waiting queue
4832                          * and retry later.
4833                          */
4834                         ASC_STATS(scp->device->host, exe_busy);
4835                         break;
4836                 case ASC_ERROR:
4837                         ASC_PRINT2
4838                             ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4839                              boardp->id, asc_dvc_varp->err_code);
4840                         ASC_STATS(scp->device->host, exe_error);
4841                         scp->result = HOST_BYTE(DID_ERROR);
4842                         asc_enqueue(&boardp->done, scp, ASC_BACK);
4843                         break;
4844                 default:
4845                         ASC_PRINT2
4846                             ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
4847                              boardp->id, asc_dvc_varp->err_code);
4848                         ASC_STATS(scp->device->host, exe_unknown);
4849                         scp->result = HOST_BYTE(DID_ERROR);
4850                         asc_enqueue(&boardp->done, scp, ASC_BACK);
4851                         break;
4852                 }
4853         } else {
4854                 /*
4855                  * Build and execute Wide Board request.
4856                  */
4857                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4858
4859                 /*
4860                  * Build and get a pointer to an Adv Library request structure.
4861                  *
4862                  * If the request is successfully built then send it below,
4863                  * otherwise return with an error.
4864                  */
4865                 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
4866                 case ASC_NOERROR:
4867                         ASC_DBG(3,
4868                                 "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
4869                         break;
4870                 case ASC_BUSY:
4871                         ASC_DBG(1,
4872                                 "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
4873                         /*
4874                          * If busy is returned the request has not been enqueued.
4875                          * It will be enqueued by the caller on the target's waiting
4876                          * queue and retried later.
4877                          *
4878                          * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg'
4879                          * count wide board busy conditions. They are updated in
4880                          * adv_build_req and adv_get_sglist, respectively.
4881                          */
4882                         return ASC_BUSY;
4883                 case ASC_ERROR:
4884                         /* 
4885                          * If an error is returned, then the request has been
4886                          * queued on the board done queue. It will be completed
4887                          * by the caller.
4888                          */
4889                 default:
4890                         ASC_DBG(1,
4891                                 "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
4892                         ASC_STATS(scp->device->host, build_error);
4893                         return ASC_ERROR;
4894                 }
4895
4896                 /*
4897                  * Execute the command. If there is no error, add the command
4898                  * to the active queue.
4899                  */
4900                 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
4901                 case ASC_NOERROR:
4902                         ASC_STATS(scp->device->host, exe_noerror);
4903                         /*
4904                          * Increment monotonically increasing per device successful
4905                          * request counter. Wrapping doesn't matter.
4906                          */
4907                         boardp->reqcnt[scp->device->id]++;
4908                         asc_enqueue(&boardp->active, scp, ASC_BACK);
4909                         ASC_DBG(1,
4910                                 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
4911                         break;
4912                 case ASC_BUSY:
4913                         /*
4914                          * Caller will enqueue request on the target's waiting queue
4915                          * and retry later.
4916                          */
4917                         ASC_STATS(scp->device->host, exe_busy);
4918                         break;
4919                 case ASC_ERROR:
4920                         ASC_PRINT2
4921                             ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4922                              boardp->id, adv_dvc_varp->err_code);
4923                         ASC_STATS(scp->device->host, exe_error);
4924                         scp->result = HOST_BYTE(DID_ERROR);
4925                         asc_enqueue(&boardp->done, scp, ASC_BACK);
4926                         break;
4927                 default:
4928                         ASC_PRINT2
4929                             ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
4930                              boardp->id, adv_dvc_varp->err_code);
4931                         ASC_STATS(scp->device->host, exe_unknown);
4932                         scp->result = HOST_BYTE(DID_ERROR);
4933                         asc_enqueue(&boardp->done, scp, ASC_BACK);
4934                         break;
4935                 }
4936         }
4937
4938         ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
4939         return ret;
4940 }
4941
4942 /*
4943  * Build a request structure for the Asc Library (Narrow Board).
4944  *
4945  * The global structures 'asc_scsi_q' and 'asc_sg_head' are
4946  * used to build the request.
4947  *
4948  * If an error occurs, then queue the request on the board done
4949  * queue and return ASC_ERROR.
4950  */
4951 static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
4952 {
4953         struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
4954
4955         /*
4956          * Mutually exclusive access is required to 'asc_scsi_q' and
4957          * 'asc_sg_head' until after the request is started.
4958          */
4959         memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
4960
4961         /*
4962          * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
4963          */
4964         asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
4965
4966         /*
4967          * Build the ASC_SCSI_Q request.
4968          *
4969          * For narrow boards a CDB length maximum of 12 bytes
4970          * is supported.
4971          */
4972         if (scp->cmd_len > ASC_MAX_CDB_LEN) {
4973                 ASC_PRINT3
4974                     ("asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN  %d\n",
4975                      boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN);
4976                 scp->result = HOST_BYTE(DID_ERROR);
4977                 asc_enqueue(&boardp->done, scp, ASC_BACK);
4978                 return ASC_ERROR;
4979         }
4980         asc_scsi_q.cdbptr = &scp->cmnd[0];
4981         asc_scsi_q.q2.cdb_len = scp->cmd_len;
4982         asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
4983         asc_scsi_q.q1.target_lun = scp->device->lun;
4984         asc_scsi_q.q2.target_ix =
4985             ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
4986         asc_scsi_q.q1.sense_addr =
4987             cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
4988         asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
4989
4990         /*
4991          * If there are any outstanding requests for the current target,
4992          * then every 255th request send an ORDERED request. This heuristic
4993          * tries to retain the benefit of request sorting while preventing
4994          * request starvation. 255 is the max number of tags or pending commands
4995          * a device may have outstanding.
4996          *
4997          * The request count is incremented below for every successfully
4998          * started request.
4999          *
5000          */
5001         if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
5002             (boardp->reqcnt[scp->device->id] % 255) == 0) {
5003                 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
5004         } else {
5005                 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
5006         }
5007
5008         /*
5009          * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
5010          * buffer command.
5011          */
5012         if (scp->use_sg == 0) {
5013                 /*
5014                  * CDB request of single contiguous buffer.
5015                  */
5016                 ASC_STATS(scp->device->host, cont_cnt);
5017                 scp->SCp.dma_handle = scp->request_bufflen ?
5018                     dma_map_single(dev, scp->request_buffer,
5019                                    scp->request_bufflen,
5020                                    scp->sc_data_direction) : 0;
5021                 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
5022                 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
5023                 ASC_STATS_ADD(scp->device->host, cont_xfer,
5024                               ASC_CEILING(scp->request_bufflen, 512));
5025                 asc_scsi_q.q1.sg_queue_cnt = 0;
5026                 asc_scsi_q.sg_head = NULL;
5027         } else {
5028                 /*
5029                  * CDB scatter-gather request list.
5030                  */
5031                 int sgcnt;
5032                 int use_sg;
5033                 struct scatterlist *slp;
5034
5035                 slp = (struct scatterlist *)scp->request_buffer;
5036                 use_sg =
5037                     dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
5038
5039                 if (use_sg > scp->device->host->sg_tablesize) {
5040                         ASC_PRINT3
5041                             ("asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
5042                              boardp->id, use_sg,
5043                              scp->device->host->sg_tablesize);
5044                         dma_unmap_sg(dev, slp, scp->use_sg,
5045                                      scp->sc_data_direction);
5046                         scp->result = HOST_BYTE(DID_ERROR);
5047                         asc_enqueue(&boardp->done, scp, ASC_BACK);
5048                         return ASC_ERROR;
5049                 }
5050
5051                 ASC_STATS(scp->device->host, sg_cnt);
5052
5053                 /*
5054                  * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
5055                  * structure to point to it.
5056                  */
5057                 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
5058
5059                 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
5060                 asc_scsi_q.sg_head = &asc_sg_head;
5061                 asc_scsi_q.q1.data_cnt = 0;
5062                 asc_scsi_q.q1.data_addr = 0;
5063                 /* This is a byte value, otherwise it would need to be swapped. */
5064                 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
5065                 ASC_STATS_ADD(scp->device->host, sg_elem,
5066                               asc_sg_head.entry_cnt);
5067
5068                 /*
5069                  * Convert scatter-gather list into ASC_SG_HEAD list.
5070                  */
5071                 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
5072                         asc_sg_head.sg_list[sgcnt].addr =
5073                             cpu_to_le32(sg_dma_address(slp));
5074                         asc_sg_head.sg_list[sgcnt].bytes =
5075                             cpu_to_le32(sg_dma_len(slp));
5076                         ASC_STATS_ADD(scp->device->host, sg_xfer,
5077                                       ASC_CEILING(sg_dma_len(slp), 512));
5078                 }
5079         }
5080
5081         ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
5082         ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
5083
5084         return ASC_NOERROR;
5085 }
5086
5087 /*
5088  * Build a request structure for the Adv Library (Wide Board).
5089  *
5090  * If an adv_req_t can not be allocated to issue the request,
5091  * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
5092  *
5093  * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
5094  * microcode for DMA addresses or math operations are byte swapped
5095  * to little-endian order.
5096  */
5097 static int
5098 adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
5099               ADV_SCSI_REQ_Q **adv_scsiqpp)
5100 {
5101         adv_req_t *reqp;
5102         ADV_SCSI_REQ_Q *scsiqp;
5103         int i;
5104         int ret;
5105         struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
5106
5107         /*
5108          * Allocate an adv_req_t structure from the board to execute
5109          * the command.
5110          */
5111         if (boardp->adv_reqp == NULL) {
5112                 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
5113                 ASC_STATS(scp->device->host, adv_build_noreq);
5114                 return ASC_BUSY;
5115         } else {
5116                 reqp = boardp->adv_reqp;
5117                 boardp->adv_reqp = reqp->next_reqp;
5118                 reqp->next_reqp = NULL;
5119         }
5120
5121         /*
5122          * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
5123          */
5124         scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5125
5126         /*
5127          * Initialize the structure.
5128          */
5129         scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
5130
5131         /*
5132          * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
5133          */
5134         scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
5135
5136         /*
5137          * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
5138          */
5139         reqp->cmndp = scp;
5140
5141         /*
5142          * Build the ADV_SCSI_REQ_Q request.
5143          */
5144
5145         /*
5146          * Set CDB length and copy it to the request structure.
5147          * For wide  boards a CDB length maximum of 16 bytes
5148          * is supported.
5149          */
5150         if (scp->cmd_len > ADV_MAX_CDB_LEN) {
5151                 ASC_PRINT3
5152                     ("adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN  %d\n",
5153                      boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
5154                 scp->result = HOST_BYTE(DID_ERROR);
5155                 asc_enqueue(&boardp->done, scp, ASC_BACK);
5156                 return ASC_ERROR;
5157         }
5158         scsiqp->cdb_len = scp->cmd_len;
5159         /* Copy first 12 CDB bytes to cdb[]. */
5160         for (i = 0; i < scp->cmd_len && i < 12; i++) {
5161                 scsiqp->cdb[i] = scp->cmnd[i];
5162         }
5163         /* Copy last 4 CDB bytes, if present, to cdb16[]. */
5164         for (; i < scp->cmd_len; i++) {
5165                 scsiqp->cdb16[i - 12] = scp->cmnd[i];
5166         }
5167
5168         scsiqp->target_id = scp->device->id;
5169         scsiqp->target_lun = scp->device->lun;
5170
5171         scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
5172         scsiqp->sense_len = sizeof(scp->sense_buffer);
5173
5174         /*
5175          * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
5176          * buffer command.
5177          */
5178
5179         scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
5180         scsiqp->vdata_addr = scp->request_buffer;
5181         scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
5182
5183         if (scp->use_sg == 0) {
5184                 /*
5185                  * CDB request of single contiguous buffer.
5186                  */
5187                 reqp->sgblkp = NULL;
5188                 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
5189                 if (scp->request_bufflen) {
5190                         scsiqp->vdata_addr = scp->request_buffer;
5191                         scp->SCp.dma_handle =
5192                             dma_map_single(dev, scp->request_buffer,
5193                                            scp->request_bufflen,
5194                                            scp->sc_data_direction);
5195                 } else {
5196                         scsiqp->vdata_addr = NULL;
5197                         scp->SCp.dma_handle = 0;
5198                 }
5199                 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
5200                 scsiqp->sg_list_ptr = NULL;
5201                 scsiqp->sg_real_addr = 0;
5202                 ASC_STATS(scp->device->host, cont_cnt);
5203                 ASC_STATS_ADD(scp->device->host, cont_xfer,
5204                               ASC_CEILING(scp->request_bufflen, 512));
5205         } else {
5206                 /*
5207                  * CDB scatter-gather request list.
5208                  */
5209                 struct scatterlist *slp;
5210                 int use_sg;
5211
5212                 slp = (struct scatterlist *)scp->request_buffer;
5213                 use_sg =
5214                     dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
5215
5216                 if (use_sg > ADV_MAX_SG_LIST) {
5217                         ASC_PRINT3
5218                             ("adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
5219                              boardp->id, use_sg,
5220                              scp->device->host->sg_tablesize);
5221                         dma_unmap_sg(dev, slp, scp->use_sg,
5222                                      scp->sc_data_direction);
5223                         scp->result = HOST_BYTE(DID_ERROR);
5224                         asc_enqueue(&boardp->done, scp, ASC_BACK);
5225
5226                         /*
5227                          * Free the 'adv_req_t' structure by adding it back to the
5228                          * board free list.
5229                          */
5230                         reqp->next_reqp = boardp->adv_reqp;
5231                         boardp->adv_reqp = reqp;
5232
5233                         return ASC_ERROR;
5234                 }
5235
5236                 if ((ret =
5237                      adv_get_sglist(boardp, reqp, scp,
5238                                     use_sg)) != ADV_SUCCESS) {
5239                         /*
5240                          * Free the adv_req_t structure by adding it back to the
5241                          * board free list.
5242                          */
5243                         reqp->next_reqp = boardp->adv_reqp;
5244                         boardp->adv_reqp = reqp;
5245
5246                         return ret;
5247                 }
5248
5249                 ASC_STATS(scp->device->host, sg_cnt);
5250                 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
5251         }
5252
5253         ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5254         ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
5255
5256         *adv_scsiqpp = scsiqp;
5257
5258         return ASC_NOERROR;
5259 }
5260
5261 /*
5262  * Build scatter-gather list for Adv Library (Wide Board).
5263  *
5264  * Additional ADV_SG_BLOCK structures will need to be allocated
5265  * if the total number of scatter-gather elements exceeds
5266  * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
5267  * assumed to be physically contiguous.
5268  *
5269  * Return:
5270  *      ADV_SUCCESS(1) - SG List successfully created
5271  *      ADV_ERROR(-1) - SG List creation failed
5272  */
5273 static int
5274 adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
5275                int use_sg)
5276 {
5277         adv_sgblk_t *sgblkp;
5278         ADV_SCSI_REQ_Q *scsiqp;
5279         struct scatterlist *slp;
5280         int sg_elem_cnt;
5281         ADV_SG_BLOCK *sg_block, *prev_sg_block;
5282         ADV_PADDR sg_block_paddr;
5283         int i;
5284
5285         scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5286         slp = (struct scatterlist *)scp->request_buffer;
5287         sg_elem_cnt = use_sg;
5288         prev_sg_block = NULL;
5289         reqp->sgblkp = NULL;
5290
5291         do {
5292                 /*
5293                  * Allocate a 'adv_sgblk_t' structure from the board free
5294                  * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
5295                  * (15) scatter-gather elements.
5296                  */
5297                 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
5298                         ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
5299                         ASC_STATS(scp->device->host, adv_build_nosg);
5300
5301                         /*
5302                          * Allocation failed. Free 'adv_sgblk_t' structures already
5303                          * allocated for the request.
5304                          */
5305                         while ((sgblkp = reqp->sgblkp) != NULL) {
5306                                 /* Remove 'sgblkp' from the request list. */
5307                                 reqp->sgblkp = sgblkp->next_sgblkp;
5308
5309                                 /* Add 'sgblkp' to the board free list. */
5310                                 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5311                                 boardp->adv_sgblkp = sgblkp;
5312                         }
5313                         return ASC_BUSY;
5314                 } else {
5315                         /* Complete 'adv_sgblk_t' board allocation. */
5316                         boardp->adv_sgblkp = sgblkp->next_sgblkp;
5317                         sgblkp->next_sgblkp = NULL;
5318
5319                         /*
5320                          * Get 8 byte aligned virtual and physical addresses for
5321                          * the allocated ADV_SG_BLOCK structure.
5322                          */
5323                         sg_block =
5324                             (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
5325                         sg_block_paddr = virt_to_bus(sg_block);
5326
5327                         /*
5328                          * Check if this is the first 'adv_sgblk_t' for the request.
5329                          */
5330                         if (reqp->sgblkp == NULL) {
5331                                 /* Request's first scatter-gather block. */
5332                                 reqp->sgblkp = sgblkp;
5333
5334                                 /*
5335                                  * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
5336                                  * address pointers.
5337                                  */
5338                                 scsiqp->sg_list_ptr = sg_block;
5339                                 scsiqp->sg_real_addr =
5340                                     cpu_to_le32(sg_block_paddr);
5341                         } else {
5342                                 /* Request's second or later scatter-gather block. */
5343                                 sgblkp->next_sgblkp = reqp->sgblkp;
5344                                 reqp->sgblkp = sgblkp;
5345
5346                                 /*
5347                                  * Point the previous ADV_SG_BLOCK structure to
5348                                  * the newly allocated ADV_SG_BLOCK structure.
5349                                  */
5350                                 ASC_ASSERT(prev_sg_block != NULL);
5351                                 prev_sg_block->sg_ptr =
5352                                     cpu_to_le32(sg_block_paddr);
5353                         }
5354                 }
5355
5356                 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
5357                         sg_block->sg_list[i].sg_addr =
5358                             cpu_to_le32(sg_dma_address(slp));
5359                         sg_block->sg_list[i].sg_count =
5360                             cpu_to_le32(sg_dma_len(slp));
5361                         ASC_STATS_ADD(scp->device->host, sg_xfer,
5362                                       ASC_CEILING(sg_dma_len(slp), 512));
5363
5364                         if (--sg_elem_cnt == 0) {       /* Last ADV_SG_BLOCK and scatter-gather entry. */
5365                                 sg_block->sg_cnt = i + 1;
5366                                 sg_block->sg_ptr = 0L;  /* Last ADV_SG_BLOCK in list. */
5367                                 return ADV_SUCCESS;
5368                         }
5369                         slp++;
5370                 }
5371                 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
5372                 prev_sg_block = sg_block;
5373         }
5374         while (1);
5375         /* NOTREACHED */
5376 }
5377
5378 /*
5379  * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
5380  *
5381  * Interrupt callback function for the Narrow SCSI Asc Library.
5382  */
5383 static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
5384 {
5385         asc_board_t *boardp;
5386         struct scsi_cmnd *scp;
5387         struct Scsi_Host *shost;
5388
5389         ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
5390                  (ulong)asc_dvc_varp, (ulong)qdonep);
5391         ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
5392
5393         /*
5394          * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5395          * command that has been completed.
5396          */
5397         scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
5398         ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp);
5399
5400         if (scp == NULL) {
5401                 ASC_PRINT("asc_isr_callback: scp is NULL\n");
5402                 return;
5403         }
5404         ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5405
5406         shost = scp->device->host;
5407         ASC_STATS(shost, callback);
5408         ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
5409
5410         /*
5411          * If the request isn't found on the active queue, it may
5412          * have been removed to handle a reset request.
5413          * Display a message and return.
5414          */
5415         boardp = ASC_BOARDP(shost);
5416         ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
5417         if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5418                 ASC_PRINT2
5419                     ("asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
5420                      boardp->id, (ulong)scp);
5421                 return;
5422         }
5423
5424         /*
5425          * 'qdonep' contains the command's ending status.
5426          */
5427         switch (qdonep->d3.done_stat) {
5428         case QD_NO_ERROR:
5429                 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
5430                 scp->result = 0;
5431
5432                 /*
5433                  * If an INQUIRY command completed successfully, then call
5434                  * the AscInquiryHandling() function to set-up the device.
5435                  */
5436                 if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 &&
5437                     (scp->request_bufflen - qdonep->remain_bytes) >= 8) {
5438                         AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7,
5439                                            (ASC_SCSI_INQUIRY *)scp->
5440                                            request_buffer);
5441                 }
5442
5443                 /*
5444                  * Check for an underrun condition.
5445                  *
5446                  * If there was no error and an underrun condition, then
5447                  * then return the number of underrun bytes.
5448                  */
5449                 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
5450                     qdonep->remain_bytes <= scp->request_bufflen) {
5451                         ASC_DBG1(1,
5452                                  "asc_isr_callback: underrun condition %u bytes\n",
5453                                  (unsigned)qdonep->remain_bytes);
5454                         scp->resid = qdonep->remain_bytes;
5455                 }
5456                 break;
5457
5458         case QD_WITH_ERROR:
5459                 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
5460                 switch (qdonep->d3.host_stat) {
5461                 case QHSTA_NO_ERROR:
5462                         if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
5463                                 ASC_DBG(2,
5464                                         "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5465                                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5466                                                   sizeof(scp->sense_buffer));
5467                                 /*
5468                                  * Note: The 'status_byte()' macro used by target drivers
5469                                  * defined in scsi.h shifts the status byte returned by
5470                                  * host drivers right by 1 bit. This is why target drivers
5471                                  * also use right shifted status byte definitions. For
5472                                  * instance target drivers use CHECK_CONDITION, defined to
5473                                  * 0x1, instead of the SCSI defined check condition value
5474                                  * of 0x2. Host drivers are supposed to return the status
5475                                  * byte as it is defined by SCSI.
5476                                  */
5477                                 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5478                                     STATUS_BYTE(qdonep->d3.scsi_stat);
5479                         } else {
5480                                 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
5481                         }
5482                         break;
5483
5484                 default:
5485                         /* QHSTA error occurred */
5486                         ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
5487                                  qdonep->d3.host_stat);
5488                         scp->result = HOST_BYTE(DID_BAD_TARGET);
5489                         break;
5490                 }
5491                 break;
5492
5493         case QD_ABORTED_BY_HOST:
5494                 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
5495                 scp->result =
5496                     HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
5497                                                     scsi_msg) |
5498                     STATUS_BYTE(qdonep->d3.scsi_stat);
5499                 break;
5500
5501         default:
5502                 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n",
5503                          qdonep->d3.done_stat);
5504                 scp->result =
5505                     HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
5506                                                     scsi_msg) |
5507                     STATUS_BYTE(qdonep->d3.scsi_stat);
5508                 break;
5509         }
5510
5511         /*
5512          * If the 'init_tidmask' bit isn't already set for the target and the
5513          * current request finished normally, then set the bit for the target
5514          * to indicate that a device is present.
5515          */
5516         if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5517             qdonep->d3.done_stat == QD_NO_ERROR &&
5518             qdonep->d3.host_stat == QHSTA_NO_ERROR) {
5519                 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5520         }
5521
5522         /*
5523          * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5524          * function, add the command to the end of the board's done queue.
5525          * The done function for the command will be called from
5526          * advansys_interrupt().
5527          */
5528         asc_enqueue(&boardp->done, scp, ASC_BACK);
5529
5530         return;
5531 }
5532
5533 /*
5534  * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
5535  *
5536  * Callback function for the Wide SCSI Adv Library.
5537  */
5538 static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
5539 {
5540         asc_board_t *boardp;
5541         adv_req_t *reqp;
5542         adv_sgblk_t *sgblkp;
5543         struct scsi_cmnd *scp;
5544         struct Scsi_Host *shost;
5545         ADV_DCNT resid_cnt;
5546
5547         ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
5548                  (ulong)adv_dvc_varp, (ulong)scsiqp);
5549         ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5550
5551         /*
5552          * Get the adv_req_t structure for the command that has been
5553          * completed. The adv_req_t structure actually contains the
5554          * completed ADV_SCSI_REQ_Q structure.
5555          */
5556         reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
5557         ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp);
5558         if (reqp == NULL) {
5559                 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
5560                 return;
5561         }
5562
5563         /*
5564          * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5565          * command that has been completed.
5566          *
5567          * Note: The adv_req_t request structure and adv_sgblk_t structure,
5568          * if any, are dropped, because a board structure pointer can not be
5569          * determined.
5570          */
5571         scp = reqp->cmndp;
5572         ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp);
5573         if (scp == NULL) {
5574                 ASC_PRINT
5575                     ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
5576                 return;
5577         }
5578         ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5579
5580         shost = scp->device->host;
5581         ASC_STATS(shost, callback);
5582         ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
5583
5584         /*
5585          * If the request isn't found on the active queue, it may have been
5586          * removed to handle a reset request. Display a message and return.
5587          *
5588          * Note: Because the structure may still be in use don't attempt
5589          * to free the adv_req_t and adv_sgblk_t, if any, structures.
5590          */
5591         boardp = ASC_BOARDP(shost);
5592         ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
5593         if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5594                 ASC_PRINT2
5595                     ("adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
5596                      boardp->id, (ulong)scp);
5597                 return;
5598         }
5599
5600         /*
5601          * 'done_status' contains the command's ending status.
5602          */
5603         switch (scsiqp->done_status) {
5604         case QD_NO_ERROR:
5605                 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
5606                 scp->result = 0;
5607
5608                 /*
5609                  * Check for an underrun condition.
5610                  *
5611                  * If there was no error and an underrun condition, then
5612                  * then return the number of underrun bytes.
5613                  */
5614                 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
5615                 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
5616                     resid_cnt <= scp->request_bufflen) {
5617                         ASC_DBG1(1,
5618                                  "adv_isr_callback: underrun condition %lu bytes\n",
5619                                  (ulong)resid_cnt);
5620                         scp->resid = resid_cnt;
5621                 }
5622                 break;
5623
5624         case QD_WITH_ERROR:
5625                 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
5626                 switch (scsiqp->host_status) {
5627                 case QHSTA_NO_ERROR:
5628                         if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
5629                                 ASC_DBG(2,
5630                                         "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5631                                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5632                                                   sizeof(scp->sense_buffer));
5633                                 /*
5634                                  * Note: The 'status_byte()' macro used by target drivers
5635                                  * defined in scsi.h shifts the status byte returned by
5636                                  * host drivers right by 1 bit. This is why target drivers
5637                                  * also use right shifted status byte definitions. For
5638                                  * instance target drivers use CHECK_CONDITION, defined to
5639                                  * 0x1, instead of the SCSI defined check condition value
5640                                  * of 0x2. Host drivers are supposed to return the status
5641                                  * byte as it is defined by SCSI.
5642                                  */
5643                                 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5644                                     STATUS_BYTE(scsiqp->scsi_status);
5645                         } else {
5646                                 scp->result = STATUS_BYTE(scsiqp->scsi_status);
5647                         }
5648                         break;
5649
5650                 default:
5651                         /* Some other QHSTA error occurred. */
5652                         ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
5653                                  scsiqp->host_status);
5654                         scp->result = HOST_BYTE(DID_BAD_TARGET);
5655                         break;
5656                 }
5657                 break;
5658
5659         case QD_ABORTED_BY_HOST:
5660                 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
5661                 scp->result =
5662                     HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
5663                 break;
5664
5665         default:
5666                 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n",
5667                          scsiqp->done_status);
5668                 scp->result =
5669                     HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
5670                 break;
5671         }
5672
5673         /*
5674          * If the 'init_tidmask' bit isn't already set for the target and the
5675          * current request finished normally, then set the bit for the target
5676          * to indicate that a device is present.
5677          */
5678         if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5679             scsiqp->done_status == QD_NO_ERROR &&
5680             scsiqp->host_status == QHSTA_NO_ERROR) {
5681                 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5682         }
5683
5684         /*
5685          * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5686          * function, add the command to the end of the board's done queue.
5687          * The done function for the command will be called from
5688          * advansys_interrupt().
5689          */
5690         asc_enqueue(&boardp->done, scp, ASC_BACK);
5691
5692         /*
5693          * Free all 'adv_sgblk_t' structures allocated for the request.
5694          */
5695         while ((sgblkp = reqp->sgblkp) != NULL) {
5696                 /* Remove 'sgblkp' from the request list. */
5697                 reqp->sgblkp = sgblkp->next_sgblkp;
5698
5699                 /* Add 'sgblkp' to the board free list. */
5700                 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5701                 boardp->adv_sgblkp = sgblkp;
5702         }
5703
5704         /*
5705          * Free the adv_req_t structure used with the command by adding
5706          * it back to the board free list.
5707          */
5708         reqp->next_reqp = boardp->adv_reqp;
5709         boardp->adv_reqp = reqp;
5710
5711         ASC_DBG(1, "adv_isr_callback: done\n");
5712
5713         return;
5714 }
5715
5716 /*
5717  * adv_async_callback() - Adv Library asynchronous event callback function.
5718  */
5719 static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
5720 {
5721         switch (code) {
5722         case ADV_ASYNC_SCSI_BUS_RESET_DET:
5723                 /*
5724                  * The firmware detected a SCSI Bus reset.
5725                  */
5726                 ASC_DBG(0,
5727                         "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
5728                 break;
5729
5730         case ADV_ASYNC_RDMA_FAILURE:
5731                 /*
5732                  * Handle RDMA failure by resetting the SCSI Bus and
5733                  * possibly the chip if it is unresponsive. Log the error
5734                  * with a unique code.
5735                  */
5736                 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
5737                 AdvResetChipAndSB(adv_dvc_varp);
5738                 break;
5739
5740         case ADV_HOST_SCSI_BUS_RESET:
5741                 /*
5742                  * Host generated SCSI bus reset occurred.
5743                  */
5744                 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
5745                 break;
5746
5747         default:
5748                 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
5749                 break;
5750         }
5751 }
5752
5753 /*
5754  * Add a 'REQP' to the end of specified queue. Set 'tidmask'
5755  * to indicate a command is queued for the device.
5756  *
5757  * 'flag' may be either ASC_FRONT or ASC_BACK.
5758  *
5759  * 'REQPNEXT(reqp)' returns reqp's next pointer.
5760  */
5761 static void asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
5762 {
5763         int tid;
5764
5765         ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
5766                  (ulong)ascq, (ulong)reqp, flag);
5767         ASC_ASSERT(reqp != NULL);
5768         ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
5769         tid = REQPTID(reqp);
5770         ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5771         if (flag == ASC_FRONT) {
5772                 reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
5773                 ascq->q_first[tid] = reqp;
5774                 /* If the queue was empty, set the last pointer. */
5775                 if (ascq->q_last[tid] == NULL) {
5776                         ascq->q_last[tid] = reqp;
5777                 }
5778         } else {                /* ASC_BACK */
5779                 if (ascq->q_last[tid] != NULL) {
5780                         ascq->q_last[tid]->host_scribble =
5781                             (unsigned char *)reqp;
5782                 }
5783                 ascq->q_last[tid] = reqp;
5784                 reqp->host_scribble = NULL;
5785                 /* If the queue was empty, set the first pointer. */
5786                 if (ascq->q_first[tid] == NULL) {
5787                         ascq->q_first[tid] = reqp;
5788                 }
5789         }
5790         /* The queue has at least one entry, set its bit. */
5791         ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
5792 #ifdef ADVANSYS_STATS
5793         /* Maintain request queue statistics. */
5794         ascq->q_tot_cnt[tid]++;
5795         ascq->q_cur_cnt[tid]++;
5796         if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
5797                 ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
5798                 ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
5799                          tid, ascq->q_max_cnt[tid]);
5800         }
5801         REQPTIME(reqp) = REQTIMESTAMP();
5802 #endif /* ADVANSYS_STATS */
5803         ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong)reqp);
5804         return;
5805 }
5806
5807 /*
5808  * Return first queued 'REQP' on the specified queue for
5809  * the specified target device. Clear the 'tidmask' bit for
5810  * the device if no more commands are left queued for it.
5811  *
5812  * 'REQPNEXT(reqp)' returns reqp's next pointer.
5813  */
5814 static REQP asc_dequeue(asc_queue_t *ascq, int tid)
5815 {
5816         REQP reqp;
5817
5818         ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5819         ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5820         if ((reqp = ascq->q_first[tid]) != NULL) {
5821                 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
5822                 ascq->q_first[tid] = REQPNEXT(reqp);
5823                 /* If the queue is empty, clear its bit and the last pointer. */
5824                 if (ascq->q_first[tid] == NULL) {
5825                         ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5826                         ASC_ASSERT(ascq->q_last[tid] == reqp);
5827                         ascq->q_last[tid] = NULL;
5828                 }
5829 #ifdef ADVANSYS_STATS
5830                 /* Maintain request queue statistics. */
5831                 ascq->q_cur_cnt[tid]--;
5832                 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
5833                 REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
5834 #endif /* ADVANSYS_STATS */
5835         }
5836         ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong)reqp);
5837         return reqp;
5838 }
5839
5840 /*
5841  * Return a pointer to a singly linked list of all the requests queued
5842  * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
5843  *
5844  * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
5845  * the last request returned in the singly linked list.
5846  *
5847  * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
5848  * then all queued requests are concatenated into one list and
5849  * returned.
5850  *
5851  * Note: If 'lastpp' is used to append a new list to the end of
5852  * an old list, only change the old list last pointer if '*lastpp'
5853  * (or the function return value) is not NULL, i.e. use a temporary
5854  * variable for 'lastpp' and check its value after the function return
5855  * before assigning it to the list last pointer.
5856  *
5857  * Unfortunately collecting queuing time statistics adds overhead to
5858  * the function that isn't inherent to the function's algorithm.
5859  */
5860 static REQP asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
5861 {
5862         REQP firstp, lastp;
5863         int i;
5864
5865         ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5866         ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
5867
5868         /*
5869          * If 'tid' is not ASC_TID_ALL, return requests only for
5870          * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
5871          * requests for all tids.
5872          */
5873         if (tid != ASC_TID_ALL) {
5874                 /* Return all requests for the specified 'tid'. */
5875                 if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
5876                         /* List is empty; Set first and last return pointers to NULL. */
5877                         firstp = lastp = NULL;
5878                 } else {
5879                         firstp = ascq->q_first[tid];
5880                         lastp = ascq->q_last[tid];
5881                         ascq->q_first[tid] = ascq->q_last[tid] = NULL;
5882                         ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5883 #ifdef ADVANSYS_STATS
5884                         {
5885                                 REQP reqp;
5886                                 ascq->q_cur_cnt[tid] = 0;
5887                                 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
5888                                         REQTIMESTAT("asc_dequeue_list", ascq,
5889                                                     reqp, tid);
5890                                 }
5891                         }
5892 #endif /* ADVANSYS_STATS */
5893                 }
5894         } else {
5895                 /* Return all requests for all tids. */
5896                 firstp = lastp = NULL;
5897                 for (i = 0; i <= ADV_MAX_TID; i++) {
5898                         if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
5899                                 if (firstp == NULL) {
5900                                         firstp = ascq->q_first[i];
5901                                         lastp = ascq->q_last[i];
5902                                 } else {
5903                                         ASC_ASSERT(lastp != NULL);
5904                                         lastp->host_scribble =
5905                                             (unsigned char *)ascq->q_first[i];
5906                                         lastp = ascq->q_last[i];
5907                                 }
5908                                 ascq->q_first[i] = ascq->q_last[i] = NULL;
5909                                 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
5910 #ifdef ADVANSYS_STATS
5911                                 ascq->q_cur_cnt[i] = 0;
5912 #endif /* ADVANSYS_STATS */
5913                         }
5914                 }
5915 #ifdef ADVANSYS_STATS
5916                 {
5917                         REQP reqp;
5918                         for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
5919                                 REQTIMESTAT("asc_dequeue_list", ascq, reqp,
5920                                             reqp->device->id);
5921                         }
5922                 }
5923 #endif /* ADVANSYS_STATS */
5924         }
5925         if (lastpp) {
5926                 *lastpp = lastp;
5927         }
5928         ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong)firstp);
5929         return firstp;
5930 }
5931
5932 /*
5933  * Remove the specified 'REQP' from the specified queue for
5934  * the specified target device. Clear the 'tidmask' bit for the
5935  * device if no more commands are left queued for it.
5936  *
5937  * 'REQPNEXT(reqp)' returns reqp's the next pointer.
5938  *
5939  * Return ASC_TRUE if the command was found and removed,
5940  * otherwise return ASC_FALSE.
5941  */
5942 static int asc_rmqueue(asc_queue_t *ascq, REQP reqp)
5943 {
5944         REQP currp, prevp;
5945         int tid;
5946         int ret = ASC_FALSE;
5947
5948         ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
5949                  (ulong)ascq, (ulong)reqp);
5950         ASC_ASSERT(reqp != NULL);
5951
5952         tid = REQPTID(reqp);
5953         ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5954
5955         /*
5956          * Handle the common case of 'reqp' being the first
5957          * entry on the queue.
5958          */
5959         if (reqp == ascq->q_first[tid]) {
5960                 ret = ASC_TRUE;
5961                 ascq->q_first[tid] = REQPNEXT(reqp);
5962                 /* If the queue is now empty, clear its bit and the last pointer. */
5963                 if (ascq->q_first[tid] == NULL) {
5964                         ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5965                         ASC_ASSERT(ascq->q_last[tid] == reqp);
5966                         ascq->q_last[tid] = NULL;
5967                 }
5968         } else if (ascq->q_first[tid] != NULL) {
5969                 ASC_ASSERT(ascq->q_last[tid] != NULL);
5970                 /*
5971                  * Because the case of 'reqp' being the first entry has been
5972                  * handled above and it is known the queue is not empty, if
5973                  * 'reqp' is found on the queue it is guaranteed the queue will
5974                  * not become empty and that 'q_first[tid]' will not be changed.
5975                  *
5976                  * Set 'prevp' to the first entry, 'currp' to the second entry,
5977                  * and search for 'reqp'.
5978                  */
5979                 for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
5980                      currp; prevp = currp, currp = REQPNEXT(currp)) {
5981                         if (currp == reqp) {
5982                                 ret = ASC_TRUE;
5983                                 prevp->host_scribble =
5984                                     (unsigned char *)REQPNEXT(currp);
5985                                 reqp->host_scribble = NULL;
5986                                 if (ascq->q_last[tid] == reqp) {
5987                                         ascq->q_last[tid] = prevp;
5988                                 }
5989                                 break;
5990                         }
5991                 }
5992         }
5993 #ifdef ADVANSYS_STATS
5994         /* Maintain request queue statistics. */
5995         if (ret == ASC_TRUE) {
5996                 ascq->q_cur_cnt[tid]--;
5997                 REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
5998         }
5999         ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
6000 #endif /* ADVANSYS_STATS */
6001         ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong)reqp, ret);
6002         return ret;
6003 }
6004
6005 /*
6006  * Execute as many queued requests as possible for the specified queue.
6007  *
6008  * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd.
6009  */
6010 static void asc_execute_queue(asc_queue_t *ascq)
6011 {
6012         ADV_SCSI_BIT_ID_TYPE scan_tidmask;
6013         REQP reqp;
6014         int i;
6015
6016         ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong)ascq);
6017         /*
6018          * Execute queued commands for devices attached to
6019          * the current board in round-robin fashion.
6020          */
6021         scan_tidmask = ascq->q_tidmask;
6022         do {
6023                 for (i = 0; i <= ADV_MAX_TID; i++) {
6024                         if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
6025                                 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
6026                                         scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
6027                                 } else
6028                                     if (asc_execute_scsi_cmnd
6029                                         ((struct scsi_cmnd *)reqp)
6030                                         == ASC_BUSY) {
6031                                         scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
6032                                         /*
6033                                          * The request returned ASC_BUSY. Enqueue at the front of
6034                                          * target's waiting list to maintain correct ordering.
6035                                          */
6036                                         asc_enqueue(ascq, reqp, ASC_FRONT);
6037                                 }
6038                         }
6039                 }
6040         } while (scan_tidmask);
6041         return;
6042 }
6043
6044 #ifdef CONFIG_PROC_FS
6045 /*
6046  * asc_prt_board_devices()
6047  *
6048  * Print driver information for devices attached to the board.
6049  *
6050  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6051  * cf. asc_prt_line().
6052  *
6053  * Return the number of characters copied into 'cp'. No more than
6054  * 'cplen' characters will be copied to 'cp'.
6055  */
6056 static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
6057 {
6058         asc_board_t *boardp;
6059         int leftlen;
6060         int totlen;
6061         int len;
6062         int chip_scsi_id;
6063         int i;
6064
6065         boardp = ASC_BOARDP(shost);
6066         leftlen = cplen;
6067         totlen = len = 0;
6068
6069         len = asc_prt_line(cp, leftlen,
6070                            "\nDevice Information for AdvanSys SCSI Host %d:\n",
6071                            shost->host_no);
6072         ASC_PRT_NEXT();
6073
6074         if (ASC_NARROW_BOARD(boardp)) {
6075                 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6076         } else {
6077                 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6078         }
6079
6080         len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
6081         ASC_PRT_NEXT();
6082         for (i = 0; i <= ADV_MAX_TID; i++) {
6083                 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
6084                         len = asc_prt_line(cp, leftlen, " %X,", i);
6085                         ASC_PRT_NEXT();
6086                 }
6087         }
6088         len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
6089         ASC_PRT_NEXT();
6090
6091         return totlen;
6092 }
6093
6094 /*
6095  * Display Wide Board BIOS Information.
6096  */
6097 static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
6098 {
6099         asc_board_t *boardp;
6100         int leftlen;
6101         int totlen;
6102         int len;
6103         ushort major, minor, letter;
6104
6105         boardp = ASC_BOARDP(shost);
6106         leftlen = cplen;
6107         totlen = len = 0;
6108
6109         len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
6110         ASC_PRT_NEXT();
6111
6112         /*
6113          * If the BIOS saved a valid signature, then fill in
6114          * the BIOS code segment base address.
6115          */
6116         if (boardp->bios_signature != 0x55AA) {
6117                 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
6118                 ASC_PRT_NEXT();
6119                 len = asc_prt_line(cp, leftlen,
6120                                    "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
6121                 ASC_PRT_NEXT();
6122                 len = asc_prt_line(cp, leftlen,
6123                                    "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
6124                 ASC_PRT_NEXT();
6125         } else {
6126                 major = (boardp->bios_version >> 12) & 0xF;
6127                 minor = (boardp->bios_version >> 8) & 0xF;
6128                 letter = (boardp->bios_version & 0xFF);
6129
6130                 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
6131                                    major, minor,
6132                                    letter >= 26 ? '?' : letter + 'A');
6133                 ASC_PRT_NEXT();
6134
6135                 /*
6136                  * Current available ROM BIOS release is 3.1I for UW
6137                  * and 3.2I for U2W. This code doesn't differentiate
6138                  * UW and U2W boards.
6139                  */
6140                 if (major < 3 || (major <= 3 && minor < 1) ||
6141                     (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
6142                         len = asc_prt_line(cp, leftlen,
6143                                            "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
6144                         ASC_PRT_NEXT();
6145                         len = asc_prt_line(cp, leftlen,
6146                                            "ftp://ftp.connectcom.net/pub\n");
6147                         ASC_PRT_NEXT();
6148                 }
6149         }
6150
6151         return totlen;
6152 }
6153
6154 /*
6155  * Add serial number to information bar if signature AAh
6156  * is found in at bit 15-9 (7 bits) of word 1.
6157  *
6158  * Serial Number consists fo 12 alpha-numeric digits.
6159  *
6160  *       1 - Product type (A,B,C,D..)  Word0: 15-13 (3 bits)
6161  *       2 - MFG Location (A,B,C,D..)  Word0: 12-10 (3 bits)
6162  *     3-4 - Product ID (0-99)         Word0: 9-0 (10 bits)
6163  *       5 - Product revision (A-J)    Word0:  "         "
6164  *
6165  *           Signature                 Word1: 15-9 (7 bits)
6166  *       6 - Year (0-9)                Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
6167  *     7-8 - Week of the year (1-52)   Word1: 5-0 (6 bits)
6168  *
6169  *    9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
6170  *
6171  * Note 1: Only production cards will have a serial number.
6172  *
6173  * Note 2: Signature is most significant 7 bits (0xFE).
6174  *
6175  * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
6176  */
6177 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
6178 {
6179         ushort w, num;
6180
6181         if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
6182                 return ASC_FALSE;
6183         } else {
6184                 /*
6185                  * First word - 6 digits.
6186                  */
6187                 w = serialnum[0];
6188
6189                 /* Product type - 1st digit. */
6190                 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
6191                         /* Product type is P=Prototype */
6192                         *cp += 0x8;
6193                 }
6194                 cp++;
6195
6196                 /* Manufacturing location - 2nd digit. */
6197                 *cp++ = 'A' + ((w & 0x1C00) >> 10);
6198
6199                 /* Product ID - 3rd, 4th digits. */
6200                 num = w & 0x3FF;
6201                 *cp++ = '0' + (num / 100);
6202                 num %= 100;
6203                 *cp++ = '0' + (num / 10);
6204
6205                 /* Product revision - 5th digit. */
6206                 *cp++ = 'A' + (num % 10);
6207
6208                 /*
6209                  * Second word
6210                  */
6211                 w = serialnum[1];
6212
6213                 /*
6214                  * Year - 6th digit.
6215                  *
6216                  * If bit 15 of third word is set, then the
6217                  * last digit of the year is greater than 7.
6218                  */
6219                 if (serialnum[2] & 0x8000) {
6220                         *cp++ = '8' + ((w & 0x1C0) >> 6);
6221                 } else {
6222                         *cp++ = '0' + ((w & 0x1C0) >> 6);
6223                 }
6224
6225                 /* Week of year - 7th, 8th digits. */
6226                 num = w & 0x003F;
6227                 *cp++ = '0' + num / 10;
6228                 num %= 10;
6229                 *cp++ = '0' + num;
6230
6231                 /*
6232                  * Third word
6233                  */
6234                 w = serialnum[2] & 0x7FFF;
6235
6236                 /* Serial number - 9th digit. */
6237                 *cp++ = 'A' + (w / 1000);
6238
6239                 /* 10th, 11th, 12th digits. */
6240                 num = w % 1000;
6241                 *cp++ = '0' + num / 100;
6242                 num %= 100;
6243                 *cp++ = '0' + num / 10;
6244                 num %= 10;
6245                 *cp++ = '0' + num;
6246
6247                 *cp = '\0';     /* Null Terminate the string. */
6248                 return ASC_TRUE;
6249         }
6250 }
6251
6252 /*
6253  * asc_prt_asc_board_eeprom()
6254  *
6255  * Print board EEPROM configuration.
6256  *
6257  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6258  * cf. asc_prt_line().
6259  *
6260  * Return the number of characters copied into 'cp'. No more than
6261  * 'cplen' characters will be copied to 'cp'.
6262  */
6263 static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
6264 {
6265         asc_board_t *boardp;
6266         ASC_DVC_VAR *asc_dvc_varp;
6267         int leftlen;
6268         int totlen;
6269         int len;
6270         ASCEEP_CONFIG *ep;
6271         int i;
6272 #ifdef CONFIG_ISA
6273         int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
6274 #endif /* CONFIG_ISA */
6275         uchar serialstr[13];
6276
6277         boardp = ASC_BOARDP(shost);
6278         asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6279         ep = &boardp->eep_config.asc_eep;
6280
6281         leftlen = cplen;
6282         totlen = len = 0;
6283
6284         len = asc_prt_line(cp, leftlen,
6285                            "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6286                            shost->host_no);
6287         ASC_PRT_NEXT();
6288
6289         if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
6290             == ASC_TRUE) {
6291                 len =
6292                     asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6293                                  serialstr);
6294                 ASC_PRT_NEXT();
6295         } else {
6296                 if (ep->adapter_info[5] == 0xBB) {
6297                         len = asc_prt_line(cp, leftlen,
6298                                            " Default Settings Used for EEPROM-less Adapter.\n");
6299                         ASC_PRT_NEXT();
6300                 } else {
6301                         len = asc_prt_line(cp, leftlen,
6302                                            " Serial Number Signature Not Present.\n");
6303                         ASC_PRT_NEXT();
6304                 }
6305         }
6306
6307         len = asc_prt_line(cp, leftlen,
6308                            " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6309                            ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
6310                            ep->max_tag_qng);
6311         ASC_PRT_NEXT();
6312
6313         len = asc_prt_line(cp, leftlen,
6314                            " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
6315         ASC_PRT_NEXT();
6316
6317         len = asc_prt_line(cp, leftlen, " Target ID:           ");
6318         ASC_PRT_NEXT();
6319         for (i = 0; i <= ASC_MAX_TID; i++) {
6320                 len = asc_prt_line(cp, leftlen, " %d", i);
6321                 ASC_PRT_NEXT();
6322         }
6323         len = asc_prt_line(cp, leftlen, "\n");
6324         ASC_PRT_NEXT();
6325
6326         len = asc_prt_line(cp, leftlen, " Disconnects:         ");
6327         ASC_PRT_NEXT();
6328         for (i = 0; i <= ASC_MAX_TID; i++) {
6329                 len = asc_prt_line(cp, leftlen, " %c",
6330                                    (ep->
6331                                     disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6332                                    'N');
6333                 ASC_PRT_NEXT();
6334         }
6335         len = asc_prt_line(cp, leftlen, "\n");
6336         ASC_PRT_NEXT();
6337
6338         len = asc_prt_line(cp, leftlen, " Command Queuing:     ");
6339         ASC_PRT_NEXT();
6340         for (i = 0; i <= ASC_MAX_TID; i++) {
6341                 len = asc_prt_line(cp, leftlen, " %c",
6342                                    (ep->
6343                                     use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6344                                    'N');
6345                 ASC_PRT_NEXT();
6346         }
6347         len = asc_prt_line(cp, leftlen, "\n");
6348         ASC_PRT_NEXT();
6349
6350         len = asc_prt_line(cp, leftlen, " Start Motor:         ");
6351         ASC_PRT_NEXT();
6352         for (i = 0; i <= ASC_MAX_TID; i++) {
6353                 len = asc_prt_line(cp, leftlen, " %c",
6354                                    (ep->
6355                                     start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6356                                    'N');
6357                 ASC_PRT_NEXT();
6358         }
6359         len = asc_prt_line(cp, leftlen, "\n");
6360         ASC_PRT_NEXT();
6361
6362         len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6363         ASC_PRT_NEXT();
6364         for (i = 0; i <= ASC_MAX_TID; i++) {
6365                 len = asc_prt_line(cp, leftlen, " %c",
6366                                    (ep->
6367                                     init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6368                                    'N');
6369                 ASC_PRT_NEXT();
6370         }
6371         len = asc_prt_line(cp, leftlen, "\n");
6372         ASC_PRT_NEXT();
6373
6374 #ifdef CONFIG_ISA
6375         if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
6376                 len = asc_prt_line(cp, leftlen,
6377                                    " Host ISA DMA speed:   %d MB/S\n",
6378                                    isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
6379                 ASC_PRT_NEXT();
6380         }
6381 #endif /* CONFIG_ISA */
6382
6383         return totlen;
6384 }
6385
6386 /*
6387  * asc_prt_adv_board_eeprom()
6388  *
6389  * Print board EEPROM configuration.
6390  *
6391  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6392  * cf. asc_prt_line().
6393  *
6394  * Return the number of characters copied into 'cp'. No more than
6395  * 'cplen' characters will be copied to 'cp'.
6396  */
6397 static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
6398 {
6399         asc_board_t *boardp;
6400         ADV_DVC_VAR *adv_dvc_varp;
6401         int leftlen;
6402         int totlen;
6403         int len;
6404         int i;
6405         char *termstr;
6406         uchar serialstr[13];
6407         ADVEEP_3550_CONFIG *ep_3550 = NULL;
6408         ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
6409         ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
6410         ushort word;
6411         ushort *wordp;
6412         ushort sdtr_speed = 0;
6413
6414         boardp = ASC_BOARDP(shost);
6415         adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6416         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6417                 ep_3550 = &boardp->eep_config.adv_3550_eep;
6418         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6419                 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
6420         } else {
6421                 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
6422         }
6423
6424         leftlen = cplen;
6425         totlen = len = 0;
6426
6427         len = asc_prt_line(cp, leftlen,
6428                            "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6429                            shost->host_no);
6430         ASC_PRT_NEXT();
6431
6432         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6433                 wordp = &ep_3550->serial_number_word1;
6434         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6435                 wordp = &ep_38C0800->serial_number_word1;
6436         } else {
6437                 wordp = &ep_38C1600->serial_number_word1;
6438         }
6439
6440         if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
6441                 len =
6442                     asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6443                                  serialstr);
6444                 ASC_PRT_NEXT();
6445         } else {
6446                 len = asc_prt_line(cp, leftlen,
6447                                    " Serial Number Signature Not Present.\n");
6448                 ASC_PRT_NEXT();
6449         }
6450
6451         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6452                 len = asc_prt_line(cp, leftlen,
6453                                    " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6454                                    ep_3550->adapter_scsi_id,
6455                                    ep_3550->max_host_qng, ep_3550->max_dvc_qng);
6456                 ASC_PRT_NEXT();
6457         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6458                 len = asc_prt_line(cp, leftlen,
6459                                    " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6460                                    ep_38C0800->adapter_scsi_id,
6461                                    ep_38C0800->max_host_qng,
6462                                    ep_38C0800->max_dvc_qng);
6463                 ASC_PRT_NEXT();
6464         } else {
6465                 len = asc_prt_line(cp, leftlen,
6466                                    " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6467                                    ep_38C1600->adapter_scsi_id,
6468                                    ep_38C1600->max_host_qng,
6469                                    ep_38C1600->max_dvc_qng);
6470                 ASC_PRT_NEXT();
6471         }
6472         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6473                 word = ep_3550->termination;
6474         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6475                 word = ep_38C0800->termination_lvd;
6476         } else {
6477                 word = ep_38C1600->termination_lvd;
6478         }
6479         switch (word) {
6480         case 1:
6481                 termstr = "Low Off/High Off";
6482                 break;
6483         case 2:
6484                 termstr = "Low Off/High On";
6485                 break;
6486         case 3:
6487                 termstr = "Low On/High On";
6488                 break;
6489         default:
6490         case 0:
6491                 termstr = "Automatic";
6492                 break;
6493         }
6494
6495         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6496                 len = asc_prt_line(cp, leftlen,
6497                                    " termination: %u (%s), bios_ctrl: 0x%x\n",
6498                                    ep_3550->termination, termstr,
6499                                    ep_3550->bios_ctrl);
6500                 ASC_PRT_NEXT();
6501         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6502                 len = asc_prt_line(cp, leftlen,
6503                                    " termination: %u (%s), bios_ctrl: 0x%x\n",
6504                                    ep_38C0800->termination_lvd, termstr,
6505                                    ep_38C0800->bios_ctrl);
6506                 ASC_PRT_NEXT();
6507         } else {
6508                 len = asc_prt_line(cp, leftlen,
6509                                    " termination: %u (%s), bios_ctrl: 0x%x\n",
6510                                    ep_38C1600->termination_lvd, termstr,
6511                                    ep_38C1600->bios_ctrl);
6512                 ASC_PRT_NEXT();
6513         }
6514
6515         len = asc_prt_line(cp, leftlen, " Target ID:           ");
6516         ASC_PRT_NEXT();
6517         for (i = 0; i <= ADV_MAX_TID; i++) {
6518                 len = asc_prt_line(cp, leftlen, " %X", i);
6519                 ASC_PRT_NEXT();
6520         }
6521         len = asc_prt_line(cp, leftlen, "\n");
6522         ASC_PRT_NEXT();
6523
6524         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6525                 word = ep_3550->disc_enable;
6526         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6527                 word = ep_38C0800->disc_enable;
6528         } else {
6529                 word = ep_38C1600->disc_enable;
6530         }
6531         len = asc_prt_line(cp, leftlen, " Disconnects:         ");
6532         ASC_PRT_NEXT();
6533         for (i = 0; i <= ADV_MAX_TID; i++) {
6534                 len = asc_prt_line(cp, leftlen, " %c",
6535                                    (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6536                 ASC_PRT_NEXT();
6537         }
6538         len = asc_prt_line(cp, leftlen, "\n");
6539         ASC_PRT_NEXT();
6540
6541         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6542                 word = ep_3550->tagqng_able;
6543         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6544                 word = ep_38C0800->tagqng_able;
6545         } else {
6546                 word = ep_38C1600->tagqng_able;
6547         }
6548         len = asc_prt_line(cp, leftlen, " Command Queuing:     ");
6549         ASC_PRT_NEXT();
6550         for (i = 0; i <= ADV_MAX_TID; i++) {
6551                 len = asc_prt_line(cp, leftlen, " %c",
6552                                    (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6553                 ASC_PRT_NEXT();
6554         }
6555         len = asc_prt_line(cp, leftlen, "\n");
6556         ASC_PRT_NEXT();
6557
6558         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6559                 word = ep_3550->start_motor;
6560         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6561                 word = ep_38C0800->start_motor;
6562         } else {
6563                 word = ep_38C1600->start_motor;
6564         }
6565         len = asc_prt_line(cp, leftlen, " Start Motor:         ");
6566         ASC_PRT_NEXT();
6567         for (i = 0; i <= ADV_MAX_TID; i++) {
6568                 len = asc_prt_line(cp, leftlen, " %c",
6569                                    (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6570                 ASC_PRT_NEXT();
6571         }
6572         len = asc_prt_line(cp, leftlen, "\n");
6573         ASC_PRT_NEXT();
6574
6575         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6576                 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6577                 ASC_PRT_NEXT();
6578                 for (i = 0; i <= ADV_MAX_TID; i++) {
6579                         len = asc_prt_line(cp, leftlen, " %c",
6580                                            (ep_3550->
6581                                             sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
6582                                            'Y' : 'N');
6583                         ASC_PRT_NEXT();
6584                 }
6585                 len = asc_prt_line(cp, leftlen, "\n");
6586                 ASC_PRT_NEXT();
6587         }
6588
6589         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6590                 len = asc_prt_line(cp, leftlen, " Ultra Transfer:      ");
6591                 ASC_PRT_NEXT();
6592                 for (i = 0; i <= ADV_MAX_TID; i++) {
6593                         len = asc_prt_line(cp, leftlen, " %c",
6594                                            (ep_3550->
6595                                             ultra_able & ADV_TID_TO_TIDMASK(i))
6596                                            ? 'Y' : 'N');
6597                         ASC_PRT_NEXT();
6598                 }
6599                 len = asc_prt_line(cp, leftlen, "\n");
6600                 ASC_PRT_NEXT();
6601         }
6602
6603         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6604                 word = ep_3550->wdtr_able;
6605         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6606                 word = ep_38C0800->wdtr_able;
6607         } else {
6608                 word = ep_38C1600->wdtr_able;
6609         }
6610         len = asc_prt_line(cp, leftlen, " Wide Transfer:       ");
6611         ASC_PRT_NEXT();
6612         for (i = 0; i <= ADV_MAX_TID; i++) {
6613                 len = asc_prt_line(cp, leftlen, " %c",
6614                                    (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6615                 ASC_PRT_NEXT();
6616         }
6617         len = asc_prt_line(cp, leftlen, "\n");
6618         ASC_PRT_NEXT();
6619
6620         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
6621             adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
6622                 len = asc_prt_line(cp, leftlen,
6623                                    " Synchronous Transfer Speed (Mhz):\n  ");
6624                 ASC_PRT_NEXT();
6625                 for (i = 0; i <= ADV_MAX_TID; i++) {
6626                         char *speed_str;
6627
6628                         if (i == 0) {
6629                                 sdtr_speed = adv_dvc_varp->sdtr_speed1;
6630                         } else if (i == 4) {
6631                                 sdtr_speed = adv_dvc_varp->sdtr_speed2;
6632                         } else if (i == 8) {
6633                                 sdtr_speed = adv_dvc_varp->sdtr_speed3;
6634                         } else if (i == 12) {
6635                                 sdtr_speed = adv_dvc_varp->sdtr_speed4;
6636                         }
6637                         switch (sdtr_speed & ADV_MAX_TID) {
6638                         case 0:
6639                                 speed_str = "Off";
6640                                 break;
6641                         case 1:
6642                                 speed_str = "  5";
6643                                 break;
6644                         case 2:
6645                                 speed_str = " 10";
6646                                 break;
6647                         case 3:
6648                                 speed_str = " 20";
6649                                 break;
6650                         case 4:
6651                                 speed_str = " 40";
6652                                 break;
6653                         case 5:
6654                                 speed_str = " 80";
6655                                 break;
6656                         default:
6657                                 speed_str = "Unk";
6658                                 break;
6659                         }
6660                         len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
6661                         ASC_PRT_NEXT();
6662                         if (i == 7) {
6663                                 len = asc_prt_line(cp, leftlen, "\n  ");
6664                                 ASC_PRT_NEXT();
6665                         }
6666                         sdtr_speed >>= 4;
6667                 }
6668                 len = asc_prt_line(cp, leftlen, "\n");
6669                 ASC_PRT_NEXT();
6670         }
6671
6672         return totlen;
6673 }
6674
6675 /*
6676  * asc_prt_driver_conf()
6677  *
6678  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6679  * cf. asc_prt_line().
6680  *
6681  * Return the number of characters copied into 'cp'. No more than
6682  * 'cplen' characters will be copied to 'cp'.
6683  */
6684 static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
6685 {
6686         asc_board_t *boardp;
6687         int leftlen;
6688         int totlen;
6689         int len;
6690         int chip_scsi_id;
6691
6692         boardp = ASC_BOARDP(shost);
6693
6694         leftlen = cplen;
6695         totlen = len = 0;
6696
6697         len = asc_prt_line(cp, leftlen,
6698                            "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
6699                            shost->host_no);
6700         ASC_PRT_NEXT();
6701
6702         len = asc_prt_line(cp, leftlen,
6703                            " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
6704                            shost->host_busy, shost->last_reset, shost->max_id,
6705                            shost->max_lun, shost->max_channel);
6706         ASC_PRT_NEXT();
6707
6708         len = asc_prt_line(cp, leftlen,
6709                            " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
6710                            shost->unique_id, shost->can_queue, shost->this_id,
6711                            shost->sg_tablesize, shost->cmd_per_lun);
6712         ASC_PRT_NEXT();
6713
6714         len = asc_prt_line(cp, leftlen,
6715                            " unchecked_isa_dma %d, use_clustering %d\n",
6716                            shost->unchecked_isa_dma, shost->use_clustering);
6717         ASC_PRT_NEXT();
6718
6719         len = asc_prt_line(cp, leftlen,
6720                            " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
6721                            boardp->flags, boardp->last_reset, jiffies,
6722                            boardp->asc_n_io_port);
6723         ASC_PRT_NEXT();
6724
6725         /* 'shost->n_io_port' may be truncated because it is only one byte. */
6726         len = asc_prt_line(cp, leftlen,
6727                            " io_port 0x%x, n_io_port 0x%x\n",
6728                            shost->io_port, shost->n_io_port);
6729         ASC_PRT_NEXT();
6730
6731         if (ASC_NARROW_BOARD(boardp)) {
6732                 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6733         } else {
6734                 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6735         }
6736
6737         return totlen;
6738 }
6739
6740 /*
6741  * asc_prt_asc_board_info()
6742  *
6743  * Print dynamic board configuration information.
6744  *
6745  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6746  * cf. asc_prt_line().
6747  *
6748  * Return the number of characters copied into 'cp'. No more than
6749  * 'cplen' characters will be copied to 'cp'.
6750  */
6751 static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
6752 {
6753         asc_board_t *boardp;
6754         int chip_scsi_id;
6755         int leftlen;
6756         int totlen;
6757         int len;
6758         ASC_DVC_VAR *v;
6759         ASC_DVC_CFG *c;
6760         int i;
6761         int renegotiate = 0;
6762
6763         boardp = ASC_BOARDP(shost);
6764         v = &boardp->dvc_var.asc_dvc_var;
6765         c = &boardp->dvc_cfg.asc_dvc_cfg;
6766         chip_scsi_id = c->chip_scsi_id;
6767
6768         leftlen = cplen;
6769         totlen = len = 0;
6770
6771         len = asc_prt_line(cp, leftlen,
6772                            "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6773                            shost->host_no);
6774         ASC_PRT_NEXT();
6775
6776         len = asc_prt_line(cp, leftlen,
6777                            " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
6778                            c->chip_version, c->lib_version, c->lib_serial_no,
6779                            c->mcode_date);
6780         ASC_PRT_NEXT();
6781
6782         len = asc_prt_line(cp, leftlen,
6783                            " mcode_version 0x%x, err_code %u\n",
6784                            c->mcode_version, v->err_code);
6785         ASC_PRT_NEXT();
6786
6787         /* Current number of commands waiting for the host. */
6788         len = asc_prt_line(cp, leftlen,
6789                            " Total Command Pending: %d\n", v->cur_total_qng);
6790         ASC_PRT_NEXT();
6791
6792         len = asc_prt_line(cp, leftlen, " Command Queuing:");
6793         ASC_PRT_NEXT();
6794         for (i = 0; i <= ASC_MAX_TID; i++) {
6795                 if ((chip_scsi_id == i) ||
6796                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6797                         continue;
6798                 }
6799                 len = asc_prt_line(cp, leftlen, " %X:%c",
6800                                    i,
6801                                    (v->
6802                                     use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
6803                                    'Y' : 'N');
6804                 ASC_PRT_NEXT();
6805         }
6806         len = asc_prt_line(cp, leftlen, "\n");
6807         ASC_PRT_NEXT();
6808
6809         /* Current number of commands waiting for a device. */
6810         len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
6811         ASC_PRT_NEXT();
6812         for (i = 0; i <= ASC_MAX_TID; i++) {
6813                 if ((chip_scsi_id == i) ||
6814                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6815                         continue;
6816                 }
6817                 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
6818                 ASC_PRT_NEXT();
6819         }
6820         len = asc_prt_line(cp, leftlen, "\n");
6821         ASC_PRT_NEXT();
6822
6823         /* Current limit on number of commands that can be sent to a device. */
6824         len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
6825         ASC_PRT_NEXT();
6826         for (i = 0; i <= ASC_MAX_TID; i++) {
6827                 if ((chip_scsi_id == i) ||
6828                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6829                         continue;
6830                 }
6831                 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
6832                 ASC_PRT_NEXT();
6833         }
6834         len = asc_prt_line(cp, leftlen, "\n");
6835         ASC_PRT_NEXT();
6836
6837         /* Indicate whether the device has returned queue full status. */
6838         len = asc_prt_line(cp, leftlen, " Command Queue Full:");
6839         ASC_PRT_NEXT();
6840         for (i = 0; i <= ASC_MAX_TID; i++) {
6841                 if ((chip_scsi_id == i) ||
6842                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6843                         continue;
6844                 }
6845                 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
6846                         len = asc_prt_line(cp, leftlen, " %X:Y-%d",
6847                                            i, boardp->queue_full_cnt[i]);
6848                 } else {
6849                         len = asc_prt_line(cp, leftlen, " %X:N", i);
6850                 }
6851                 ASC_PRT_NEXT();
6852         }
6853         len = asc_prt_line(cp, leftlen, "\n");
6854         ASC_PRT_NEXT();
6855
6856         len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6857         ASC_PRT_NEXT();
6858         for (i = 0; i <= ASC_MAX_TID; i++) {
6859                 if ((chip_scsi_id == i) ||
6860                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6861                         continue;
6862                 }
6863                 len = asc_prt_line(cp, leftlen, " %X:%c",
6864                                    i,
6865                                    (v->
6866                                     sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6867                                    'N');
6868                 ASC_PRT_NEXT();
6869         }
6870         len = asc_prt_line(cp, leftlen, "\n");
6871         ASC_PRT_NEXT();
6872
6873         for (i = 0; i <= ASC_MAX_TID; i++) {
6874                 uchar syn_period_ix;
6875
6876                 if ((chip_scsi_id == i) ||
6877                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
6878                     ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
6879                         continue;
6880                 }
6881
6882                 len = asc_prt_line(cp, leftlen, "  %X:", i);
6883                 ASC_PRT_NEXT();
6884
6885                 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
6886                         len = asc_prt_line(cp, leftlen, " Asynchronous");
6887                         ASC_PRT_NEXT();
6888                 } else {
6889                         syn_period_ix =
6890                             (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
6891                                                            1);
6892
6893                         len = asc_prt_line(cp, leftlen,
6894                                            " Transfer Period Factor: %d (%d.%d Mhz),",
6895                                            v->sdtr_period_tbl[syn_period_ix],
6896                                            250 /
6897                                            v->sdtr_period_tbl[syn_period_ix],
6898                                            ASC_TENTHS(250,
6899                                                       v->
6900                                                       sdtr_period_tbl
6901                                                       [syn_period_ix]));
6902                         ASC_PRT_NEXT();
6903
6904                         len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
6905                                            boardp->
6906                                            sdtr_data[i] & ASC_SYN_MAX_OFFSET);
6907                         ASC_PRT_NEXT();
6908                 }
6909
6910                 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
6911                         len = asc_prt_line(cp, leftlen, "*\n");
6912                         renegotiate = 1;
6913                 } else {
6914                         len = asc_prt_line(cp, leftlen, "\n");
6915                 }
6916                 ASC_PRT_NEXT();
6917         }
6918
6919         if (renegotiate) {
6920                 len = asc_prt_line(cp, leftlen,
6921                                    " * = Re-negotiation pending before next command.\n");
6922                 ASC_PRT_NEXT();
6923         }
6924
6925         return totlen;
6926 }
6927
6928 /*
6929  * asc_prt_adv_board_info()
6930  *
6931  * Print dynamic board configuration information.
6932  *
6933  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6934  * cf. asc_prt_line().
6935  *
6936  * Return the number of characters copied into 'cp'. No more than
6937  * 'cplen' characters will be copied to 'cp'.
6938  */
6939 static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
6940 {
6941         asc_board_t *boardp;
6942         int leftlen;
6943         int totlen;
6944         int len;
6945         int i;
6946         ADV_DVC_VAR *v;
6947         ADV_DVC_CFG *c;
6948         AdvPortAddr iop_base;
6949         ushort chip_scsi_id;
6950         ushort lramword;
6951         uchar lrambyte;
6952         ushort tagqng_able;
6953         ushort sdtr_able, wdtr_able;
6954         ushort wdtr_done, sdtr_done;
6955         ushort period = 0;
6956         int renegotiate = 0;
6957
6958         boardp = ASC_BOARDP(shost);
6959         v = &boardp->dvc_var.adv_dvc_var;
6960         c = &boardp->dvc_cfg.adv_dvc_cfg;
6961         iop_base = v->iop_base;
6962         chip_scsi_id = v->chip_scsi_id;
6963
6964         leftlen = cplen;
6965         totlen = len = 0;
6966
6967         len = asc_prt_line(cp, leftlen,
6968                            "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6969                            shost->host_no);
6970         ASC_PRT_NEXT();
6971
6972         len = asc_prt_line(cp, leftlen,
6973                            " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
6974                            v->iop_base,
6975                            AdvReadWordRegister(iop_base,
6976                                                IOPW_SCSI_CFG1) & CABLE_DETECT,
6977                            v->err_code);
6978         ASC_PRT_NEXT();
6979
6980         len = asc_prt_line(cp, leftlen,
6981                            " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
6982                            c->chip_version, c->lib_version, c->mcode_date,
6983                            c->mcode_version);
6984         ASC_PRT_NEXT();
6985
6986         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
6987         len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
6988         ASC_PRT_NEXT();
6989         for (i = 0; i <= ADV_MAX_TID; i++) {
6990                 if ((chip_scsi_id == i) ||
6991                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6992                         continue;
6993                 }
6994
6995                 len = asc_prt_line(cp, leftlen, " %X:%c",
6996                                    i,
6997                                    (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6998                                    'N');
6999                 ASC_PRT_NEXT();
7000         }
7001         len = asc_prt_line(cp, leftlen, "\n");
7002         ASC_PRT_NEXT();
7003
7004         len = asc_prt_line(cp, leftlen, " Queue Limit:");
7005         ASC_PRT_NEXT();
7006         for (i = 0; i <= ADV_MAX_TID; i++) {
7007                 if ((chip_scsi_id == i) ||
7008                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7009                         continue;
7010                 }
7011
7012                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
7013                                 lrambyte);
7014
7015                 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
7016                 ASC_PRT_NEXT();
7017         }
7018         len = asc_prt_line(cp, leftlen, "\n");
7019         ASC_PRT_NEXT();
7020
7021         len = asc_prt_line(cp, leftlen, " Command Pending:");
7022         ASC_PRT_NEXT();
7023         for (i = 0; i <= ADV_MAX_TID; i++) {
7024                 if ((chip_scsi_id == i) ||
7025                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7026                         continue;
7027                 }
7028
7029                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
7030                                 lrambyte);
7031
7032                 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
7033                 ASC_PRT_NEXT();
7034         }
7035         len = asc_prt_line(cp, leftlen, "\n");
7036         ASC_PRT_NEXT();
7037
7038         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7039         len = asc_prt_line(cp, leftlen, " Wide Enabled:");
7040         ASC_PRT_NEXT();
7041         for (i = 0; i <= ADV_MAX_TID; i++) {
7042                 if ((chip_scsi_id == i) ||
7043                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7044                         continue;
7045                 }
7046
7047                 len = asc_prt_line(cp, leftlen, " %X:%c",
7048                                    i,
7049                                    (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7050                                    'N');
7051                 ASC_PRT_NEXT();
7052         }
7053         len = asc_prt_line(cp, leftlen, "\n");
7054         ASC_PRT_NEXT();
7055
7056         AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
7057         len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
7058         ASC_PRT_NEXT();
7059         for (i = 0; i <= ADV_MAX_TID; i++) {
7060                 if ((chip_scsi_id == i) ||
7061                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7062                         continue;
7063                 }
7064
7065                 AdvReadWordLram(iop_base,
7066                                 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7067                                 lramword);
7068
7069                 len = asc_prt_line(cp, leftlen, " %X:%d",
7070                                    i, (lramword & 0x8000) ? 16 : 8);
7071                 ASC_PRT_NEXT();
7072
7073                 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
7074                     (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7075                         len = asc_prt_line(cp, leftlen, "*");
7076                         ASC_PRT_NEXT();
7077                         renegotiate = 1;
7078                 }
7079         }
7080         len = asc_prt_line(cp, leftlen, "\n");
7081         ASC_PRT_NEXT();
7082
7083         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7084         len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
7085         ASC_PRT_NEXT();
7086         for (i = 0; i <= ADV_MAX_TID; i++) {
7087                 if ((chip_scsi_id == i) ||
7088                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7089                         continue;
7090                 }
7091
7092                 len = asc_prt_line(cp, leftlen, " %X:%c",
7093                                    i,
7094                                    (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7095                                    'N');
7096                 ASC_PRT_NEXT();
7097         }
7098         len = asc_prt_line(cp, leftlen, "\n");
7099         ASC_PRT_NEXT();
7100
7101         AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
7102         for (i = 0; i <= ADV_MAX_TID; i++) {
7103
7104                 AdvReadWordLram(iop_base,
7105                                 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7106                                 lramword);
7107                 lramword &= ~0x8000;
7108
7109                 if ((chip_scsi_id == i) ||
7110                     ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
7111                     ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
7112                         continue;
7113                 }
7114
7115                 len = asc_prt_line(cp, leftlen, "  %X:", i);
7116                 ASC_PRT_NEXT();
7117
7118                 if ((lramword & 0x1F) == 0) {   /* Check for REQ/ACK Offset 0. */
7119                         len = asc_prt_line(cp, leftlen, " Asynchronous");
7120                         ASC_PRT_NEXT();
7121                 } else {
7122                         len =
7123                             asc_prt_line(cp, leftlen,
7124                                          " Transfer Period Factor: ");
7125                         ASC_PRT_NEXT();
7126
7127                         if ((lramword & 0x1F00) == 0x1100) {    /* 80 Mhz */
7128                                 len =
7129                                     asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
7130                                 ASC_PRT_NEXT();
7131                         } else if ((lramword & 0x1F00) == 0x1000) {     /* 40 Mhz */
7132                                 len =
7133                                     asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
7134                                 ASC_PRT_NEXT();
7135                         } else {        /* 20 Mhz or below. */
7136
7137                                 period = (((lramword >> 8) * 25) + 50) / 4;
7138
7139                                 if (period == 0) {      /* Should never happen. */
7140                                         len =
7141                                             asc_prt_line(cp, leftlen,
7142                                                          "%d (? Mhz), ");
7143                                         ASC_PRT_NEXT();
7144                                 } else {
7145                                         len = asc_prt_line(cp, leftlen,
7146                                                            "%d (%d.%d Mhz),",
7147                                                            period, 250 / period,
7148                                                            ASC_TENTHS(250,
7149                                                                       period));
7150                                         ASC_PRT_NEXT();
7151                                 }
7152                         }
7153
7154                         len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
7155                                            lramword & 0x1F);
7156                         ASC_PRT_NEXT();
7157                 }
7158
7159                 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7160                         len = asc_prt_line(cp, leftlen, "*\n");
7161                         renegotiate = 1;
7162                 } else {
7163                         len = asc_prt_line(cp, leftlen, "\n");
7164                 }
7165                 ASC_PRT_NEXT();
7166         }
7167
7168         if (renegotiate) {
7169                 len = asc_prt_line(cp, leftlen,
7170                                    " * = Re-negotiation pending before next command.\n");
7171                 ASC_PRT_NEXT();
7172         }
7173
7174         return totlen;
7175 }
7176
7177 /*
7178  * asc_proc_copy()
7179  *
7180  * Copy proc information to a read buffer taking into account the current
7181  * read offset in the file and the remaining space in the read buffer.
7182  */
7183 static int
7184 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
7185               char *cp, int cplen)
7186 {
7187         int cnt = 0;
7188
7189         ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
7190                  (unsigned)offset, (unsigned)advoffset, cplen);
7191         if (offset <= advoffset) {
7192                 /* Read offset below current offset, copy everything. */
7193                 cnt = min(cplen, leftlen);
7194                 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7195                          (ulong)curbuf, (ulong)cp, cnt);
7196                 memcpy(curbuf, cp, cnt);
7197         } else if (offset < advoffset + cplen) {
7198                 /* Read offset within current range, partial copy. */
7199                 cnt = (advoffset + cplen) - offset;
7200                 cp = (cp + cplen) - cnt;
7201                 cnt = min(cnt, leftlen);
7202                 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7203                          (ulong)curbuf, (ulong)cp, cnt);
7204                 memcpy(curbuf, cp, cnt);
7205         }
7206         return cnt;
7207 }
7208
7209 /*
7210  * asc_prt_line()
7211  *
7212  * If 'cp' is NULL print to the console, otherwise print to a buffer.
7213  *
7214  * Return 0 if printing to the console, otherwise return the number of
7215  * bytes written to the buffer.
7216  *
7217  * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
7218  * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
7219  */
7220 static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
7221 {
7222         va_list args;
7223         int ret;
7224         char s[ASC_PRTLINE_SIZE];
7225
7226         va_start(args, fmt);
7227         ret = vsprintf(s, fmt, args);
7228         ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
7229         if (buf == NULL) {
7230                 (void)printk(s);
7231                 ret = 0;
7232         } else {
7233                 ret = min(buflen, ret);
7234                 memcpy(buf, s, ret);
7235         }
7236         va_end(args);
7237         return ret;
7238 }
7239 #endif /* CONFIG_PROC_FS */
7240
7241 /*
7242  * --- Functions Required by the Asc Library
7243  */
7244
7245 /*
7246  * Delay for 'n' milliseconds. Don't use the 'jiffies'
7247  * global variable which is incremented once every 5 ms
7248  * from a timer interrupt, because this function may be
7249  * called when interrupts are disabled.
7250  */
7251 static void DvcSleepMilliSecond(ADV_DCNT n)
7252 {
7253         ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong)n);
7254         mdelay(n);
7255 }
7256
7257 /*
7258  * Currently and inline noop but leave as a placeholder.
7259  * Leave DvcEnterCritical() as a noop placeholder.
7260  */
7261 static inline ulong DvcEnterCritical(void)
7262 {
7263         return 0;
7264 }
7265
7266 /*
7267  * Critical sections are all protected by the board spinlock.
7268  * Leave DvcLeaveCritical() as a noop placeholder.
7269  */
7270 static inline void DvcLeaveCritical(ulong flags)
7271 {
7272         return;
7273 }
7274
7275 /*
7276  * void
7277  * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7278  *
7279  * Calling/Exit State:
7280  *    none
7281  *
7282  * Description:
7283  *     Output an ASC_SCSI_Q structure to the chip
7284  */
7285 static void
7286 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7287 {
7288         int i;
7289
7290         ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
7291         AscSetChipLramAddr(iop_base, s_addr);
7292         for (i = 0; i < 2 * words; i += 2) {
7293                 if (i == 4 || i == 20) {
7294                         continue;
7295                 }
7296                 outpw(iop_base + IOP_RAM_DATA,
7297                       ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
7298         }
7299 }
7300
7301 /*
7302  * void
7303  * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7304  *
7305  * Calling/Exit State:
7306  *    none
7307  *
7308  * Description:
7309  *     Input an ASC_QDONE_INFO structure from the chip
7310  */
7311 static void
7312 DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7313 {
7314         int i;
7315         ushort word;
7316
7317         AscSetChipLramAddr(iop_base, s_addr);
7318         for (i = 0; i < 2 * words; i += 2) {
7319                 if (i == 10) {
7320                         continue;
7321                 }
7322                 word = inpw(iop_base + IOP_RAM_DATA);
7323                 inbuf[i] = word & 0xff;
7324                 inbuf[i + 1] = (word >> 8) & 0xff;
7325         }
7326         ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
7327 }
7328
7329 /*
7330  * Read a PCI configuration byte.
7331  */
7332 static uchar __devinit DvcReadPCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset)
7333 {
7334 #ifdef CONFIG_PCI
7335         uchar byte_data;
7336         pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
7337         return byte_data;
7338 #else /* !defined(CONFIG_PCI) */
7339         return 0;
7340 #endif /* !defined(CONFIG_PCI) */
7341 }
7342
7343 /*
7344  * Write a PCI configuration byte.
7345  */
7346 static void __devinit
7347 DvcWritePCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset, uchar byte_data)
7348 {
7349 #ifdef CONFIG_PCI
7350         pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
7351 #endif /* CONFIG_PCI */
7352 }
7353
7354 /*
7355  * Return the BIOS address of the adapter at the specified
7356  * I/O port and with the specified bus type.
7357  */
7358 static ushort __devinit AscGetChipBiosAddress(PortAddr iop_base, ushort bus_type)
7359 {
7360         ushort cfg_lsw;
7361         ushort bios_addr;
7362
7363         /*
7364          * The PCI BIOS is re-located by the motherboard BIOS. Because
7365          * of this the driver can not determine where a PCI BIOS is
7366          * loaded and executes.
7367          */
7368         if (bus_type & ASC_IS_PCI) {
7369                 return (0);
7370         }
7371 #ifdef CONFIG_ISA
7372         if ((bus_type & ASC_IS_EISA) != 0) {
7373                 cfg_lsw = AscGetEisaChipCfg(iop_base);
7374                 cfg_lsw &= 0x000F;
7375                 bios_addr = (ushort)(ASC_BIOS_MIN_ADDR +
7376                                      (cfg_lsw * ASC_BIOS_BANK_SIZE));
7377                 return (bios_addr);
7378         }                       /* if */
7379 #endif /* CONFIG_ISA */
7380
7381         cfg_lsw = AscGetChipCfgLsw(iop_base);
7382
7383         /*
7384          *  ISA PnP uses the top bit as the 32K BIOS flag
7385          */
7386         if (bus_type == ASC_IS_ISAPNP) {
7387                 cfg_lsw &= 0x7FFF;
7388         }
7389         /* if */
7390         bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
7391                              ASC_BIOS_MIN_ADDR);
7392         return (bios_addr);
7393 }
7394
7395 /*
7396  * --- Functions Required by the Adv Library
7397  */
7398
7399 /*
7400  * DvcGetPhyAddr()
7401  *
7402  * Return the physical address of 'vaddr' and set '*lenp' to the
7403  * number of physically contiguous bytes that follow 'vaddr'.
7404  * 'flag' indicates the type of structure whose physical address
7405  * is being translated.
7406  *
7407  * Note: Because Linux currently doesn't page the kernel and all
7408  * kernel buffers are physically contiguous, leave '*lenp' unchanged.
7409  */
7410 ADV_PADDR
7411 DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
7412               uchar *vaddr, ADV_SDCNT *lenp, int flag)
7413 {
7414         ADV_PADDR paddr;
7415
7416         paddr = virt_to_bus(vaddr);
7417
7418         ASC_DBG4(4,
7419                  "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
7420                  (ulong)vaddr, (ulong)lenp, (ulong)*((ulong *)lenp),
7421                  (ulong)paddr);
7422
7423         return paddr;
7424 }
7425
7426 /*
7427  * Read a PCI configuration byte.
7428  */
7429 static uchar __devinit DvcAdvReadPCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset)
7430 {
7431 #ifdef CONFIG_PCI
7432         uchar byte_data;
7433         pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
7434         return byte_data;
7435 #else /* CONFIG_PCI */
7436         return 0;
7437 #endif /* CONFIG_PCI */
7438 }
7439
7440 /*
7441  * Write a PCI configuration byte.
7442  */
7443 static void __devinit
7444 DvcAdvWritePCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset, uchar byte_data)
7445 {
7446 #ifdef CONFIG_PCI
7447         pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
7448 #else /* CONFIG_PCI */
7449         return;
7450 #endif /* CONFIG_PCI */
7451 }
7452
7453 /*
7454  * --- Tracing and Debugging Functions
7455  */
7456
7457 #ifdef ADVANSYS_STATS
7458 #ifdef CONFIG_PROC_FS
7459 /*
7460  * asc_prt_board_stats()
7461  *
7462  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7463  * cf. asc_prt_line().
7464  *
7465  * Return the number of characters copied into 'cp'. No more than
7466  * 'cplen' characters will be copied to 'cp'.
7467  */
7468 static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
7469 {
7470         int leftlen;
7471         int totlen;
7472         int len;
7473         struct asc_stats *s;
7474         asc_board_t *boardp;
7475
7476         leftlen = cplen;
7477         totlen = len = 0;
7478
7479         boardp = ASC_BOARDP(shost);
7480         s = &boardp->asc_stats;
7481
7482         len = asc_prt_line(cp, leftlen,
7483                            "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
7484                            shost->host_no);
7485         ASC_PRT_NEXT();
7486
7487         len = asc_prt_line(cp, leftlen,
7488                            " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
7489                            s->queuecommand, s->reset, s->biosparam,
7490                            s->interrupt);
7491         ASC_PRT_NEXT();
7492
7493         len = asc_prt_line(cp, leftlen,
7494                            " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
7495                            s->callback, s->done, s->build_error,
7496                            s->adv_build_noreq, s->adv_build_nosg);
7497         ASC_PRT_NEXT();
7498
7499         len = asc_prt_line(cp, leftlen,
7500                            " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
7501                            s->exe_noerror, s->exe_busy, s->exe_error,
7502                            s->exe_unknown);
7503         ASC_PRT_NEXT();
7504
7505         /*
7506          * Display data transfer statistics.
7507          */
7508         if (s->cont_cnt > 0) {
7509                 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
7510                 ASC_PRT_NEXT();
7511
7512                 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
7513                                    s->cont_xfer / 2,
7514                                    ASC_TENTHS(s->cont_xfer, 2));
7515                 ASC_PRT_NEXT();
7516
7517                 /* Contiguous transfer average size */
7518                 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
7519                                    (s->cont_xfer / 2) / s->cont_cnt,
7520                                    ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
7521                 ASC_PRT_NEXT();
7522         }
7523
7524         if (s->sg_cnt > 0) {
7525
7526                 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
7527                                    s->sg_cnt, s->sg_elem);
7528                 ASC_PRT_NEXT();
7529
7530                 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
7531                                    s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
7532                 ASC_PRT_NEXT();
7533
7534                 /* Scatter gather transfer statistics */
7535                 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
7536                                    s->sg_elem / s->sg_cnt,
7537                                    ASC_TENTHS(s->sg_elem, s->sg_cnt));
7538                 ASC_PRT_NEXT();
7539
7540                 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
7541                                    (s->sg_xfer / 2) / s->sg_elem,
7542                                    ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
7543                 ASC_PRT_NEXT();
7544
7545                 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
7546                                    (s->sg_xfer / 2) / s->sg_cnt,
7547                                    ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
7548                 ASC_PRT_NEXT();
7549         }
7550
7551         /*
7552          * Display request queuing statistics.
7553          */
7554         len = asc_prt_line(cp, leftlen,
7555                            " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
7556                            HZ);
7557         ASC_PRT_NEXT();
7558
7559         return totlen;
7560 }
7561
7562 /*
7563  * asc_prt_target_stats()
7564  *
7565  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7566  * cf. asc_prt_line().
7567  *
7568  * This is separated from asc_prt_board_stats because a full set
7569  * of targets will overflow ASC_PRTBUF_SIZE.
7570  *
7571  * Return the number of characters copied into 'cp'. No more than
7572  * 'cplen' characters will be copied to 'cp'.
7573  */
7574 static int
7575 asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen)
7576 {
7577         int leftlen;
7578         int totlen;
7579         int len;
7580         struct asc_stats *s;
7581         ushort chip_scsi_id;
7582         asc_board_t *boardp;
7583         asc_queue_t *active;
7584         asc_queue_t *waiting;
7585
7586         leftlen = cplen;
7587         totlen = len = 0;
7588
7589         boardp = ASC_BOARDP(shost);
7590         s = &boardp->asc_stats;
7591
7592         active = &ASC_BOARDP(shost)->active;
7593         waiting = &ASC_BOARDP(shost)->waiting;
7594
7595         if (ASC_NARROW_BOARD(boardp)) {
7596                 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7597         } else {
7598                 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7599         }
7600
7601         if ((chip_scsi_id == tgt_id) ||
7602             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
7603                 return 0;
7604         }
7605
7606         do {
7607                 if (active->q_tot_cnt[tgt_id] > 0
7608                     || waiting->q_tot_cnt[tgt_id] > 0) {
7609                         len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
7610                         ASC_PRT_NEXT();
7611
7612                         len = asc_prt_line(cp, leftlen,
7613                                            "   active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
7614                                            active->q_cur_cnt[tgt_id],
7615                                            active->q_max_cnt[tgt_id],
7616                                            active->q_tot_cnt[tgt_id],
7617                                            active->q_min_tim[tgt_id],
7618                                            active->q_max_tim[tgt_id],
7619                                            (active->q_tot_cnt[tgt_id] ==
7620                                             0) ? 0 : (active->
7621                                                       q_tot_tim[tgt_id] /
7622                                                       active->
7623                                                       q_tot_cnt[tgt_id]),
7624                                            (active->q_tot_cnt[tgt_id] ==
7625                                             0) ? 0 : ASC_TENTHS(active->
7626                                                                 q_tot_tim
7627                                                                 [tgt_id],
7628                                                                 active->
7629                                                                 q_tot_cnt
7630                                                                 [tgt_id]));
7631                         ASC_PRT_NEXT();
7632
7633                         len = asc_prt_line(cp, leftlen,
7634                                            "   waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
7635                                            waiting->q_cur_cnt[tgt_id],
7636                                            waiting->q_max_cnt[tgt_id],
7637                                            waiting->q_tot_cnt[tgt_id],
7638                                            waiting->q_min_tim[tgt_id],
7639                                            waiting->q_max_tim[tgt_id],
7640                                            (waiting->q_tot_cnt[tgt_id] ==
7641                                             0) ? 0 : (waiting->
7642                                                       q_tot_tim[tgt_id] /
7643                                                       waiting->
7644                                                       q_tot_cnt[tgt_id]),
7645                                            (waiting->q_tot_cnt[tgt_id] ==
7646                                             0) ? 0 : ASC_TENTHS(waiting->
7647                                                                 q_tot_tim
7648                                                                 [tgt_id],
7649                                                                 waiting->
7650                                                                 q_tot_cnt
7651                                                                 [tgt_id]));
7652                         ASC_PRT_NEXT();
7653                 }
7654         } while (0);
7655
7656         return totlen;
7657 }
7658 #endif /* CONFIG_PROC_FS */
7659 #endif /* ADVANSYS_STATS */
7660
7661 #ifdef ADVANSYS_DEBUG
7662 /*
7663  * asc_prt_scsi_host()
7664  */
7665 static void asc_prt_scsi_host(struct Scsi_Host *s)
7666 {
7667         asc_board_t *boardp;
7668
7669         boardp = ASC_BOARDP(s);
7670
7671         printk("Scsi_Host at addr 0x%lx\n", (ulong)s);
7672         printk(" host_busy %u, host_no %d, last_reset %d,\n",
7673                s->host_busy, s->host_no, (unsigned)s->last_reset);
7674
7675         printk(" base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
7676                (ulong)s->base, (ulong)s->io_port, s->n_io_port, s->irq);
7677
7678         printk(" dma_channel %d, this_id %d, can_queue %d,\n",
7679                s->dma_channel, s->this_id, s->can_queue);
7680
7681         printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
7682                s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
7683
7684         if (ASC_NARROW_BOARD(boardp)) {
7685                 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
7686                 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
7687         } else {
7688                 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
7689                 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
7690         }
7691 }
7692
7693 /*
7694  * asc_prt_scsi_cmnd()
7695  */
7696 static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
7697 {
7698         printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s);
7699
7700         printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
7701                (ulong)s->device->host, (ulong)s->device, s->device->id,
7702                s->device->lun, s->device->channel);
7703
7704         asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
7705
7706         printk("sc_data_direction %u, resid %d\n",
7707                s->sc_data_direction, s->resid);
7708
7709         printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len);
7710
7711         printk(" serial_number 0x%x, retries %d, allowed %d\n",
7712                (unsigned)s->serial_number, s->retries, s->allowed);
7713
7714         printk(" timeout_per_command %d\n", s->timeout_per_command);
7715
7716         printk
7717             (" scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
7718              (ulong)s->scsi_done, (ulong)s->done, (ulong)s->host_scribble,
7719              s->result);
7720
7721         printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
7722 }
7723
7724 /*
7725  * asc_prt_asc_dvc_var()
7726  */
7727 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
7728 {
7729         printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
7730
7731         printk
7732             (" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n",
7733              h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
7734
7735         printk
7736             (" bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n",
7737              h->bus_type, (ulong)h->isr_callback, (ulong)h->exe_callback,
7738              (unsigned)h->init_sdtr);
7739
7740         printk
7741             (" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n",
7742              (unsigned)h->sdtr_done, (unsigned)h->use_tagged_qng,
7743              (unsigned)h->unit_not_ready, (unsigned)h->chip_no);
7744
7745         printk
7746             (" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n",
7747              (unsigned)h->queue_full_or_busy, (unsigned)h->start_motor,
7748              (unsigned)h->scsi_reset_wait);
7749
7750         printk
7751             (" is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n",
7752              (unsigned)h->is_in_int, (unsigned)h->max_total_qng,
7753              (unsigned)h->cur_total_qng, (unsigned)h->in_critical_cnt);
7754
7755         printk
7756             (" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n",
7757              (unsigned)h->last_q_shortage, (unsigned)h->init_state,
7758              (unsigned)h->no_scam, (unsigned)h->pci_fix_asyn_xfer);
7759
7760         printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no);
7761 }
7762
7763 /*
7764  * asc_prt_asc_dvc_cfg()
7765  */
7766 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
7767 {
7768         printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
7769
7770         printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
7771                h->can_tagged_qng, h->cmd_qng_enabled);
7772         printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
7773                h->disc_enable, h->sdtr_enable);
7774
7775         printk
7776             (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
7777              h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
7778              h->chip_version);
7779
7780         printk
7781             (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
7782              to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
7783              h->mcode_date);
7784
7785         printk(" mcode_version %d, overrun_buf 0x%lx\n",
7786                h->mcode_version, (ulong)h->overrun_buf);
7787 }
7788
7789 /*
7790  * asc_prt_asc_scsi_q()
7791  */
7792 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
7793 {
7794         ASC_SG_HEAD *sgp;
7795         int i;
7796
7797         printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
7798
7799         printk
7800             (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
7801              q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
7802              q->q2.tag_code);
7803
7804         printk
7805             (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7806              (ulong)le32_to_cpu(q->q1.data_addr),
7807              (ulong)le32_to_cpu(q->q1.data_cnt),
7808              (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
7809
7810         printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
7811                (ulong)q->cdbptr, q->q2.cdb_len,
7812                (ulong)q->sg_head, q->q1.sg_queue_cnt);
7813
7814         if (q->sg_head) {
7815                 sgp = q->sg_head;
7816                 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
7817                 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
7818                        sgp->queue_cnt);
7819                 for (i = 0; i < sgp->entry_cnt; i++) {
7820                         printk(" [%u]: addr 0x%lx, bytes %lu\n",
7821                                i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
7822                                (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
7823                 }
7824
7825         }
7826 }
7827
7828 /*
7829  * asc_prt_asc_qdone_info()
7830  */
7831 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
7832 {
7833         printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
7834         printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
7835                (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
7836                q->d2.tag_code);
7837         printk
7838             (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
7839              q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
7840 }
7841
7842 /*
7843  * asc_prt_adv_dvc_var()
7844  *
7845  * Display an ADV_DVC_VAR structure.
7846  */
7847 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
7848 {
7849         printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
7850
7851         printk("  iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
7852                (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
7853
7854         printk("  isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
7855                (ulong)h->isr_callback, (unsigned)h->sdtr_able,
7856                (unsigned)h->wdtr_able);
7857
7858         printk("  start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
7859                (unsigned)h->start_motor,
7860                (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no);
7861
7862         printk("  max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
7863                (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
7864                (ulong)h->carr_freelist);
7865
7866         printk("  icq_sp 0x%lx, irq_sp 0x%lx\n",
7867                (ulong)h->icq_sp, (ulong)h->irq_sp);
7868
7869         printk("  no_scam 0x%x, tagqng_able 0x%x\n",
7870                (unsigned)h->no_scam, (unsigned)h->tagqng_able);
7871
7872         printk("  chip_scsi_id 0x%x, cfg 0x%lx\n",
7873                (unsigned)h->chip_scsi_id, (ulong)h->cfg);
7874 }
7875
7876 /*
7877  * asc_prt_adv_dvc_cfg()
7878  *
7879  * Display an ADV_DVC_CFG structure.
7880  */
7881 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
7882 {
7883         printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
7884
7885         printk("  disc_enable 0x%x, termination 0x%x\n",
7886                h->disc_enable, h->termination);
7887
7888         printk("  chip_version 0x%x, mcode_date 0x%x\n",
7889                h->chip_version, h->mcode_date);
7890
7891         printk("  mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
7892                h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
7893
7894         printk("  control_flag 0x%x, pci_slot_info 0x%x\n",
7895                h->control_flag, h->pci_slot_info);
7896 }
7897
7898 /*
7899  * asc_prt_adv_scsi_req_q()
7900  *
7901  * Display an ADV_SCSI_REQ_Q structure.
7902  */
7903 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
7904 {
7905         int sg_blk_cnt;
7906         struct asc_sg_block *sg_ptr;
7907
7908         printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
7909
7910         printk("  target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
7911                q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
7912
7913         printk("  cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
7914                q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
7915
7916         printk("  data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7917                (ulong)le32_to_cpu(q->data_cnt),
7918                (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
7919
7920         printk
7921             ("  cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
7922              q->cdb_len, q->done_status, q->host_status, q->scsi_status);
7923
7924         printk("  sg_working_ix 0x%x, target_cmd %u\n",
7925                q->sg_working_ix, q->target_cmd);
7926
7927         printk("  scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
7928                (ulong)le32_to_cpu(q->scsiq_rptr),
7929                (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
7930
7931         /* Display the request's ADV_SG_BLOCK structures. */
7932         if (q->sg_list_ptr != NULL) {
7933                 sg_blk_cnt = 0;
7934                 while (1) {
7935                         /*
7936                          * 'sg_ptr' is a physical address. Convert it to a virtual
7937                          * address by indexing 'sg_blk_cnt' into the virtual address
7938                          * array 'sg_list_ptr'.
7939                          *
7940                          * XXX - Assumes all SG physical blocks are virtually contiguous.
7941                          */
7942                         sg_ptr =
7943                             &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
7944                         asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
7945                         if (sg_ptr->sg_ptr == 0) {
7946                                 break;
7947                         }
7948                         sg_blk_cnt++;
7949                 }
7950         }
7951 }
7952
7953 /*
7954  * asc_prt_adv_sgblock()
7955  *
7956  * Display an ADV_SG_BLOCK structure.
7957  */
7958 static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
7959 {
7960         int i;
7961
7962         printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
7963                (ulong)b, sgblockno);
7964         printk("  sg_cnt %u, sg_ptr 0x%lx\n",
7965                b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
7966         ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
7967         if (b->sg_ptr != 0) {
7968                 ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
7969         }
7970         for (i = 0; i < b->sg_cnt; i++) {
7971                 printk("  [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
7972                        i, (ulong)b->sg_list[i].sg_addr,
7973                        (ulong)b->sg_list[i].sg_count);
7974         }
7975 }
7976
7977 /*
7978  * asc_prt_hex()
7979  *
7980  * Print hexadecimal output in 4 byte groupings 32 bytes
7981  * or 8 double-words per line.
7982  */
7983 static void asc_prt_hex(char *f, uchar *s, int l)
7984 {
7985         int i;
7986         int j;
7987         int k;
7988         int m;
7989
7990         printk("%s: (%d bytes)\n", f, l);
7991
7992         for (i = 0; i < l; i += 32) {
7993
7994                 /* Display a maximum of 8 double-words per line. */
7995                 if ((k = (l - i) / 4) >= 8) {
7996                         k = 8;
7997                         m = 0;
7998                 } else {
7999                         m = (l - i) % 4;
8000                 }
8001
8002                 for (j = 0; j < k; j++) {
8003                         printk(" %2.2X%2.2X%2.2X%2.2X",
8004                                (unsigned)s[i + (j * 4)],
8005                                (unsigned)s[i + (j * 4) + 1],
8006                                (unsigned)s[i + (j * 4) + 2],
8007                                (unsigned)s[i + (j * 4) + 3]);
8008                 }
8009
8010                 switch (m) {
8011                 case 0:
8012                 default:
8013                         break;
8014                 case 1:
8015                         printk(" %2.2X", (unsigned)s[i + (j * 4)]);
8016                         break;
8017                 case 2:
8018                         printk(" %2.2X%2.2X",
8019                                (unsigned)s[i + (j * 4)],
8020                                (unsigned)s[i + (j * 4) + 1]);
8021                         break;
8022                 case 3:
8023                         printk(" %2.2X%2.2X%2.2X",
8024                                (unsigned)s[i + (j * 4) + 1],
8025                                (unsigned)s[i + (j * 4) + 2],
8026                                (unsigned)s[i + (j * 4) + 3]);
8027                         break;
8028                 }
8029
8030                 printk("\n");
8031         }
8032 }
8033 #endif /* ADVANSYS_DEBUG */
8034
8035 /*
8036  * --- Asc Library Functions
8037  */
8038
8039 static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
8040 {
8041         PortAddr eisa_cfg_iop;
8042
8043         eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8044             (PortAddr) (ASC_EISA_CFG_IOP_MASK);
8045         return (inpw(eisa_cfg_iop));
8046 }
8047
8048 static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
8049 {
8050         ushort cfg_lsw;
8051
8052         if (AscGetChipScsiID(iop_base) == new_host_id) {
8053                 return (new_host_id);
8054         }
8055         cfg_lsw = AscGetChipCfgLsw(iop_base);
8056         cfg_lsw &= 0xF8FF;
8057         cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
8058         AscSetChipCfgLsw(iop_base, cfg_lsw);
8059         return (AscGetChipScsiID(iop_base));
8060 }
8061
8062 static uchar __devinit AscGetChipScsiCtrl(PortAddr iop_base)
8063 {
8064         uchar sc;
8065
8066         AscSetBank(iop_base, 1);
8067         sc = inp(iop_base + IOP_REG_SC);
8068         AscSetBank(iop_base, 0);
8069         return (sc);
8070 }
8071
8072 static uchar __devinit AscGetChipVersion(PortAddr iop_base, ushort bus_type)
8073 {
8074         if ((bus_type & ASC_IS_EISA) != 0) {
8075                 PortAddr eisa_iop;
8076                 uchar revision;
8077                 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8078                     (PortAddr) ASC_EISA_REV_IOP_MASK;
8079                 revision = inp(eisa_iop);
8080                 return ((uchar)((ASC_CHIP_MIN_VER_EISA - 1) + revision));
8081         }
8082         return (AscGetChipVerNo(iop_base));
8083 }
8084
8085 static ushort __devinit AscGetChipBusType(PortAddr iop_base)
8086 {
8087         ushort chip_ver;
8088
8089         chip_ver = AscGetChipVerNo(iop_base);
8090         if ((chip_ver >= ASC_CHIP_MIN_VER_VL)
8091             && (chip_ver <= ASC_CHIP_MAX_VER_VL)
8092             ) {
8093                 if (((iop_base & 0x0C30) == 0x0C30)
8094                     || ((iop_base & 0x0C50) == 0x0C50)
8095                     ) {
8096                         return (ASC_IS_EISA);
8097                 }
8098                 return (ASC_IS_VL);
8099         }
8100         if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
8101             (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
8102                 if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
8103                         return (ASC_IS_ISAPNP);
8104                 }
8105                 return (ASC_IS_ISA);
8106         } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
8107                    (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
8108                 return (ASC_IS_PCI);
8109         }
8110         return (0);
8111 }
8112
8113 static ASC_DCNT
8114 AscLoadMicroCode(PortAddr iop_base,
8115                  ushort s_addr, uchar *mcode_buf, ushort mcode_size)
8116 {
8117         ASC_DCNT chksum;
8118         ushort mcode_word_size;
8119         ushort mcode_chksum;
8120
8121         /* Write the microcode buffer starting at LRAM address 0. */
8122         mcode_word_size = (ushort)(mcode_size >> 1);
8123         AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
8124         AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
8125
8126         chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
8127         ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum);
8128         mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
8129                                                  (ushort)ASC_CODE_SEC_BEG,
8130                                                  (ushort)((mcode_size -
8131                                                            s_addr - (ushort)
8132                                                            ASC_CODE_SEC_BEG) /
8133                                                           2));
8134         ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
8135                  (ulong)mcode_chksum);
8136         AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
8137         AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
8138         return (chksum);
8139 }
8140
8141 static int AscFindSignature(PortAddr iop_base)
8142 {
8143         ushort sig_word;
8144
8145         ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
8146                  iop_base, AscGetChipSignatureByte(iop_base));
8147         if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
8148                 ASC_DBG2(1,
8149                          "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
8150                          iop_base, AscGetChipSignatureWord(iop_base));
8151                 sig_word = AscGetChipSignatureWord(iop_base);
8152                 if ((sig_word == (ushort)ASC_1000_ID0W) ||
8153                     (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
8154                         return (1);
8155                 }
8156         }
8157         return (0);
8158 }
8159
8160 static void __devinit AscToggleIRQAct(PortAddr iop_base)
8161 {
8162         AscSetChipStatus(iop_base, CIW_IRQ_ACT);
8163         AscSetChipStatus(iop_base, 0);
8164         return;
8165 }
8166
8167 static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
8168 {
8169         ushort cfg_lsw;
8170         uchar chip_irq;
8171
8172         if ((bus_type & ASC_IS_EISA) != 0) {
8173                 cfg_lsw = AscGetEisaChipCfg(iop_base);
8174                 chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10);
8175                 if ((chip_irq == 13) || (chip_irq > 15)) {
8176                         return (0);
8177                 }
8178                 return (chip_irq);
8179         }
8180         if ((bus_type & ASC_IS_VL) != 0) {
8181                 cfg_lsw = AscGetChipCfgLsw(iop_base);
8182                 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07));
8183                 if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) {
8184                         return (0);
8185                 }
8186                 return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1)));
8187         }
8188         cfg_lsw = AscGetChipCfgLsw(iop_base);
8189         chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03));
8190         if (chip_irq == 3)
8191                 chip_irq += (uchar)2;
8192         return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
8193 }
8194
8195 static uchar __devinit
8196 AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
8197 {
8198         ushort cfg_lsw;
8199
8200         if ((bus_type & ASC_IS_VL) != 0) {
8201                 if (irq_no != 0) {
8202                         if ((irq_no < ASC_MIN_IRQ_NO)
8203                             || (irq_no > ASC_MAX_IRQ_NO)) {
8204                                 irq_no = 0;
8205                         } else {
8206                                 irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1));
8207                         }
8208                 }
8209                 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3);
8210                 cfg_lsw |= (ushort)0x0010;
8211                 AscSetChipCfgLsw(iop_base, cfg_lsw);
8212                 AscToggleIRQAct(iop_base);
8213                 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0);
8214                 cfg_lsw |= (ushort)((irq_no & 0x07) << 2);
8215                 AscSetChipCfgLsw(iop_base, cfg_lsw);
8216                 AscToggleIRQAct(iop_base);
8217                 return (AscGetChipIRQ(iop_base, bus_type));
8218         }
8219         if ((bus_type & (ASC_IS_ISA)) != 0) {
8220                 if (irq_no == 15)
8221                         irq_no -= (uchar)2;
8222                 irq_no -= (uchar)ASC_MIN_IRQ_NO;
8223                 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3);
8224                 cfg_lsw |= (ushort)((irq_no & 0x03) << 2);
8225                 AscSetChipCfgLsw(iop_base, cfg_lsw);
8226                 return (AscGetChipIRQ(iop_base, bus_type));
8227         }
8228         return (0);
8229 }
8230
8231 #ifdef CONFIG_ISA
8232 static void __devinit AscEnableIsaDma(uchar dma_channel)
8233 {
8234         if (dma_channel < 4) {
8235                 outp(0x000B, (ushort)(0xC0 | dma_channel));
8236                 outp(0x000A, dma_channel);
8237         } else if (dma_channel < 8) {
8238                 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
8239                 outp(0x00D4, (ushort)(dma_channel - 4));
8240         }
8241         return;
8242 }
8243 #endif /* CONFIG_ISA */
8244
8245 static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
8246 {
8247         EXT_MSG ext_msg;
8248         EXT_MSG out_msg;
8249         ushort halt_q_addr;
8250         int sdtr_accept;
8251         ushort int_halt_code;
8252         ASC_SCSI_BIT_ID_TYPE scsi_busy;
8253         ASC_SCSI_BIT_ID_TYPE target_id;
8254         PortAddr iop_base;
8255         uchar tag_code;
8256         uchar q_status;
8257         uchar halt_qp;
8258         uchar sdtr_data;
8259         uchar target_ix;
8260         uchar q_cntl, tid_no;
8261         uchar cur_dvc_qng;
8262         uchar asyn_sdtr;
8263         uchar scsi_status;
8264         asc_board_t *boardp;
8265
8266         ASC_ASSERT(asc_dvc->drv_ptr != NULL);
8267         boardp = asc_dvc->drv_ptr;
8268
8269         iop_base = asc_dvc->iop_base;
8270         int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
8271
8272         halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
8273         halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
8274         target_ix = AscReadLramByte(iop_base,
8275                                     (ushort)(halt_q_addr +
8276                                              (ushort)ASC_SCSIQ_B_TARGET_IX));
8277         q_cntl =
8278             AscReadLramByte(iop_base,
8279                             (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8280         tid_no = ASC_TIX_TO_TID(target_ix);
8281         target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
8282         if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8283                 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
8284         } else {
8285                 asyn_sdtr = 0;
8286         }
8287         if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
8288                 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8289                         AscSetChipSDTR(iop_base, 0, tid_no);
8290                         boardp->sdtr_data[tid_no] = 0;
8291                 }
8292                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8293                 return (0);
8294         } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
8295                 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8296                         AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8297                         boardp->sdtr_data[tid_no] = asyn_sdtr;
8298                 }
8299                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8300                 return (0);
8301         } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
8302
8303                 AscMemWordCopyPtrFromLram(iop_base,
8304                                           ASCV_MSGIN_BEG,
8305                                           (uchar *)&ext_msg,
8306                                           sizeof(EXT_MSG) >> 1);
8307
8308                 if (ext_msg.msg_type == MS_EXTEND &&
8309                     ext_msg.msg_req == MS_SDTR_CODE &&
8310                     ext_msg.msg_len == MS_SDTR_LEN) {
8311                         sdtr_accept = TRUE;
8312                         if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
8313
8314                                 sdtr_accept = FALSE;
8315                                 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
8316                         }
8317                         if ((ext_msg.xfer_period <
8318                              asc_dvc->sdtr_period_tbl[asc_dvc->
8319                                                       host_init_sdtr_index])
8320                             || (ext_msg.xfer_period >
8321                                 asc_dvc->sdtr_period_tbl[asc_dvc->
8322                                                          max_sdtr_index])) {
8323                                 sdtr_accept = FALSE;
8324                                 ext_msg.xfer_period =
8325                                     asc_dvc->sdtr_period_tbl[asc_dvc->
8326                                                              host_init_sdtr_index];
8327                         }
8328                         if (sdtr_accept) {
8329                                 sdtr_data =
8330                                     AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
8331                                                    ext_msg.req_ack_offset);
8332                                 if ((sdtr_data == 0xFF)) {
8333
8334                                         q_cntl |= QC_MSG_OUT;
8335                                         asc_dvc->init_sdtr &= ~target_id;
8336                                         asc_dvc->sdtr_done &= ~target_id;
8337                                         AscSetChipSDTR(iop_base, asyn_sdtr,
8338                                                        tid_no);
8339                                         boardp->sdtr_data[tid_no] = asyn_sdtr;
8340                                 }
8341                         }
8342                         if (ext_msg.req_ack_offset == 0) {
8343
8344                                 q_cntl &= ~QC_MSG_OUT;
8345                                 asc_dvc->init_sdtr &= ~target_id;
8346                                 asc_dvc->sdtr_done &= ~target_id;
8347                                 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8348                         } else {
8349                                 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
8350
8351                                         q_cntl &= ~QC_MSG_OUT;
8352                                         asc_dvc->sdtr_done |= target_id;
8353                                         asc_dvc->init_sdtr |= target_id;
8354                                         asc_dvc->pci_fix_asyn_xfer &=
8355                                             ~target_id;
8356                                         sdtr_data =
8357                                             AscCalSDTRData(asc_dvc,
8358                                                            ext_msg.xfer_period,
8359                                                            ext_msg.
8360                                                            req_ack_offset);
8361                                         AscSetChipSDTR(iop_base, sdtr_data,
8362                                                        tid_no);
8363                                         boardp->sdtr_data[tid_no] = sdtr_data;
8364                                 } else {
8365
8366                                         q_cntl |= QC_MSG_OUT;
8367                                         AscMsgOutSDTR(asc_dvc,
8368                                                       ext_msg.xfer_period,
8369                                                       ext_msg.req_ack_offset);
8370                                         asc_dvc->pci_fix_asyn_xfer &=
8371                                             ~target_id;
8372                                         sdtr_data =
8373                                             AscCalSDTRData(asc_dvc,
8374                                                            ext_msg.xfer_period,
8375                                                            ext_msg.
8376                                                            req_ack_offset);
8377                                         AscSetChipSDTR(iop_base, sdtr_data,
8378                                                        tid_no);
8379                                         boardp->sdtr_data[tid_no] = sdtr_data;
8380                                         asc_dvc->sdtr_done |= target_id;
8381                                         asc_dvc->init_sdtr |= target_id;
8382                                 }
8383                         }
8384
8385                         AscWriteLramByte(iop_base,
8386                                          (ushort)(halt_q_addr +
8387                                                   (ushort)ASC_SCSIQ_B_CNTL),
8388                                          q_cntl);
8389                         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8390                         return (0);
8391                 } else if (ext_msg.msg_type == MS_EXTEND &&
8392                            ext_msg.msg_req == MS_WDTR_CODE &&
8393                            ext_msg.msg_len == MS_WDTR_LEN) {
8394
8395                         ext_msg.wdtr_width = 0;
8396                         AscMemWordCopyPtrToLram(iop_base,
8397                                                 ASCV_MSGOUT_BEG,
8398                                                 (uchar *)&ext_msg,
8399                                                 sizeof(EXT_MSG) >> 1);
8400                         q_cntl |= QC_MSG_OUT;
8401                         AscWriteLramByte(iop_base,
8402                                          (ushort)(halt_q_addr +
8403                                                   (ushort)ASC_SCSIQ_B_CNTL),
8404                                          q_cntl);
8405                         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8406                         return (0);
8407                 } else {
8408
8409                         ext_msg.msg_type = MESSAGE_REJECT;
8410                         AscMemWordCopyPtrToLram(iop_base,
8411                                                 ASCV_MSGOUT_BEG,
8412                                                 (uchar *)&ext_msg,
8413                                                 sizeof(EXT_MSG) >> 1);
8414                         q_cntl |= QC_MSG_OUT;
8415                         AscWriteLramByte(iop_base,
8416                                          (ushort)(halt_q_addr +
8417                                                   (ushort)ASC_SCSIQ_B_CNTL),
8418                                          q_cntl);
8419                         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8420                         return (0);
8421                 }
8422         } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
8423
8424                 q_cntl |= QC_REQ_SENSE;
8425
8426                 if ((asc_dvc->init_sdtr & target_id) != 0) {
8427
8428                         asc_dvc->sdtr_done &= ~target_id;
8429
8430                         sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8431                         q_cntl |= QC_MSG_OUT;
8432                         AscMsgOutSDTR(asc_dvc,
8433                                       asc_dvc->
8434                                       sdtr_period_tbl[(sdtr_data >> 4) &
8435                                                       (uchar)(asc_dvc->
8436                                                               max_sdtr_index -
8437                                                               1)],
8438                                       (uchar)(sdtr_data & (uchar)
8439                                               ASC_SYN_MAX_OFFSET));
8440                 }
8441
8442                 AscWriteLramByte(iop_base,
8443                                  (ushort)(halt_q_addr +
8444                                           (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8445
8446                 tag_code = AscReadLramByte(iop_base,
8447                                            (ushort)(halt_q_addr + (ushort)
8448                                                     ASC_SCSIQ_B_TAG_CODE));
8449                 tag_code &= 0xDC;
8450                 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
8451                     && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
8452                     ) {
8453
8454                         tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
8455                                      | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
8456
8457                 }
8458                 AscWriteLramByte(iop_base,
8459                                  (ushort)(halt_q_addr +
8460                                           (ushort)ASC_SCSIQ_B_TAG_CODE),
8461                                  tag_code);
8462
8463                 q_status = AscReadLramByte(iop_base,
8464                                            (ushort)(halt_q_addr + (ushort)
8465                                                     ASC_SCSIQ_B_STATUS));
8466                 q_status |= (QS_READY | QS_BUSY);
8467                 AscWriteLramByte(iop_base,
8468                                  (ushort)(halt_q_addr +
8469                                           (ushort)ASC_SCSIQ_B_STATUS),
8470                                  q_status);
8471
8472                 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
8473                 scsi_busy &= ~target_id;
8474                 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8475
8476                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8477                 return (0);
8478         } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
8479
8480                 AscMemWordCopyPtrFromLram(iop_base,
8481                                           ASCV_MSGOUT_BEG,
8482                                           (uchar *)&out_msg,
8483                                           sizeof(EXT_MSG) >> 1);
8484
8485                 if ((out_msg.msg_type == MS_EXTEND) &&
8486                     (out_msg.msg_len == MS_SDTR_LEN) &&
8487                     (out_msg.msg_req == MS_SDTR_CODE)) {
8488
8489                         asc_dvc->init_sdtr &= ~target_id;
8490                         asc_dvc->sdtr_done &= ~target_id;
8491                         AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8492                         boardp->sdtr_data[tid_no] = asyn_sdtr;
8493                 }
8494                 q_cntl &= ~QC_MSG_OUT;
8495                 AscWriteLramByte(iop_base,
8496                                  (ushort)(halt_q_addr +
8497                                           (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8498                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8499                 return (0);
8500         } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
8501
8502                 scsi_status = AscReadLramByte(iop_base,
8503                                               (ushort)((ushort)halt_q_addr +
8504                                                        (ushort)
8505                                                        ASC_SCSIQ_SCSI_STATUS));
8506                 cur_dvc_qng =
8507                     AscReadLramByte(iop_base,
8508                                     (ushort)((ushort)ASC_QADR_BEG +
8509                                              (ushort)target_ix));
8510                 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
8511
8512                         scsi_busy = AscReadLramByte(iop_base,
8513                                                     (ushort)ASCV_SCSIBUSY_B);
8514                         scsi_busy |= target_id;
8515                         AscWriteLramByte(iop_base,
8516                                          (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8517                         asc_dvc->queue_full_or_busy |= target_id;
8518
8519                         if (scsi_status == SAM_STAT_TASK_SET_FULL) {
8520                                 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
8521                                         cur_dvc_qng -= 1;
8522                                         asc_dvc->max_dvc_qng[tid_no] =
8523                                             cur_dvc_qng;
8524
8525                                         AscWriteLramByte(iop_base,
8526                                                          (ushort)((ushort)
8527                                                                   ASCV_MAX_DVC_QNG_BEG
8528                                                                   + (ushort)
8529                                                                   tid_no),
8530                                                          cur_dvc_qng);
8531
8532                                         /*
8533                                          * Set the device queue depth to the number of
8534                                          * active requests when the QUEUE FULL condition
8535                                          * was encountered.
8536                                          */
8537                                         boardp->queue_full |= target_id;
8538                                         boardp->queue_full_cnt[tid_no] =
8539                                             cur_dvc_qng;
8540                                 }
8541                         }
8542                 }
8543                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8544                 return (0);
8545         }
8546 #if CC_VERY_LONG_SG_LIST
8547         else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
8548                 uchar q_no;
8549                 ushort q_addr;
8550                 uchar sg_wk_q_no;
8551                 uchar first_sg_wk_q_no;
8552                 ASC_SCSI_Q *scsiq;      /* Ptr to driver request. */
8553                 ASC_SG_HEAD *sg_head;   /* Ptr to driver SG request. */
8554                 ASC_SG_LIST_Q scsi_sg_q;        /* Structure written to queue. */
8555                 ushort sg_list_dwords;
8556                 ushort sg_entry_cnt;
8557                 uchar next_qp;
8558                 int i;
8559
8560                 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
8561                 if (q_no == ASC_QLINK_END) {
8562                         return (0);
8563                 }
8564
8565                 q_addr = ASC_QNO_TO_QADDR(q_no);
8566
8567                 /*
8568                  * Convert the request's SRB pointer to a host ASC_SCSI_REQ
8569                  * structure pointer using a macro provided by the driver.
8570                  * The ASC_SCSI_REQ pointer provides a pointer to the
8571                  * host ASC_SG_HEAD structure.
8572                  */
8573                 /* Read request's SRB pointer. */
8574                 scsiq = (ASC_SCSI_Q *)
8575                     ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
8576                                                                     (ushort)
8577                                                                     (q_addr +
8578                                                                      ASC_SCSIQ_D_SRBPTR))));
8579
8580                 /*
8581                  * Get request's first and working SG queue.
8582                  */
8583                 sg_wk_q_no = AscReadLramByte(iop_base,
8584                                              (ushort)(q_addr +
8585                                                       ASC_SCSIQ_B_SG_WK_QP));
8586
8587                 first_sg_wk_q_no = AscReadLramByte(iop_base,
8588                                                    (ushort)(q_addr +
8589                                                             ASC_SCSIQ_B_FIRST_SG_WK_QP));
8590
8591                 /*
8592                  * Reset request's working SG queue back to the
8593                  * first SG queue.
8594                  */
8595                 AscWriteLramByte(iop_base,
8596                                  (ushort)(q_addr +
8597                                           (ushort)ASC_SCSIQ_B_SG_WK_QP),
8598                                  first_sg_wk_q_no);
8599
8600                 sg_head = scsiq->sg_head;
8601
8602                 /*
8603                  * Set sg_entry_cnt to the number of SG elements
8604                  * that will be completed on this interrupt.
8605                  *
8606                  * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
8607                  * SG elements. The data_cnt and data_addr fields which
8608                  * add 1 to the SG element capacity are not used when
8609                  * restarting SG handling after a halt.
8610                  */
8611                 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
8612                         sg_entry_cnt = ASC_MAX_SG_LIST - 1;
8613
8614                         /*
8615                          * Keep track of remaining number of SG elements that will
8616                          * need to be handled on the next interrupt.
8617                          */
8618                         scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
8619                 } else {
8620                         sg_entry_cnt = scsiq->remain_sg_entry_cnt;
8621                         scsiq->remain_sg_entry_cnt = 0;
8622                 }
8623
8624                 /*
8625                  * Copy SG elements into the list of allocated SG queues.
8626                  *
8627                  * Last index completed is saved in scsiq->next_sg_index.
8628                  */
8629                 next_qp = first_sg_wk_q_no;
8630                 q_addr = ASC_QNO_TO_QADDR(next_qp);
8631                 scsi_sg_q.sg_head_qp = q_no;
8632                 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
8633                 for (i = 0; i < sg_head->queue_cnt; i++) {
8634                         scsi_sg_q.seq_no = i + 1;
8635                         if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
8636                                 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
8637                                 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
8638                                 /*
8639                                  * After very first SG queue RISC FW uses next
8640                                  * SG queue first element then checks sg_list_cnt
8641                                  * against zero and then decrements, so set
8642                                  * sg_list_cnt 1 less than number of SG elements
8643                                  * in each SG queue.
8644                                  */
8645                                 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
8646                                 scsi_sg_q.sg_cur_list_cnt =
8647                                     ASC_SG_LIST_PER_Q - 1;
8648                         } else {
8649                                 /*
8650                                  * This is the last SG queue in the list of
8651                                  * allocated SG queues. If there are more
8652                                  * SG elements than will fit in the allocated
8653                                  * queues, then set the QCSG_SG_XFER_MORE flag.
8654                                  */
8655                                 if (scsiq->remain_sg_entry_cnt != 0) {
8656                                         scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
8657                                 } else {
8658                                         scsi_sg_q.cntl |= QCSG_SG_XFER_END;
8659                                 }
8660                                 /* equals sg_entry_cnt * 2 */
8661                                 sg_list_dwords = sg_entry_cnt << 1;
8662                                 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
8663                                 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
8664                                 sg_entry_cnt = 0;
8665                         }
8666
8667                         scsi_sg_q.q_no = next_qp;
8668                         AscMemWordCopyPtrToLram(iop_base,
8669                                                 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
8670                                                 (uchar *)&scsi_sg_q,
8671                                                 sizeof(ASC_SG_LIST_Q) >> 1);
8672
8673                         AscMemDWordCopyPtrToLram(iop_base,
8674                                                  q_addr + ASC_SGQ_LIST_BEG,
8675                                                  (uchar *)&sg_head->
8676                                                  sg_list[scsiq->next_sg_index],
8677                                                  sg_list_dwords);
8678
8679                         scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
8680
8681                         /*
8682                          * If the just completed SG queue contained the
8683                          * last SG element, then no more SG queues need
8684                          * to be written.
8685                          */
8686                         if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
8687                                 break;
8688                         }
8689
8690                         next_qp = AscReadLramByte(iop_base,
8691                                                   (ushort)(q_addr +
8692                                                            ASC_SCSIQ_B_FWD));
8693                         q_addr = ASC_QNO_TO_QADDR(next_qp);
8694                 }
8695
8696                 /*
8697                  * Clear the halt condition so the RISC will be restarted
8698                  * after the return.
8699                  */
8700                 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8701                 return (0);
8702         }
8703 #endif /* CC_VERY_LONG_SG_LIST */
8704         return (0);
8705 }
8706
8707 static uchar
8708 _AscCopyLramScsiDoneQ(PortAddr iop_base,
8709                       ushort q_addr,
8710                       ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
8711 {
8712         ushort _val;
8713         uchar sg_queue_cnt;
8714
8715         DvcGetQinfo(iop_base,
8716                     q_addr + ASC_SCSIQ_DONE_INFO_BEG,
8717                     (uchar *)scsiq,
8718                     (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
8719
8720         _val = AscReadLramWord(iop_base,
8721                                (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
8722         scsiq->q_status = (uchar)_val;
8723         scsiq->q_no = (uchar)(_val >> 8);
8724         _val = AscReadLramWord(iop_base,
8725                                (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8726         scsiq->cntl = (uchar)_val;
8727         sg_queue_cnt = (uchar)(_val >> 8);
8728         _val = AscReadLramWord(iop_base,
8729                                (ushort)(q_addr +
8730                                         (ushort)ASC_SCSIQ_B_SENSE_LEN));
8731         scsiq->sense_len = (uchar)_val;
8732         scsiq->extra_bytes = (uchar)(_val >> 8);
8733
8734         /*
8735          * Read high word of remain bytes from alternate location.
8736          */
8737         scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
8738                                                           (ushort)(q_addr +
8739                                                                    (ushort)
8740                                                                    ASC_SCSIQ_W_ALT_DC1)))
8741                                << 16);
8742         /*
8743          * Read low word of remain bytes from original location.
8744          */
8745         scsiq->remain_bytes += AscReadLramWord(iop_base,
8746                                                (ushort)(q_addr + (ushort)
8747                                                         ASC_SCSIQ_DW_REMAIN_XFER_CNT));
8748
8749         scsiq->remain_bytes &= max_dma_count;
8750         return (sg_queue_cnt);
8751 }
8752
8753 static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
8754 {
8755         uchar next_qp;
8756         uchar n_q_used;
8757         uchar sg_list_qp;
8758         uchar sg_queue_cnt;
8759         uchar q_cnt;
8760         uchar done_q_tail;
8761         uchar tid_no;
8762         ASC_SCSI_BIT_ID_TYPE scsi_busy;
8763         ASC_SCSI_BIT_ID_TYPE target_id;
8764         PortAddr iop_base;
8765         ushort q_addr;
8766         ushort sg_q_addr;
8767         uchar cur_target_qng;
8768         ASC_QDONE_INFO scsiq_buf;
8769         ASC_QDONE_INFO *scsiq;
8770         int false_overrun;
8771         ASC_ISR_CALLBACK asc_isr_callback;
8772
8773         iop_base = asc_dvc->iop_base;
8774         asc_isr_callback = asc_dvc->isr_callback;
8775         n_q_used = 1;
8776         scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
8777         done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
8778         q_addr = ASC_QNO_TO_QADDR(done_q_tail);
8779         next_qp = AscReadLramByte(iop_base,
8780                                   (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
8781         if (next_qp != ASC_QLINK_END) {
8782                 AscPutVarDoneQTail(iop_base, next_qp);
8783                 q_addr = ASC_QNO_TO_QADDR(next_qp);
8784                 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
8785                                                      asc_dvc->max_dma_count);
8786                 AscWriteLramByte(iop_base,
8787                                  (ushort)(q_addr +
8788                                           (ushort)ASC_SCSIQ_B_STATUS),
8789                                  (uchar)(scsiq->
8790                                          q_status & (uchar)~(QS_READY |
8791                                                              QS_ABORTED)));
8792                 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
8793                 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
8794                 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
8795                         sg_q_addr = q_addr;
8796                         sg_list_qp = next_qp;
8797                         for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
8798                                 sg_list_qp = AscReadLramByte(iop_base,
8799                                                              (ushort)(sg_q_addr
8800                                                                       + (ushort)
8801                                                                       ASC_SCSIQ_B_FWD));
8802                                 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
8803                                 if (sg_list_qp == ASC_QLINK_END) {
8804                                         AscSetLibErrorCode(asc_dvc,
8805                                                            ASCQ_ERR_SG_Q_LINKS);
8806                                         scsiq->d3.done_stat = QD_WITH_ERROR;
8807                                         scsiq->d3.host_stat =
8808                                             QHSTA_D_QDONE_SG_LIST_CORRUPTED;
8809                                         goto FATAL_ERR_QDONE;
8810                                 }
8811                                 AscWriteLramByte(iop_base,
8812                                                  (ushort)(sg_q_addr + (ushort)
8813                                                           ASC_SCSIQ_B_STATUS),
8814                                                  QS_FREE);
8815                         }
8816                         n_q_used = sg_queue_cnt + 1;
8817                         AscPutVarDoneQTail(iop_base, sg_list_qp);
8818                 }
8819                 if (asc_dvc->queue_full_or_busy & target_id) {
8820                         cur_target_qng = AscReadLramByte(iop_base,
8821                                                          (ushort)((ushort)
8822                                                                   ASC_QADR_BEG
8823                                                                   + (ushort)
8824                                                                   scsiq->d2.
8825                                                                   target_ix));
8826                         if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
8827                                 scsi_busy = AscReadLramByte(iop_base, (ushort)
8828                                                             ASCV_SCSIBUSY_B);
8829                                 scsi_busy &= ~target_id;
8830                                 AscWriteLramByte(iop_base,
8831                                                  (ushort)ASCV_SCSIBUSY_B,
8832                                                  scsi_busy);
8833                                 asc_dvc->queue_full_or_busy &= ~target_id;
8834                         }
8835                 }
8836                 if (asc_dvc->cur_total_qng >= n_q_used) {
8837                         asc_dvc->cur_total_qng -= n_q_used;
8838                         if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
8839                                 asc_dvc->cur_dvc_qng[tid_no]--;
8840                         }
8841                 } else {
8842                         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
8843                         scsiq->d3.done_stat = QD_WITH_ERROR;
8844                         goto FATAL_ERR_QDONE;
8845                 }
8846                 if ((scsiq->d2.srb_ptr == 0UL) ||
8847                     ((scsiq->q_status & QS_ABORTED) != 0)) {
8848                         return (0x11);
8849                 } else if (scsiq->q_status == QS_DONE) {
8850                         false_overrun = FALSE;
8851                         if (scsiq->extra_bytes != 0) {
8852                                 scsiq->remain_bytes +=
8853                                     (ADV_DCNT)scsiq->extra_bytes;
8854                         }
8855                         if (scsiq->d3.done_stat == QD_WITH_ERROR) {
8856                                 if (scsiq->d3.host_stat ==
8857                                     QHSTA_M_DATA_OVER_RUN) {
8858                                         if ((scsiq->
8859                                              cntl & (QC_DATA_IN | QC_DATA_OUT))
8860                                             == 0) {
8861                                                 scsiq->d3.done_stat =
8862                                                     QD_NO_ERROR;
8863                                                 scsiq->d3.host_stat =
8864                                                     QHSTA_NO_ERROR;
8865                                         } else if (false_overrun) {
8866                                                 scsiq->d3.done_stat =
8867                                                     QD_NO_ERROR;
8868                                                 scsiq->d3.host_stat =
8869                                                     QHSTA_NO_ERROR;
8870                                         }
8871                                 } else if (scsiq->d3.host_stat ==
8872                                            QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
8873                                         AscStopChip(iop_base);
8874                                         AscSetChipControl(iop_base,
8875                                                           (uchar)(CC_SCSI_RESET
8876                                                                   | CC_HALT));
8877                                         DvcDelayNanoSecond(asc_dvc, 60000);
8878                                         AscSetChipControl(iop_base, CC_HALT);
8879                                         AscSetChipStatus(iop_base,
8880                                                          CIW_CLR_SCSI_RESET_INT);
8881                                         AscSetChipStatus(iop_base, 0);
8882                                         AscSetChipControl(iop_base, 0);
8883                                 }
8884                         }
8885                         if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
8886                                 (*asc_isr_callback) (asc_dvc, scsiq);
8887                         } else {
8888                                 if ((AscReadLramByte(iop_base,
8889                                                      (ushort)(q_addr + (ushort)
8890                                                               ASC_SCSIQ_CDB_BEG))
8891                                      == START_STOP)) {
8892                                         asc_dvc->unit_not_ready &= ~target_id;
8893                                         if (scsiq->d3.done_stat != QD_NO_ERROR) {
8894                                                 asc_dvc->start_motor &=
8895                                                     ~target_id;
8896                                         }
8897                                 }
8898                         }
8899                         return (1);
8900                 } else {
8901                         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
8902  FATAL_ERR_QDONE:
8903                         if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
8904                                 (*asc_isr_callback) (asc_dvc, scsiq);
8905                         }
8906                         return (0x80);
8907                 }
8908         }
8909         return (0);
8910 }
8911
8912 static int AscISR(ASC_DVC_VAR *asc_dvc)
8913 {
8914         ASC_CS_TYPE chipstat;
8915         PortAddr iop_base;
8916         ushort saved_ram_addr;
8917         uchar ctrl_reg;
8918         uchar saved_ctrl_reg;
8919         int int_pending;
8920         int status;
8921         uchar host_flag;
8922
8923         iop_base = asc_dvc->iop_base;
8924         int_pending = FALSE;
8925
8926         if (AscIsIntPending(iop_base) == 0) {
8927                 return int_pending;
8928         }
8929
8930         if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
8931             || (asc_dvc->isr_callback == 0)
8932             ) {
8933                 return (ERR);
8934         }
8935         if (asc_dvc->in_critical_cnt != 0) {
8936                 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
8937                 return (ERR);
8938         }
8939         if (asc_dvc->is_in_int) {
8940                 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
8941                 return (ERR);
8942         }
8943         asc_dvc->is_in_int = TRUE;
8944         ctrl_reg = AscGetChipControl(iop_base);
8945         saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
8946                                        CC_SINGLE_STEP | CC_DIAG | CC_TEST));
8947         chipstat = AscGetChipStatus(iop_base);
8948         if (chipstat & CSW_SCSI_RESET_LATCH) {
8949                 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
8950                         int i = 10;
8951                         int_pending = TRUE;
8952                         asc_dvc->sdtr_done = 0;
8953                         saved_ctrl_reg &= (uchar)(~CC_HALT);
8954                         while ((AscGetChipStatus(iop_base) &
8955                                 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
8956                                 DvcSleepMilliSecond(100);
8957                         }
8958                         AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
8959                         AscSetChipControl(iop_base, CC_HALT);
8960                         AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
8961                         AscSetChipStatus(iop_base, 0);
8962                         chipstat = AscGetChipStatus(iop_base);
8963                 }
8964         }
8965         saved_ram_addr = AscGetChipLramAddr(iop_base);
8966         host_flag = AscReadLramByte(iop_base,
8967                                     ASCV_HOST_FLAG_B) &
8968             (uchar)(~ASC_HOST_FLAG_IN_ISR);
8969         AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
8970                          (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
8971         if ((chipstat & CSW_INT_PENDING)
8972             || (int_pending)
8973             ) {
8974                 AscAckInterrupt(iop_base);
8975                 int_pending = TRUE;
8976                 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
8977                         if (AscIsrChipHalted(asc_dvc) == ERR) {
8978                                 goto ISR_REPORT_QDONE_FATAL_ERROR;
8979                         } else {
8980                                 saved_ctrl_reg &= (uchar)(~CC_HALT);
8981                         }
8982                 } else {
8983  ISR_REPORT_QDONE_FATAL_ERROR:
8984                         if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
8985                                 while (((status =
8986                                          AscIsrQDone(asc_dvc)) & 0x01) != 0) {
8987                                 }
8988                         } else {
8989                                 do {
8990                                         if ((status =
8991                                              AscIsrQDone(asc_dvc)) == 1) {
8992                                                 break;
8993                                         }
8994                                 } while (status == 0x11);
8995                         }
8996                         if ((status & 0x80) != 0)
8997                                 int_pending = ERR;
8998                 }
8999         }
9000         AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
9001         AscSetChipLramAddr(iop_base, saved_ram_addr);
9002         AscSetChipControl(iop_base, saved_ctrl_reg);
9003         asc_dvc->is_in_int = FALSE;
9004         return (int_pending);
9005 }
9006
9007 /* Microcode buffer is kept after initialization for error recovery. */
9008 static uchar _asc_mcode_buf[] = {
9009         0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9010         0x00, 0x00, 0x00, 0x00,
9011         0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00,
9012         0x00, 0x00, 0x00, 0x00,
9013         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9014         0x00, 0x00, 0x00, 0x00,
9015         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9016         0x00, 0x00, 0x00, 0x00,
9017         0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00,
9018         0x00, 0xFF, 0x00, 0x00,
9019         0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00,
9020         0x00, 0x00, 0x00, 0x00,
9021         0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
9022         0x00, 0x00, 0x00, 0x00,
9023         0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88,
9024         0x00, 0x00, 0x00, 0x00,
9025         0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73,
9026         0x03, 0x23, 0x36, 0x40,
9027         0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
9028         0xC2, 0x00, 0x92, 0x80,
9029         0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60,
9030         0xB6, 0x00, 0x92, 0x80,
9031         0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00,
9032         0x92, 0x80, 0x80, 0x62,
9033         0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
9034         0xCD, 0x04, 0x4D, 0x00,
9035         0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01,
9036         0xE6, 0x84, 0xD2, 0xC1,
9037         0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97,
9038         0xC6, 0x81, 0xC2, 0x88,
9039         0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
9040         0x84, 0x97, 0x07, 0xA6,
9041         0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE,
9042         0xC2, 0x88, 0xCE, 0x00,
9043         0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01,
9044         0x80, 0x63, 0x07, 0xA6,
9045         0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
9046         0x34, 0x01, 0x00, 0x33,
9047         0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23,
9048         0x68, 0x98, 0x4D, 0x04,
9049         0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23,
9050         0xF8, 0x88, 0xFB, 0x23,
9051         0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
9052         0x00, 0x33, 0x0A, 0x00,
9053         0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00,
9054         0xC2, 0x88, 0xCD, 0x04,
9055         0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81,
9056         0x06, 0xAB, 0x82, 0x01,
9057         0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
9058         0x3C, 0x01, 0x00, 0x05,
9059         0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01,
9060         0x15, 0x23, 0xA1, 0x01,
9061         0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00,
9062         0x06, 0x61, 0x00, 0xA0,
9063         0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
9064         0xC2, 0x88, 0x06, 0x23,
9065         0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01,
9066         0x57, 0x60, 0x00, 0xA0,
9067         0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73,
9068         0x4B, 0x00, 0x06, 0x61,
9069         0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
9070         0x4F, 0x00, 0x84, 0x97,
9071         0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97,
9072         0x48, 0x04, 0x84, 0x80,
9073         0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00,
9074         0x81, 0x73, 0x06, 0x29,
9075         0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
9076         0x04, 0x98, 0xF0, 0x80,
9077         0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6,
9078         0x34, 0x02, 0x03, 0xA6,
9079         0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96,
9080         0x46, 0x82, 0xFE, 0x95,
9081         0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
9082         0x07, 0xA6, 0x5A, 0x02,
9083         0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95,
9084         0x48, 0x82, 0x60, 0x96,
9085         0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84,
9086         0x04, 0x01, 0x0C, 0xDC,
9087         0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
9088         0x6F, 0x00, 0xA5, 0x01,
9089         0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01,
9090         0x02, 0xA6, 0xAA, 0x02,
9091         0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04,
9092         0x01, 0xA6, 0xB4, 0x02,
9093         0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
9094         0x80, 0x63, 0x00, 0x43,
9095         0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23,
9096         0x04, 0x61, 0x84, 0x01,
9097         0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F,
9098         0x00, 0x00, 0xEA, 0x82,
9099         0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
9100         0x00, 0x33, 0x1F, 0x00,
9101         0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98,
9102         0xB6, 0x2D, 0x01, 0xA6,
9103         0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6,
9104         0x10, 0x03, 0x03, 0xA6,
9105         0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
9106         0x7C, 0x95, 0xEE, 0x82,
9107         0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4,
9108         0x04, 0x01, 0x2D, 0xC8,
9109         0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01,
9110         0x05, 0x05, 0x86, 0x98,
9111         0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
9112         0x3C, 0x04, 0x06, 0xA6,
9113         0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88,
9114         0x7C, 0x95, 0x32, 0x83,
9115         0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05,
9116         0xEB, 0x04, 0x00, 0x33,
9117         0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
9118         0xFF, 0xA2, 0x7A, 0x03,
9119         0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01,
9120         0x00, 0xA2, 0x9A, 0x03,
9121         0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00,
9122         0x01, 0xA6, 0x96, 0x03,
9123         0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
9124         0xA4, 0x03, 0x00, 0xA6,
9125         0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03,
9126         0x07, 0xA6, 0xB2, 0x03,
9127         0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88,
9128         0xA8, 0x98, 0x80, 0x42,
9129         0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
9130         0xC0, 0x83, 0x00, 0x33,
9131         0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23,
9132         0xA0, 0x01, 0x12, 0x23,
9133         0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B,
9134         0x80, 0x67, 0x05, 0x23,
9135         0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
9136         0x06, 0xA6, 0x0A, 0x04,
9137         0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96,
9138         0xF4, 0x83, 0x20, 0x84,
9139         0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
9140         0x83, 0x03, 0x80, 0x63,
9141         0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
9142         0x38, 0x04, 0x00, 0x33,
9143         0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84,
9144         0x1D, 0x01, 0x06, 0xCC,
9145         0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62,
9146         0xA2, 0x0D, 0x80, 0x63,
9147         0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
9148         0x80, 0x63, 0xA3, 0x01,
9149         0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0,
9150         0x76, 0x04, 0xE0, 0x00,
9151         0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00,
9152         0x00, 0x33, 0x1E, 0x00,
9153         0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
9154         0x08, 0x23, 0x22, 0xA3,
9155         0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3,
9156         0xC4, 0x04, 0x42, 0x23,
9157         0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23,
9158         0xF8, 0x88, 0x04, 0x98,
9159         0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
9160         0x81, 0x62, 0xE8, 0x81,
9161         0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98,
9162         0x00, 0x33, 0x00, 0x81,
9163         0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23,
9164         0xF8, 0x88, 0x04, 0x23,
9165         0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
9166         0xF4, 0x04, 0x00, 0x33,
9167         0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01,
9168         0x04, 0x23, 0xA0, 0x01,
9169         0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00,
9170         0x00, 0xA3, 0x22, 0x05,
9171         0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
9172         0x46, 0x97, 0xCD, 0x04,
9173         0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23,
9174         0x82, 0x01, 0x34, 0x85,
9175         0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05,
9176         0x1D, 0x01, 0x04, 0xD6,
9177         0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
9178         0x49, 0x00, 0x81, 0x01,
9179         0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01,
9180         0x49, 0x04, 0x80, 0x01,
9181         0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04,
9182         0x01, 0x23, 0xEA, 0x00,
9183         0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
9184         0x07, 0xA4, 0xF8, 0x05,
9185         0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00,
9186         0xC2, 0x88, 0x04, 0xA0,
9187         0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61,
9188         0x00, 0xA2, 0xA4, 0x05,
9189         0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
9190         0x62, 0x97, 0x04, 0x85,
9191         0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05,
9192         0xF4, 0x85, 0x03, 0xA0,
9193         0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63,
9194         0xCC, 0x86, 0x07, 0xA0,
9195         0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
9196         0x80, 0x67, 0x80, 0x63,
9197         0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23,
9198         0xF8, 0x88, 0x07, 0x23,
9199         0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00,
9200         0x00, 0x63, 0x4A, 0x00,
9201         0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
9202         0x07, 0x41, 0x83, 0x03,
9203         0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88,
9204         0x1D, 0x01, 0x01, 0xD6,
9205         0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00,
9206         0x07, 0xA6, 0x7C, 0x05,
9207         0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
9208         0x52, 0x00, 0x06, 0x61,
9209         0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41,
9210         0x00, 0x63, 0x1D, 0x01,
9211         0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23,
9212         0x07, 0x41, 0x00, 0x63,
9213         0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
9214         0xDF, 0x00, 0x06, 0xA6,
9215         0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33,
9216         0x00, 0x40, 0xC0, 0x20,
9217         0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63,
9218         0x06, 0xA6, 0x94, 0x06,
9219         0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
9220         0x40, 0x0E, 0x80, 0x63,
9221         0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E,
9222         0x80, 0x63, 0x00, 0x43,
9223         0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05,
9224         0x80, 0x67, 0x40, 0x0E,
9225         0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
9226         0x07, 0xA6, 0xD6, 0x06,
9227         0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00,
9228         0x0A, 0x2B, 0x07, 0xA6,
9229         0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2,
9230         0xF4, 0x06, 0xC0, 0x0E,
9231         0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
9232         0x81, 0x62, 0x04, 0x01,
9233         0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6,
9234         0x8C, 0x06, 0x00, 0x33,
9235         0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03,
9236         0x80, 0x63, 0x06, 0xA6,
9237         0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
9238         0x00, 0x00, 0x80, 0x67,
9239         0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05,
9240         0xBF, 0x23, 0x04, 0x61,
9241         0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00,
9242         0x00, 0x01, 0xF2, 0x00,
9243         0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
9244         0x80, 0x05, 0x81, 0x05,
9245         0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00,
9246         0x70, 0x00, 0x81, 0x01,
9247         0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04,
9248         0x70, 0x00, 0x80, 0x01,
9249         0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
9250         0xF1, 0x00, 0x70, 0x00,
9251         0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01,
9252         0x71, 0x04, 0x70, 0x00,
9253         0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05,
9254         0xA3, 0x01, 0xA2, 0x01,
9255         0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
9256         0xC4, 0x07, 0x00, 0x33,
9257         0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8,
9258         0x48, 0x00, 0xB0, 0x01,
9259         0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43,
9260         0x00, 0xA2, 0xE4, 0x07,
9261         0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
9262         0x05, 0x05, 0x00, 0x63,
9263         0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43,
9264         0x76, 0x08, 0x80, 0x02,
9265         0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
9266         0x00, 0x02, 0x00, 0xA0,
9267         0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
9268         0x00, 0x63, 0xF3, 0x04,
9269         0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40,
9270         0x00, 0xA2, 0x44, 0x08,
9271         0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1,
9272         0x24, 0x08, 0x04, 0x98,
9273         0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
9274         0x5A, 0x88, 0x02, 0x01,
9275         0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00,
9276         0x00, 0xA3, 0x64, 0x08,
9277         0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63,
9278         0x06, 0xA6, 0x76, 0x08,
9279         0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
9280         0x00, 0x63, 0x38, 0x2B,
9281         0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98,
9282         0x05, 0x05, 0xB2, 0x09,
9283         0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63,
9284         0x80, 0x32, 0x80, 0x36,
9285         0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
9286         0x40, 0x36, 0x40, 0x3A,
9287         0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08,
9288         0x5D, 0x00, 0xFE, 0xC3,
9289         0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73,
9290         0xFF, 0xFD, 0x80, 0x73,
9291         0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
9292         0xA1, 0x23, 0xA1, 0x01,
9293         0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2,
9294         0x80, 0x00, 0x03, 0xC2,
9295         0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23,
9296         0xA0, 0x01, 0xE6, 0x84,
9297 };
9298
9299 static ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
9300 static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
9301
9302 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST  16
9303 static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
9304         INQUIRY,
9305         REQUEST_SENSE,
9306         READ_CAPACITY,
9307         READ_TOC,
9308         MODE_SELECT,
9309         MODE_SENSE,
9310         MODE_SELECT_10,
9311         MODE_SENSE_10,
9312         0xFF,
9313         0xFF,
9314         0xFF,
9315         0xFF,
9316         0xFF,
9317         0xFF,
9318         0xFF,
9319         0xFF
9320 };
9321
9322 static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
9323 {
9324         PortAddr iop_base;
9325         ulong last_int_level;
9326         int sta;
9327         int n_q_required;
9328         int disable_syn_offset_one_fix;
9329         int i;
9330         ASC_PADDR addr;
9331         ASC_EXE_CALLBACK asc_exe_callback;
9332         ushort sg_entry_cnt = 0;
9333         ushort sg_entry_cnt_minus_one = 0;
9334         uchar target_ix;
9335         uchar tid_no;
9336         uchar sdtr_data;
9337         uchar extra_bytes;
9338         uchar scsi_cmd;
9339         uchar disable_cmd;
9340         ASC_SG_HEAD *sg_head;
9341         ASC_DCNT data_cnt;
9342
9343         iop_base = asc_dvc->iop_base;
9344         sg_head = scsiq->sg_head;
9345         asc_exe_callback = asc_dvc->exe_callback;
9346         if (asc_dvc->err_code != 0)
9347                 return (ERR);
9348         if (scsiq == (ASC_SCSI_Q *)0L) {
9349                 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
9350                 return (ERR);
9351         }
9352         scsiq->q1.q_no = 0;
9353         if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
9354                 scsiq->q1.extra_bytes = 0;
9355         }
9356         sta = 0;
9357         target_ix = scsiq->q2.target_ix;
9358         tid_no = ASC_TIX_TO_TID(target_ix);
9359         n_q_required = 1;
9360         if (scsiq->cdbptr[0] == REQUEST_SENSE) {
9361                 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
9362                         asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
9363                         sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9364                         AscMsgOutSDTR(asc_dvc,
9365                                       asc_dvc->
9366                                       sdtr_period_tbl[(sdtr_data >> 4) &
9367                                                       (uchar)(asc_dvc->
9368                                                               max_sdtr_index -
9369                                                               1)],
9370                                       (uchar)(sdtr_data & (uchar)
9371                                               ASC_SYN_MAX_OFFSET));
9372                         scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
9373                 }
9374         }
9375         last_int_level = DvcEnterCritical();
9376         if (asc_dvc->in_critical_cnt != 0) {
9377                 DvcLeaveCritical(last_int_level);
9378                 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
9379                 return (ERR);
9380         }
9381         asc_dvc->in_critical_cnt++;
9382         if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9383                 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
9384                         asc_dvc->in_critical_cnt--;
9385                         DvcLeaveCritical(last_int_level);
9386                         return (ERR);
9387                 }
9388 #if !CC_VERY_LONG_SG_LIST
9389                 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9390                         asc_dvc->in_critical_cnt--;
9391                         DvcLeaveCritical(last_int_level);
9392                         return (ERR);
9393                 }
9394 #endif /* !CC_VERY_LONG_SG_LIST */
9395                 if (sg_entry_cnt == 1) {
9396                         scsiq->q1.data_addr =
9397                             (ADV_PADDR)sg_head->sg_list[0].addr;
9398                         scsiq->q1.data_cnt =
9399                             (ADV_DCNT)sg_head->sg_list[0].bytes;
9400                         scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
9401                 }
9402                 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
9403         }
9404         scsi_cmd = scsiq->cdbptr[0];
9405         disable_syn_offset_one_fix = FALSE;
9406         if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
9407             !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
9408                 if (scsiq->q1.cntl & QC_SG_HEAD) {
9409                         data_cnt = 0;
9410                         for (i = 0; i < sg_entry_cnt; i++) {
9411                                 data_cnt +=
9412                                     (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
9413                                                           bytes);
9414                         }
9415                 } else {
9416                         data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
9417                 }
9418                 if (data_cnt != 0UL) {
9419                         if (data_cnt < 512UL) {
9420                                 disable_syn_offset_one_fix = TRUE;
9421                         } else {
9422                                 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
9423                                      i++) {
9424                                         disable_cmd =
9425                                             _syn_offset_one_disable_cmd[i];
9426                                         if (disable_cmd == 0xFF) {
9427                                                 break;
9428                                         }
9429                                         if (scsi_cmd == disable_cmd) {
9430                                                 disable_syn_offset_one_fix =
9431                                                     TRUE;
9432                                                 break;
9433                                         }
9434                                 }
9435                         }
9436                 }
9437         }
9438         if (disable_syn_offset_one_fix) {
9439                 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9440                 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
9441                                        ASC_TAG_FLAG_DISABLE_DISCONNECT);
9442         } else {
9443                 scsiq->q2.tag_code &= 0x27;
9444         }
9445         if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9446                 if (asc_dvc->bug_fix_cntl) {
9447                         if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9448                                 if ((scsi_cmd == READ_6) ||
9449                                     (scsi_cmd == READ_10)) {
9450                                         addr =
9451                                             (ADV_PADDR)le32_to_cpu(sg_head->
9452                                                                    sg_list
9453                                                                    [sg_entry_cnt_minus_one].
9454                                                                    addr) +
9455                                             (ADV_DCNT)le32_to_cpu(sg_head->
9456                                                                   sg_list
9457                                                                   [sg_entry_cnt_minus_one].
9458                                                                   bytes);
9459                                         extra_bytes =
9460                                             (uchar)((ushort)addr & 0x0003);
9461                                         if ((extra_bytes != 0)
9462                                             &&
9463                                             ((scsiq->q2.
9464                                               tag_code &
9465                                               ASC_TAG_FLAG_EXTRA_BYTES)
9466                                              == 0)) {
9467                                                 scsiq->q2.tag_code |=
9468                                                     ASC_TAG_FLAG_EXTRA_BYTES;
9469                                                 scsiq->q1.extra_bytes =
9470                                                     extra_bytes;
9471                                                 data_cnt =
9472                                                     le32_to_cpu(sg_head->
9473                                                                 sg_list
9474                                                                 [sg_entry_cnt_minus_one].
9475                                                                 bytes);
9476                                                 data_cnt -=
9477                                                     (ASC_DCNT) extra_bytes;
9478                                                 sg_head->
9479                                                     sg_list
9480                                                     [sg_entry_cnt_minus_one].
9481                                                     bytes =
9482                                                     cpu_to_le32(data_cnt);
9483                                         }
9484                                 }
9485                         }
9486                 }
9487                 sg_head->entry_to_copy = sg_head->entry_cnt;
9488 #if CC_VERY_LONG_SG_LIST
9489                 /*
9490                  * Set the sg_entry_cnt to the maximum possible. The rest of
9491                  * the SG elements will be copied when the RISC completes the
9492                  * SG elements that fit and halts.
9493                  */
9494                 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9495                         sg_entry_cnt = ASC_MAX_SG_LIST;
9496                 }
9497 #endif /* CC_VERY_LONG_SG_LIST */
9498                 n_q_required = AscSgListToQueue(sg_entry_cnt);
9499                 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
9500                      (uint) n_q_required)
9501                     || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9502                         if ((sta =
9503                              AscSendScsiQueue(asc_dvc, scsiq,
9504                                               n_q_required)) == 1) {
9505                                 asc_dvc->in_critical_cnt--;
9506                                 if (asc_exe_callback != 0) {
9507                                         (*asc_exe_callback) (asc_dvc, scsiq);
9508                                 }
9509                                 DvcLeaveCritical(last_int_level);
9510                                 return (sta);
9511                         }
9512                 }
9513         } else {
9514                 if (asc_dvc->bug_fix_cntl) {
9515                         if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9516                                 if ((scsi_cmd == READ_6) ||
9517                                     (scsi_cmd == READ_10)) {
9518                                         addr =
9519                                             le32_to_cpu(scsiq->q1.data_addr) +
9520                                             le32_to_cpu(scsiq->q1.data_cnt);
9521                                         extra_bytes =
9522                                             (uchar)((ushort)addr & 0x0003);
9523                                         if ((extra_bytes != 0)
9524                                             &&
9525                                             ((scsiq->q2.
9526                                               tag_code &
9527                                               ASC_TAG_FLAG_EXTRA_BYTES)
9528                                              == 0)) {
9529                                                 data_cnt =
9530                                                     le32_to_cpu(scsiq->q1.
9531                                                                 data_cnt);
9532                                                 if (((ushort)data_cnt & 0x01FF)
9533                                                     == 0) {
9534                                                         scsiq->q2.tag_code |=
9535                                                             ASC_TAG_FLAG_EXTRA_BYTES;
9536                                                         data_cnt -= (ASC_DCNT)
9537                                                             extra_bytes;
9538                                                         scsiq->q1.data_cnt =
9539                                                             cpu_to_le32
9540                                                             (data_cnt);
9541                                                         scsiq->q1.extra_bytes =
9542                                                             extra_bytes;
9543                                                 }
9544                                         }
9545                                 }
9546                         }
9547                 }
9548                 n_q_required = 1;
9549                 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
9550                     ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9551                         if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
9552                                                     n_q_required)) == 1) {
9553                                 asc_dvc->in_critical_cnt--;
9554                                 if (asc_exe_callback != 0) {
9555                                         (*asc_exe_callback) (asc_dvc, scsiq);
9556                                 }
9557                                 DvcLeaveCritical(last_int_level);
9558                                 return (sta);
9559                         }
9560                 }
9561         }
9562         asc_dvc->in_critical_cnt--;
9563         DvcLeaveCritical(last_int_level);
9564         return (sta);
9565 }
9566
9567 static int
9568 AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
9569 {
9570         PortAddr iop_base;
9571         uchar free_q_head;
9572         uchar next_qp;
9573         uchar tid_no;
9574         uchar target_ix;
9575         int sta;
9576
9577         iop_base = asc_dvc->iop_base;
9578         target_ix = scsiq->q2.target_ix;
9579         tid_no = ASC_TIX_TO_TID(target_ix);
9580         sta = 0;
9581         free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
9582         if (n_q_required > 1) {
9583                 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
9584                                                          free_q_head, (uchar)
9585                                                          (n_q_required)))
9586                     != (uchar)ASC_QLINK_END) {
9587                         asc_dvc->last_q_shortage = 0;
9588                         scsiq->sg_head->queue_cnt = n_q_required - 1;
9589                         scsiq->q1.q_no = free_q_head;
9590                         if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
9591                                                           free_q_head)) == 1) {
9592                                 AscPutVarFreeQHead(iop_base, next_qp);
9593                                 asc_dvc->cur_total_qng += (uchar)(n_q_required);
9594                                 asc_dvc->cur_dvc_qng[tid_no]++;
9595                         }
9596                         return (sta);
9597                 }
9598         } else if (n_q_required == 1) {
9599                 if ((next_qp = AscAllocFreeQueue(iop_base,
9600                                                  free_q_head)) !=
9601                     ASC_QLINK_END) {
9602                         scsiq->q1.q_no = free_q_head;
9603                         if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
9604                                                     free_q_head)) == 1) {
9605                                 AscPutVarFreeQHead(iop_base, next_qp);
9606                                 asc_dvc->cur_total_qng++;
9607                                 asc_dvc->cur_dvc_qng[tid_no]++;
9608                         }
9609                         return (sta);
9610                 }
9611         }
9612         return (sta);
9613 }
9614
9615 static int AscSgListToQueue(int sg_list)
9616 {
9617         int n_sg_list_qs;
9618
9619         n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
9620         if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
9621                 n_sg_list_qs++;
9622         return (n_sg_list_qs + 1);
9623 }
9624
9625 static uint
9626 AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
9627 {
9628         uint cur_used_qs;
9629         uint cur_free_qs;
9630         ASC_SCSI_BIT_ID_TYPE target_id;
9631         uchar tid_no;
9632
9633         target_id = ASC_TIX_TO_TARGET_ID(target_ix);
9634         tid_no = ASC_TIX_TO_TID(target_ix);
9635         if ((asc_dvc->unit_not_ready & target_id) ||
9636             (asc_dvc->queue_full_or_busy & target_id)) {
9637                 return (0);
9638         }
9639         if (n_qs == 1) {
9640                 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9641                     (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
9642         } else {
9643                 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9644                     (uint) ASC_MIN_FREE_Q;
9645         }
9646         if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
9647                 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
9648                 if (asc_dvc->cur_dvc_qng[tid_no] >=
9649                     asc_dvc->max_dvc_qng[tid_no]) {
9650                         return (0);
9651                 }
9652                 return (cur_free_qs);
9653         }
9654         if (n_qs > 1) {
9655                 if ((n_qs > asc_dvc->last_q_shortage)
9656                     && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
9657                         asc_dvc->last_q_shortage = n_qs;
9658                 }
9659         }
9660         return (0);
9661 }
9662
9663 static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
9664 {
9665         ushort q_addr;
9666         uchar tid_no;
9667         uchar sdtr_data;
9668         uchar syn_period_ix;
9669         uchar syn_offset;
9670         PortAddr iop_base;
9671
9672         iop_base = asc_dvc->iop_base;
9673         if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
9674             ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
9675                 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
9676                 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9677                 syn_period_ix =
9678                     (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
9679                 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
9680                 AscMsgOutSDTR(asc_dvc,
9681                               asc_dvc->sdtr_period_tbl[syn_period_ix],
9682                               syn_offset);
9683                 scsiq->q1.cntl |= QC_MSG_OUT;
9684         }
9685         q_addr = ASC_QNO_TO_QADDR(q_no);
9686         if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
9687                 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9688         }
9689         scsiq->q1.status = QS_FREE;
9690         AscMemWordCopyPtrToLram(iop_base,
9691                                 q_addr + ASC_SCSIQ_CDB_BEG,
9692                                 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
9693
9694         DvcPutScsiQ(iop_base,
9695                     q_addr + ASC_SCSIQ_CPY_BEG,
9696                     (uchar *)&scsiq->q1.cntl,
9697                     ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
9698         AscWriteLramWord(iop_base,
9699                          (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
9700                          (ushort)(((ushort)scsiq->q1.
9701                                    q_no << 8) | (ushort)QS_READY));
9702         return (1);
9703 }
9704
9705 static int
9706 AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
9707 {
9708         int sta;
9709         int i;
9710         ASC_SG_HEAD *sg_head;
9711         ASC_SG_LIST_Q scsi_sg_q;
9712         ASC_DCNT saved_data_addr;
9713         ASC_DCNT saved_data_cnt;
9714         PortAddr iop_base;
9715         ushort sg_list_dwords;
9716         ushort sg_index;
9717         ushort sg_entry_cnt;
9718         ushort q_addr;
9719         uchar next_qp;
9720
9721         iop_base = asc_dvc->iop_base;
9722         sg_head = scsiq->sg_head;
9723         saved_data_addr = scsiq->q1.data_addr;
9724         saved_data_cnt = scsiq->q1.data_cnt;
9725         scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
9726         scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
9727 #if CC_VERY_LONG_SG_LIST
9728         /*
9729          * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
9730          * then not all SG elements will fit in the allocated queues.
9731          * The rest of the SG elements will be copied when the RISC
9732          * completes the SG elements that fit and halts.
9733          */
9734         if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9735                 /*
9736                  * Set sg_entry_cnt to be the number of SG elements that
9737                  * will fit in the allocated SG queues. It is minus 1, because
9738                  * the first SG element is handled above. ASC_MAX_SG_LIST is
9739                  * already inflated by 1 to account for this. For example it
9740                  * may be 50 which is 1 + 7 queues * 7 SG elements.
9741                  */
9742                 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
9743
9744                 /*
9745                  * Keep track of remaining number of SG elements that will
9746                  * need to be handled from a_isr.c.
9747                  */
9748                 scsiq->remain_sg_entry_cnt =
9749                     sg_head->entry_cnt - ASC_MAX_SG_LIST;
9750         } else {
9751 #endif /* CC_VERY_LONG_SG_LIST */
9752                 /*
9753                  * Set sg_entry_cnt to be the number of SG elements that
9754                  * will fit in the allocated SG queues. It is minus 1, because
9755                  * the first SG element is handled above.
9756                  */
9757                 sg_entry_cnt = sg_head->entry_cnt - 1;
9758 #if CC_VERY_LONG_SG_LIST
9759         }
9760 #endif /* CC_VERY_LONG_SG_LIST */
9761         if (sg_entry_cnt != 0) {
9762                 scsiq->q1.cntl |= QC_SG_HEAD;
9763                 q_addr = ASC_QNO_TO_QADDR(q_no);
9764                 sg_index = 1;
9765                 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
9766                 scsi_sg_q.sg_head_qp = q_no;
9767                 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
9768                 for (i = 0; i < sg_head->queue_cnt; i++) {
9769                         scsi_sg_q.seq_no = i + 1;
9770                         if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
9771                                 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
9772                                 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
9773                                 if (i == 0) {
9774                                         scsi_sg_q.sg_list_cnt =
9775                                             ASC_SG_LIST_PER_Q;
9776                                         scsi_sg_q.sg_cur_list_cnt =
9777                                             ASC_SG_LIST_PER_Q;
9778                                 } else {
9779                                         scsi_sg_q.sg_list_cnt =
9780                                             ASC_SG_LIST_PER_Q - 1;
9781                                         scsi_sg_q.sg_cur_list_cnt =
9782                                             ASC_SG_LIST_PER_Q - 1;
9783                                 }
9784                         } else {
9785 #if CC_VERY_LONG_SG_LIST
9786                                 /*
9787                                  * This is the last SG queue in the list of
9788                                  * allocated SG queues. If there are more
9789                                  * SG elements than will fit in the allocated
9790                                  * queues, then set the QCSG_SG_XFER_MORE flag.
9791                                  */
9792                                 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9793                                         scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
9794                                 } else {
9795 #endif /* CC_VERY_LONG_SG_LIST */
9796                                         scsi_sg_q.cntl |= QCSG_SG_XFER_END;
9797 #if CC_VERY_LONG_SG_LIST
9798                                 }
9799 #endif /* CC_VERY_LONG_SG_LIST */
9800                                 sg_list_dwords = sg_entry_cnt << 1;
9801                                 if (i == 0) {
9802                                         scsi_sg_q.sg_list_cnt = sg_entry_cnt;
9803                                         scsi_sg_q.sg_cur_list_cnt =
9804                                             sg_entry_cnt;
9805                                 } else {
9806                                         scsi_sg_q.sg_list_cnt =
9807                                             sg_entry_cnt - 1;
9808                                         scsi_sg_q.sg_cur_list_cnt =
9809                                             sg_entry_cnt - 1;
9810                                 }
9811                                 sg_entry_cnt = 0;
9812                         }
9813                         next_qp = AscReadLramByte(iop_base,
9814                                                   (ushort)(q_addr +
9815                                                            ASC_SCSIQ_B_FWD));
9816                         scsi_sg_q.q_no = next_qp;
9817                         q_addr = ASC_QNO_TO_QADDR(next_qp);
9818                         AscMemWordCopyPtrToLram(iop_base,
9819                                                 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
9820                                                 (uchar *)&scsi_sg_q,
9821                                                 sizeof(ASC_SG_LIST_Q) >> 1);
9822                         AscMemDWordCopyPtrToLram(iop_base,
9823                                                  q_addr + ASC_SGQ_LIST_BEG,
9824                                                  (uchar *)&sg_head->
9825                                                  sg_list[sg_index],
9826                                                  sg_list_dwords);
9827                         sg_index += ASC_SG_LIST_PER_Q;
9828                         scsiq->next_sg_index = sg_index;
9829                 }
9830         } else {
9831                 scsiq->q1.cntl &= ~QC_SG_HEAD;
9832         }
9833         sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
9834         scsiq->q1.data_addr = saved_data_addr;
9835         scsiq->q1.data_cnt = saved_data_cnt;
9836         return (sta);
9837 }
9838
9839 static int
9840 AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
9841 {
9842         int sta = FALSE;
9843
9844         if (AscHostReqRiscHalt(iop_base)) {
9845                 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9846                 AscStartChip(iop_base);
9847                 return (sta);
9848         }
9849         return (sta);
9850 }
9851
9852 static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
9853 {
9854         ASC_SCSI_BIT_ID_TYPE org_id;
9855         int i;
9856         int sta = TRUE;
9857
9858         AscSetBank(iop_base, 1);
9859         org_id = AscReadChipDvcID(iop_base);
9860         for (i = 0; i <= ASC_MAX_TID; i++) {
9861                 if (org_id == (0x01 << i))
9862                         break;
9863         }
9864         org_id = (ASC_SCSI_BIT_ID_TYPE) i;
9865         AscWriteChipDvcID(iop_base, id);
9866         if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
9867                 AscSetBank(iop_base, 0);
9868                 AscSetChipSyn(iop_base, sdtr_data);
9869                 if (AscGetChipSyn(iop_base) != sdtr_data) {
9870                         sta = FALSE;
9871                 }
9872         } else {
9873                 sta = FALSE;
9874         }
9875         AscSetBank(iop_base, 1);
9876         AscWriteChipDvcID(iop_base, org_id);
9877         AscSetBank(iop_base, 0);
9878         return (sta);
9879 }
9880
9881 static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
9882 {
9883         uchar i;
9884         ushort s_addr;
9885         PortAddr iop_base;
9886         ushort warn_code;
9887
9888         iop_base = asc_dvc->iop_base;
9889         warn_code = 0;
9890         AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
9891                           (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
9892                                     64) >> 1)
9893             );
9894         i = ASC_MIN_ACTIVE_QNO;
9895         s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
9896         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9897                          (uchar)(i + 1));
9898         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9899                          (uchar)(asc_dvc->max_total_qng));
9900         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9901                          (uchar)i);
9902         i++;
9903         s_addr += ASC_QBLK_SIZE;
9904         for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
9905                 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9906                                  (uchar)(i + 1));
9907                 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9908                                  (uchar)(i - 1));
9909                 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9910                                  (uchar)i);
9911         }
9912         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9913                          (uchar)ASC_QLINK_END);
9914         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9915                          (uchar)(asc_dvc->max_total_qng - 1));
9916         AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9917                          (uchar)asc_dvc->max_total_qng);
9918         i++;
9919         s_addr += ASC_QBLK_SIZE;
9920         for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
9921              i++, s_addr += ASC_QBLK_SIZE) {
9922                 AscWriteLramByte(iop_base,
9923                                  (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
9924                 AscWriteLramByte(iop_base,
9925                                  (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
9926                 AscWriteLramByte(iop_base,
9927                                  (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
9928         }
9929         return (warn_code);
9930 }
9931
9932 static ushort AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
9933 {
9934         PortAddr iop_base;
9935         int i;
9936         ushort lram_addr;
9937
9938         iop_base = asc_dvc->iop_base;
9939         AscPutRiscVarFreeQHead(iop_base, 1);
9940         AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
9941         AscPutVarFreeQHead(iop_base, 1);
9942         AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
9943         AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
9944                          (uchar)((int)asc_dvc->max_total_qng + 1));
9945         AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
9946                          (uchar)((int)asc_dvc->max_total_qng + 2));
9947         AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
9948                          asc_dvc->max_total_qng);
9949         AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
9950         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9951         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
9952         AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
9953         AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
9954         AscPutQDoneInProgress(iop_base, 0);
9955         lram_addr = ASC_QADR_BEG;
9956         for (i = 0; i < 32; i++, lram_addr += 2) {
9957                 AscWriteLramWord(iop_base, lram_addr, 0);
9958         }
9959         return (0);
9960 }
9961
9962 static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
9963 {
9964         if (asc_dvc->err_code == 0) {
9965                 asc_dvc->err_code = err_code;
9966                 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
9967                                  err_code);
9968         }
9969         return (err_code);
9970 }
9971
9972 static uchar
9973 AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
9974 {
9975         EXT_MSG sdtr_buf;
9976         uchar sdtr_period_index;
9977         PortAddr iop_base;
9978
9979         iop_base = asc_dvc->iop_base;
9980         sdtr_buf.msg_type = MS_EXTEND;
9981         sdtr_buf.msg_len = MS_SDTR_LEN;
9982         sdtr_buf.msg_req = MS_SDTR_CODE;
9983         sdtr_buf.xfer_period = sdtr_period;
9984         sdtr_offset &= ASC_SYN_MAX_OFFSET;
9985         sdtr_buf.req_ack_offset = sdtr_offset;
9986         if ((sdtr_period_index =
9987              AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
9988             asc_dvc->max_sdtr_index) {
9989                 AscMemWordCopyPtrToLram(iop_base,
9990                                         ASCV_MSGOUT_BEG,
9991                                         (uchar *)&sdtr_buf,
9992                                         sizeof(EXT_MSG) >> 1);
9993                 return ((sdtr_period_index << 4) | sdtr_offset);
9994         } else {
9995
9996                 sdtr_buf.req_ack_offset = 0;
9997                 AscMemWordCopyPtrToLram(iop_base,
9998                                         ASCV_MSGOUT_BEG,
9999                                         (uchar *)&sdtr_buf,
10000                                         sizeof(EXT_MSG) >> 1);
10001                 return (0);
10002         }
10003 }
10004
10005 static uchar
10006 AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
10007 {
10008         uchar byte;
10009         uchar sdtr_period_ix;
10010
10011         sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
10012         if ((sdtr_period_ix > asc_dvc->max_sdtr_index)
10013             ) {
10014                 return (0xFF);
10015         }
10016         byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
10017         return (byte);
10018 }
10019
10020 static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
10021 {
10022         AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
10023         AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
10024         return;
10025 }
10026
10027 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
10028 {
10029         uchar *period_table;
10030         int max_index;
10031         int min_index;
10032         int i;
10033
10034         period_table = asc_dvc->sdtr_period_tbl;
10035         max_index = (int)asc_dvc->max_sdtr_index;
10036         min_index = (int)asc_dvc->host_init_sdtr_index;
10037         if ((syn_time <= period_table[max_index])) {
10038                 for (i = min_index; i < (max_index - 1); i++) {
10039                         if (syn_time <= period_table[i]) {
10040                                 return ((uchar)i);
10041                         }
10042                 }
10043                 return ((uchar)max_index);
10044         } else {
10045                 return ((uchar)(max_index + 1));
10046         }
10047 }
10048
10049 static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
10050 {
10051         ushort q_addr;
10052         uchar next_qp;
10053         uchar q_status;
10054
10055         q_addr = ASC_QNO_TO_QADDR(free_q_head);
10056         q_status = (uchar)AscReadLramByte(iop_base,
10057                                           (ushort)(q_addr +
10058                                                    ASC_SCSIQ_B_STATUS));
10059         next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
10060         if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
10061                 return (next_qp);
10062         }
10063         return (ASC_QLINK_END);
10064 }
10065
10066 static uchar
10067 AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
10068 {
10069         uchar i;
10070
10071         for (i = 0; i < n_free_q; i++) {
10072                 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
10073                     == ASC_QLINK_END) {
10074                         return (ASC_QLINK_END);
10075                 }
10076         }
10077         return (free_q_head);
10078 }
10079
10080 static int AscHostReqRiscHalt(PortAddr iop_base)
10081 {
10082         int count = 0;
10083         int sta = 0;
10084         uchar saved_stop_code;
10085
10086         if (AscIsChipHalted(iop_base))
10087                 return (1);
10088         saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
10089         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
10090                          ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
10091         do {
10092                 if (AscIsChipHalted(iop_base)) {
10093                         sta = 1;
10094                         break;
10095                 }
10096                 DvcSleepMilliSecond(100);
10097         } while (count++ < 20);
10098         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
10099         return (sta);
10100 }
10101
10102 static int AscStopQueueExe(PortAddr iop_base)
10103 {
10104         int count = 0;
10105
10106         if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
10107                 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
10108                                  ASC_STOP_REQ_RISC_STOP);
10109                 do {
10110                         if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
10111                             ASC_STOP_ACK_RISC_STOP) {
10112                                 return (1);
10113                         }
10114                         DvcSleepMilliSecond(100);
10115                 } while (count++ < 20);
10116         }
10117         return (0);
10118 }
10119
10120 static void DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
10121 {
10122         udelay(micro_sec);
10123 }
10124
10125 static void DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
10126 {
10127         udelay((nano_sec + 999) / 1000);
10128 }
10129
10130 static int AscStartChip(PortAddr iop_base)
10131 {
10132         AscSetChipControl(iop_base, 0);
10133         if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
10134                 return (0);
10135         }
10136         return (1);
10137 }
10138
10139 static int AscStopChip(PortAddr iop_base)
10140 {
10141         uchar cc_val;
10142
10143         cc_val =
10144             AscGetChipControl(iop_base) &
10145             (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
10146         AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
10147         AscSetChipIH(iop_base, INS_HALT);
10148         AscSetChipIH(iop_base, INS_RFLAG_WTM);
10149         if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
10150                 return (0);
10151         }
10152         return (1);
10153 }
10154
10155 static int AscIsChipHalted(PortAddr iop_base)
10156 {
10157         if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
10158                 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
10159                         return (1);
10160                 }
10161         }
10162         return (0);
10163 }
10164
10165 static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
10166 {
10167         AscSetBank(iop_base, 1);
10168         AscWriteChipIH(iop_base, ins_code);
10169         AscSetBank(iop_base, 0);
10170         return;
10171 }
10172
10173 static void AscAckInterrupt(PortAddr iop_base)
10174 {
10175         uchar host_flag;
10176         uchar risc_flag;
10177         ushort loop;
10178
10179         loop = 0;
10180         do {
10181                 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
10182                 if (loop++ > 0x7FFF) {
10183                         break;
10184                 }
10185         } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
10186         host_flag =
10187             AscReadLramByte(iop_base,
10188                             ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
10189         AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10190                          (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
10191         AscSetChipStatus(iop_base, CIW_INT_ACK);
10192         loop = 0;
10193         while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
10194                 AscSetChipStatus(iop_base, CIW_INT_ACK);
10195                 if (loop++ > 3) {
10196                         break;
10197                 }
10198         }
10199         AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10200         return;
10201 }
10202
10203 static void AscDisableInterrupt(PortAddr iop_base)
10204 {
10205         ushort cfg;
10206
10207         cfg = AscGetChipCfgLsw(iop_base);
10208         AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
10209         return;
10210 }
10211
10212 static void AscEnableInterrupt(PortAddr iop_base)
10213 {
10214         ushort cfg;
10215
10216         cfg = AscGetChipCfgLsw(iop_base);
10217         AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
10218         return;
10219 }
10220
10221 static void AscSetBank(PortAddr iop_base, uchar bank)
10222 {
10223         uchar val;
10224
10225         val = AscGetChipControl(iop_base) &
10226             (~
10227              (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
10228               CC_CHIP_RESET));
10229         if (bank == 1) {
10230                 val |= CC_BANK_ONE;
10231         } else if (bank == 2) {
10232                 val |= CC_DIAG | CC_BANK_ONE;
10233         } else {
10234                 val &= ~CC_BANK_ONE;
10235         }
10236         AscSetChipControl(iop_base, val);
10237         return;
10238 }
10239
10240 static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
10241 {
10242         PortAddr iop_base;
10243         int i = 10;
10244
10245         iop_base = asc_dvc->iop_base;
10246         while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
10247                && (i-- > 0)) {
10248                 DvcSleepMilliSecond(100);
10249         }
10250         AscStopChip(iop_base);
10251         AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
10252         DvcDelayNanoSecond(asc_dvc, 60000);
10253         AscSetChipIH(iop_base, INS_RFLAG_WTM);
10254         AscSetChipIH(iop_base, INS_HALT);
10255         AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
10256         AscSetChipControl(iop_base, CC_HALT);
10257         DvcSleepMilliSecond(200);
10258         AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10259         AscSetChipStatus(iop_base, 0);
10260         return (AscIsChipHalted(iop_base));
10261 }
10262
10263 static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
10264 {
10265         if (bus_type & ASC_IS_ISA)
10266                 return (ASC_MAX_ISA_DMA_COUNT);
10267         else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
10268                 return (ASC_MAX_VL_DMA_COUNT);
10269         return (ASC_MAX_PCI_DMA_COUNT);
10270 }
10271
10272 #ifdef CONFIG_ISA
10273 static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
10274 {
10275         ushort channel;
10276
10277         channel = AscGetChipCfgLsw(iop_base) & 0x0003;
10278         if (channel == 0x03)
10279                 return (0);
10280         else if (channel == 0x00)
10281                 return (7);
10282         return (channel + 4);
10283 }
10284
10285 static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
10286 {
10287         ushort cfg_lsw;
10288         uchar value;
10289
10290         if ((dma_channel >= 5) && (dma_channel <= 7)) {
10291                 if (dma_channel == 7)
10292                         value = 0x00;
10293                 else
10294                         value = dma_channel - 4;
10295                 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
10296                 cfg_lsw |= value;
10297                 AscSetChipCfgLsw(iop_base, cfg_lsw);
10298                 return (AscGetIsaDmaChannel(iop_base));
10299         }
10300         return (0);
10301 }
10302
10303 static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
10304 {
10305         speed_value &= 0x07;
10306         AscSetBank(iop_base, 1);
10307         AscWriteChipDmaSpeed(iop_base, speed_value);
10308         AscSetBank(iop_base, 0);
10309         return (AscGetIsaDmaSpeed(iop_base));
10310 }
10311
10312 static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
10313 {
10314         uchar speed_value;
10315
10316         AscSetBank(iop_base, 1);
10317         speed_value = AscReadChipDmaSpeed(iop_base);
10318         speed_value &= 0x07;
10319         AscSetBank(iop_base, 0);
10320         return (speed_value);
10321 }
10322 #endif /* CONFIG_ISA */
10323
10324 static ushort __devinit
10325 AscReadPCIConfigWord(ASC_DVC_VAR *asc_dvc, ushort pci_config_offset)
10326 {
10327         uchar lsb, msb;
10328
10329         lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
10330         msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
10331         return ((ushort)((msb << 8) | lsb));
10332 }
10333
10334 static ushort __devinit AscInitGetConfig(ASC_DVC_VAR *asc_dvc)
10335 {
10336         ushort warn_code;
10337         PortAddr iop_base;
10338         ushort PCIDeviceID;
10339         ushort PCIVendorID;
10340         uchar PCIRevisionID;
10341         uchar prevCmdRegBits;
10342
10343         warn_code = 0;
10344         iop_base = asc_dvc->iop_base;
10345         asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
10346         if (asc_dvc->err_code != 0) {
10347                 return (UW_ERR);
10348         }
10349         if (asc_dvc->bus_type == ASC_IS_PCI) {
10350                 PCIVendorID = AscReadPCIConfigWord(asc_dvc,
10351                                                    AscPCIConfigVendorIDRegister);
10352
10353                 PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
10354                                                    AscPCIConfigDeviceIDRegister);
10355
10356                 PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
10357                                                      AscPCIConfigRevisionIDRegister);
10358
10359                 if (PCIVendorID != PCI_VENDOR_ID_ASP) {
10360                         warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10361                 }
10362                 prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
10363                                                       AscPCIConfigCommandRegister);
10364
10365                 if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
10366                     AscPCICmdRegBits_IOMemBusMaster) {
10367                         DvcWritePCIConfigByte(asc_dvc,
10368                                               AscPCIConfigCommandRegister,
10369                                               (prevCmdRegBits |
10370                                                AscPCICmdRegBits_IOMemBusMaster));
10371
10372                         if ((DvcReadPCIConfigByte(asc_dvc,
10373                                                   AscPCIConfigCommandRegister)
10374                              & AscPCICmdRegBits_IOMemBusMaster)
10375                             != AscPCICmdRegBits_IOMemBusMaster) {
10376                                 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10377                         }
10378                 }
10379                 if ((PCIDeviceID == PCI_DEVICE_ID_ASP_1200A) ||
10380                     (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940)) {
10381                         DvcWritePCIConfigByte(asc_dvc,
10382                                               AscPCIConfigLatencyTimer, 0x00);
10383                         if (DvcReadPCIConfigByte
10384                             (asc_dvc, AscPCIConfigLatencyTimer)
10385                             != 0x00) {
10386                                 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10387                         }
10388                 } else if (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940U) {
10389                         if (DvcReadPCIConfigByte(asc_dvc,
10390                                                  AscPCIConfigLatencyTimer) <
10391                             0x20) {
10392                                 DvcWritePCIConfigByte(asc_dvc,
10393                                                       AscPCIConfigLatencyTimer,
10394                                                       0x20);
10395
10396                                 if (DvcReadPCIConfigByte(asc_dvc,
10397                                                          AscPCIConfigLatencyTimer)
10398                                     < 0x20) {
10399                                         warn_code |=
10400                                             ASC_WARN_SET_PCI_CONFIG_SPACE;
10401                                 }
10402                         }
10403                 }
10404         }
10405
10406         if (AscFindSignature(iop_base)) {
10407                 warn_code |= AscInitAscDvcVar(asc_dvc);
10408                 warn_code |= AscInitFromEEP(asc_dvc);
10409                 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
10410                 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
10411                         asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
10412                 }
10413         } else {
10414                 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10415         }
10416         return (warn_code);
10417 }
10418
10419 static ushort __devinit AscInitSetConfig(ASC_DVC_VAR *asc_dvc)
10420 {
10421         ushort warn_code = 0;
10422
10423         asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
10424         if (asc_dvc->err_code != 0)
10425                 return (UW_ERR);
10426         if (AscFindSignature(asc_dvc->iop_base)) {
10427                 warn_code |= AscInitFromAscDvcVar(asc_dvc);
10428                 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
10429         } else {
10430                 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10431         }
10432         return (warn_code);
10433 }
10434
10435 static ushort __devinit AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc)
10436 {
10437         PortAddr iop_base;
10438         ushort cfg_msw;
10439         ushort warn_code;
10440         ushort pci_device_id = 0;
10441
10442         iop_base = asc_dvc->iop_base;
10443 #ifdef CONFIG_PCI
10444         if (asc_dvc->cfg->dev)
10445                 pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device;
10446 #endif
10447         warn_code = 0;
10448         cfg_msw = AscGetChipCfgMsw(iop_base);
10449         if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10450                 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10451                 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10452                 AscSetChipCfgMsw(iop_base, cfg_msw);
10453         }
10454         if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
10455             asc_dvc->cfg->cmd_qng_enabled) {
10456                 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
10457                 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10458         }
10459         if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10460                 warn_code |= ASC_WARN_AUTO_CONFIG;
10461         }
10462         if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
10463                 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
10464                     != asc_dvc->irq_no) {
10465                         asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
10466                 }
10467         }
10468         if (asc_dvc->bus_type & ASC_IS_PCI) {
10469                 cfg_msw &= 0xFFC0;
10470                 AscSetChipCfgMsw(iop_base, cfg_msw);
10471                 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
10472                 } else {
10473                         if ((pci_device_id == PCI_DEVICE_ID_ASP_1200A) ||
10474                             (pci_device_id == PCI_DEVICE_ID_ASP_ABP940)) {
10475                                 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
10476                                 asc_dvc->bug_fix_cntl |=
10477                                     ASC_BUG_FIX_ASYN_USE_SYN;
10478                         }
10479                 }
10480         } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
10481                 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
10482                     == ASC_CHIP_VER_ASYN_BUG) {
10483                         asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
10484                 }
10485         }
10486         if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
10487             asc_dvc->cfg->chip_scsi_id) {
10488                 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
10489         }
10490 #ifdef CONFIG_ISA
10491         if (asc_dvc->bus_type & ASC_IS_ISA) {
10492                 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
10493                 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
10494         }
10495 #endif /* CONFIG_ISA */
10496         return (warn_code);
10497 }
10498
10499 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
10500 {
10501         ushort warn_code;
10502         PortAddr iop_base;
10503
10504         iop_base = asc_dvc->iop_base;
10505         warn_code = 0;
10506         if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
10507             !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
10508                 AscResetChipAndScsiBus(asc_dvc);
10509                 DvcSleepMilliSecond((ASC_DCNT)
10510                                     ((ushort)asc_dvc->scsi_reset_wait * 1000));
10511         }
10512         asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
10513         if (asc_dvc->err_code != 0)
10514                 return (UW_ERR);
10515         if (!AscFindSignature(asc_dvc->iop_base)) {
10516                 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10517                 return (warn_code);
10518         }
10519         AscDisableInterrupt(iop_base);
10520         warn_code |= AscInitLram(asc_dvc);
10521         if (asc_dvc->err_code != 0)
10522                 return (UW_ERR);
10523         ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
10524                  (ulong)_asc_mcode_chksum);
10525         if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
10526                              _asc_mcode_size) != _asc_mcode_chksum) {
10527                 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
10528                 return (warn_code);
10529         }
10530         warn_code |= AscInitMicroCodeVar(asc_dvc);
10531         asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
10532         AscEnableInterrupt(iop_base);
10533         return (warn_code);
10534 }
10535
10536 static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
10537 {
10538         int i;
10539         PortAddr iop_base;
10540         ushort warn_code;
10541         uchar chip_version;
10542
10543         iop_base = asc_dvc->iop_base;
10544         warn_code = 0;
10545         asc_dvc->err_code = 0;
10546         if ((asc_dvc->bus_type &
10547              (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
10548                 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
10549         }
10550         AscSetChipControl(iop_base, CC_HALT);
10551         AscSetChipStatus(iop_base, 0);
10552         asc_dvc->bug_fix_cntl = 0;
10553         asc_dvc->pci_fix_asyn_xfer = 0;
10554         asc_dvc->pci_fix_asyn_xfer_always = 0;
10555         /* asc_dvc->init_state initalized in AscInitGetConfig(). */
10556         asc_dvc->sdtr_done = 0;
10557         asc_dvc->cur_total_qng = 0;
10558         asc_dvc->is_in_int = 0;
10559         asc_dvc->in_critical_cnt = 0;
10560         asc_dvc->last_q_shortage = 0;
10561         asc_dvc->use_tagged_qng = 0;
10562         asc_dvc->no_scam = 0;
10563         asc_dvc->unit_not_ready = 0;
10564         asc_dvc->queue_full_or_busy = 0;
10565         asc_dvc->redo_scam = 0;
10566         asc_dvc->res2 = 0;
10567         asc_dvc->host_init_sdtr_index = 0;
10568         asc_dvc->cfg->can_tagged_qng = 0;
10569         asc_dvc->cfg->cmd_qng_enabled = 0;
10570         asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
10571         asc_dvc->init_sdtr = 0;
10572         asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
10573         asc_dvc->scsi_reset_wait = 3;
10574         asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
10575         asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
10576         asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
10577         asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
10578         asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
10579         asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
10580         asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
10581             ASC_LIB_VERSION_MINOR;
10582         chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
10583         asc_dvc->cfg->chip_version = chip_version;
10584         asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
10585         asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
10586         asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
10587         asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
10588         asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
10589         asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
10590         asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
10591         asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
10592         asc_dvc->max_sdtr_index = 7;
10593         if ((asc_dvc->bus_type & ASC_IS_PCI) &&
10594             (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
10595                 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
10596                 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
10597                 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
10598                 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
10599                 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
10600                 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
10601                 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
10602                 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
10603                 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
10604                 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
10605                 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
10606                 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
10607                 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
10608                 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
10609                 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
10610                 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
10611                 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
10612                 asc_dvc->max_sdtr_index = 15;
10613                 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
10614                         AscSetExtraControl(iop_base,
10615                                            (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10616                 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
10617                         AscSetExtraControl(iop_base,
10618                                            (SEC_ACTIVE_NEGATE |
10619                                             SEC_ENABLE_FILTER));
10620                 }
10621         }
10622         if (asc_dvc->bus_type == ASC_IS_PCI) {
10623                 AscSetExtraControl(iop_base,
10624                                    (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10625         }
10626
10627         asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
10628         if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
10629                 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
10630                 asc_dvc->bus_type = ASC_IS_ISAPNP;
10631         }
10632 #ifdef CONFIG_ISA
10633         if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
10634                 asc_dvc->cfg->isa_dma_channel =
10635                     (uchar)AscGetIsaDmaChannel(iop_base);
10636         }
10637 #endif /* CONFIG_ISA */
10638         for (i = 0; i <= ASC_MAX_TID; i++) {
10639                 asc_dvc->cur_dvc_qng[i] = 0;
10640                 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
10641                 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
10642                 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
10643                 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
10644         }
10645         return (warn_code);
10646 }
10647
10648 static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
10649 {
10650         ASCEEP_CONFIG eep_config_buf;
10651         ASCEEP_CONFIG *eep_config;
10652         PortAddr iop_base;
10653         ushort chksum;
10654         ushort warn_code;
10655         ushort cfg_msw, cfg_lsw;
10656         int i;
10657         int write_eep = 0;
10658
10659         iop_base = asc_dvc->iop_base;
10660         warn_code = 0;
10661         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
10662         AscStopQueueExe(iop_base);
10663         if ((AscStopChip(iop_base) == FALSE) ||
10664             (AscGetChipScsiCtrl(iop_base) != 0)) {
10665                 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
10666                 AscResetChipAndScsiBus(asc_dvc);
10667                 DvcSleepMilliSecond((ASC_DCNT)
10668                                     ((ushort)asc_dvc->scsi_reset_wait * 1000));
10669         }
10670         if (AscIsChipHalted(iop_base) == FALSE) {
10671                 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10672                 return (warn_code);
10673         }
10674         AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10675         if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10676                 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10677                 return (warn_code);
10678         }
10679         eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
10680         cfg_msw = AscGetChipCfgMsw(iop_base);
10681         cfg_lsw = AscGetChipCfgLsw(iop_base);
10682         if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10683                 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10684                 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10685                 AscSetChipCfgMsw(iop_base, cfg_msw);
10686         }
10687         chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
10688         ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
10689         if (chksum == 0) {
10690                 chksum = 0xaa55;
10691         }
10692         if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10693                 warn_code |= ASC_WARN_AUTO_CONFIG;
10694                 if (asc_dvc->cfg->chip_version == 3) {
10695                         if (eep_config->cfg_lsw != cfg_lsw) {
10696                                 warn_code |= ASC_WARN_EEPROM_RECOVER;
10697                                 eep_config->cfg_lsw =
10698                                     AscGetChipCfgLsw(iop_base);
10699                         }
10700                         if (eep_config->cfg_msw != cfg_msw) {
10701                                 warn_code |= ASC_WARN_EEPROM_RECOVER;
10702                                 eep_config->cfg_msw =
10703                                     AscGetChipCfgMsw(iop_base);
10704                         }
10705                 }
10706         }
10707         eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
10708         eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
10709         ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
10710                  eep_config->chksum);
10711         if (chksum != eep_config->chksum) {
10712                 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
10713                     ASC_CHIP_VER_PCI_ULTRA_3050) {
10714                         ASC_DBG(1,
10715                                 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
10716                         eep_config->init_sdtr = 0xFF;
10717                         eep_config->disc_enable = 0xFF;
10718                         eep_config->start_motor = 0xFF;
10719                         eep_config->use_cmd_qng = 0;
10720                         eep_config->max_total_qng = 0xF0;
10721                         eep_config->max_tag_qng = 0x20;
10722                         eep_config->cntl = 0xBFFF;
10723                         ASC_EEP_SET_CHIP_ID(eep_config, 7);
10724                         eep_config->no_scam = 0;
10725                         eep_config->adapter_info[0] = 0;
10726                         eep_config->adapter_info[1] = 0;
10727                         eep_config->adapter_info[2] = 0;
10728                         eep_config->adapter_info[3] = 0;
10729                         eep_config->adapter_info[4] = 0;
10730                         /* Indicate EEPROM-less board. */
10731                         eep_config->adapter_info[5] = 0xBB;
10732                 } else {
10733                         ASC_PRINT
10734                             ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
10735                         write_eep = 1;
10736                         warn_code |= ASC_WARN_EEPROM_CHKSUM;
10737                 }
10738         }
10739         asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
10740         asc_dvc->cfg->disc_enable = eep_config->disc_enable;
10741         asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
10742         asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
10743         asc_dvc->start_motor = eep_config->start_motor;
10744         asc_dvc->dvc_cntl = eep_config->cntl;
10745         asc_dvc->no_scam = eep_config->no_scam;
10746         asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
10747         asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
10748         asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
10749         asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
10750         asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
10751         asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
10752         if (!AscTestExternalLram(asc_dvc)) {
10753                 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
10754                      ASC_IS_PCI_ULTRA)) {
10755                         eep_config->max_total_qng =
10756                             ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
10757                         eep_config->max_tag_qng =
10758                             ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
10759                 } else {
10760                         eep_config->cfg_msw |= 0x0800;
10761                         cfg_msw |= 0x0800;
10762                         AscSetChipCfgMsw(iop_base, cfg_msw);
10763                         eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
10764                         eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
10765                 }
10766         } else {
10767         }
10768         if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
10769                 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
10770         }
10771         if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
10772                 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
10773         }
10774         if (eep_config->max_tag_qng > eep_config->max_total_qng) {
10775                 eep_config->max_tag_qng = eep_config->max_total_qng;
10776         }
10777         if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
10778                 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
10779         }
10780         asc_dvc->max_total_qng = eep_config->max_total_qng;
10781         if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
10782             eep_config->use_cmd_qng) {
10783                 eep_config->disc_enable = eep_config->use_cmd_qng;
10784                 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10785         }
10786         if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
10787                 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
10788         }
10789         ASC_EEP_SET_CHIP_ID(eep_config,
10790                             ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
10791         asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
10792         if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
10793             !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
10794                 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
10795         }
10796
10797         for (i = 0; i <= ASC_MAX_TID; i++) {
10798                 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
10799                 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
10800                 asc_dvc->cfg->sdtr_period_offset[i] =
10801                     (uchar)(ASC_DEF_SDTR_OFFSET |
10802                             (asc_dvc->host_init_sdtr_index << 4));
10803         }
10804         eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
10805         if (write_eep) {
10806                 if ((i =
10807                      AscSetEEPConfig(iop_base, eep_config,
10808                                      asc_dvc->bus_type)) != 0) {
10809                         ASC_PRINT1
10810                             ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
10811                              i);
10812                 } else {
10813                         ASC_PRINT
10814                             ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
10815                 }
10816         }
10817         return (warn_code);
10818 }
10819
10820 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
10821 {
10822         int i;
10823         ushort warn_code;
10824         PortAddr iop_base;
10825         ASC_PADDR phy_addr;
10826         ASC_DCNT phy_size;
10827
10828         iop_base = asc_dvc->iop_base;
10829         warn_code = 0;
10830         for (i = 0; i <= ASC_MAX_TID; i++) {
10831                 AscPutMCodeInitSDTRAtID(iop_base, i,
10832                                         asc_dvc->cfg->sdtr_period_offset[i]
10833                     );
10834         }
10835
10836         AscInitQLinkVar(asc_dvc);
10837         AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
10838                          asc_dvc->cfg->disc_enable);
10839         AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
10840                          ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
10841
10842         /* Align overrun buffer on an 8 byte boundary. */
10843         phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
10844         phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
10845         AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
10846                                  (uchar *)&phy_addr, 1);
10847         phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
10848         AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
10849                                  (uchar *)&phy_size, 1);
10850
10851         asc_dvc->cfg->mcode_date =
10852             AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
10853         asc_dvc->cfg->mcode_version =
10854             AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
10855
10856         AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10857         if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10858                 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10859                 return (warn_code);
10860         }
10861         if (AscStartChip(iop_base) != 1) {
10862                 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10863                 return (warn_code);
10864         }
10865
10866         return (warn_code);
10867 }
10868
10869 static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
10870 {
10871         PortAddr iop_base;
10872         ushort q_addr;
10873         ushort saved_word;
10874         int sta;
10875
10876         iop_base = asc_dvc->iop_base;
10877         sta = 0;
10878         q_addr = ASC_QNO_TO_QADDR(241);
10879         saved_word = AscReadLramWord(iop_base, q_addr);
10880         AscSetChipLramAddr(iop_base, q_addr);
10881         AscSetChipLramData(iop_base, 0x55AA);
10882         DvcSleepMilliSecond(10);
10883         AscSetChipLramAddr(iop_base, q_addr);
10884         if (AscGetChipLramData(iop_base) == 0x55AA) {
10885                 sta = 1;
10886                 AscWriteLramWord(iop_base, q_addr, saved_word);
10887         }
10888         return (sta);
10889 }
10890
10891 static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
10892 {
10893         uchar read_back;
10894         int retry;
10895
10896         retry = 0;
10897         while (TRUE) {
10898                 AscSetChipEEPCmd(iop_base, cmd_reg);
10899                 DvcSleepMilliSecond(1);
10900                 read_back = AscGetChipEEPCmd(iop_base);
10901                 if (read_back == cmd_reg) {
10902                         return (1);
10903                 }
10904                 if (retry++ > ASC_EEP_MAX_RETRY) {
10905                         return (0);
10906                 }
10907         }
10908 }
10909
10910 static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
10911 {
10912         ushort read_back;
10913         int retry;
10914
10915         retry = 0;
10916         while (TRUE) {
10917                 AscSetChipEEPData(iop_base, data_reg);
10918                 DvcSleepMilliSecond(1);
10919                 read_back = AscGetChipEEPData(iop_base);
10920                 if (read_back == data_reg) {
10921                         return (1);
10922                 }
10923                 if (retry++ > ASC_EEP_MAX_RETRY) {
10924                         return (0);
10925                 }
10926         }
10927 }
10928
10929 static void __devinit AscWaitEEPRead(void)
10930 {
10931         DvcSleepMilliSecond(1);
10932         return;
10933 }
10934
10935 static void __devinit AscWaitEEPWrite(void)
10936 {
10937         DvcSleepMilliSecond(20);
10938         return;
10939 }
10940
10941 static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
10942 {
10943         ushort read_wval;
10944         uchar cmd_reg;
10945
10946         AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
10947         AscWaitEEPRead();
10948         cmd_reg = addr | ASC_EEP_CMD_READ;
10949         AscWriteEEPCmdReg(iop_base, cmd_reg);
10950         AscWaitEEPRead();
10951         read_wval = AscGetChipEEPData(iop_base);
10952         AscWaitEEPRead();
10953         return (read_wval);
10954 }
10955
10956 static ushort __devinit
10957 AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
10958 {
10959         ushort read_wval;
10960
10961         read_wval = AscReadEEPWord(iop_base, addr);
10962         if (read_wval != word_val) {
10963                 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
10964                 AscWaitEEPRead();
10965                 AscWriteEEPDataReg(iop_base, word_val);
10966                 AscWaitEEPRead();
10967                 AscWriteEEPCmdReg(iop_base,
10968                                   (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
10969                 AscWaitEEPWrite();
10970                 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
10971                 AscWaitEEPRead();
10972                 return (AscReadEEPWord(iop_base, addr));
10973         }
10974         return (read_wval);
10975 }
10976
10977 static ushort __devinit
10978 AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
10979 {
10980         ushort wval;
10981         ushort sum;
10982         ushort *wbuf;
10983         int cfg_beg;
10984         int cfg_end;
10985         int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
10986         int s_addr;
10987
10988         wbuf = (ushort *)cfg_buf;
10989         sum = 0;
10990         /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
10991         for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10992                 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
10993                 sum += *wbuf;
10994         }
10995         if (bus_type & ASC_IS_VL) {
10996                 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10997                 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10998         } else {
10999                 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11000                 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11001         }
11002         for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11003                 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
11004                 if (s_addr <= uchar_end_in_config) {
11005                         /*
11006                          * Swap all char fields - must unswap bytes already swapped
11007                          * by AscReadEEPWord().
11008                          */
11009                         *wbuf = le16_to_cpu(wval);
11010                 } else {
11011                         /* Don't swap word field at the end - cntl field. */
11012                         *wbuf = wval;
11013                 }
11014                 sum += wval;    /* Checksum treats all EEPROM data as words. */
11015         }
11016         /*
11017          * Read the checksum word which will be compared against 'sum'
11018          * by the caller. Word field already swapped.
11019          */
11020         *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11021         return (sum);
11022 }
11023
11024 static int __devinit
11025 AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11026 {
11027         int n_error;
11028         ushort *wbuf;
11029         ushort word;
11030         ushort sum;
11031         int s_addr;
11032         int cfg_beg;
11033         int cfg_end;
11034         int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11035
11036         wbuf = (ushort *)cfg_buf;
11037         n_error = 0;
11038         sum = 0;
11039         /* Write two config words; AscWriteEEPWord() will swap bytes. */
11040         for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11041                 sum += *wbuf;
11042                 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11043                         n_error++;
11044                 }
11045         }
11046         if (bus_type & ASC_IS_VL) {
11047                 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11048                 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11049         } else {
11050                 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11051                 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11052         }
11053         for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11054                 if (s_addr <= uchar_end_in_config) {
11055                         /*
11056                          * This is a char field. Swap char fields before they are
11057                          * swapped again by AscWriteEEPWord().
11058                          */
11059                         word = cpu_to_le16(*wbuf);
11060                         if (word !=
11061                             AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
11062                                 n_error++;
11063                         }
11064                 } else {
11065                         /* Don't swap word field at the end - cntl field. */
11066                         if (*wbuf !=
11067                             AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11068                                 n_error++;
11069                         }
11070                 }
11071                 sum += *wbuf;   /* Checksum calculated from word values. */
11072         }
11073         /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
11074         *wbuf = sum;
11075         if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
11076                 n_error++;
11077         }
11078
11079         /* Read EEPROM back again. */
11080         wbuf = (ushort *)cfg_buf;
11081         /*
11082          * Read two config words; Byte-swapping done by AscReadEEPWord().
11083          */
11084         for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11085                 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
11086                         n_error++;
11087                 }
11088         }
11089         if (bus_type & ASC_IS_VL) {
11090                 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11091                 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11092         } else {
11093                 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11094                 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11095         }
11096         for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11097                 if (s_addr <= uchar_end_in_config) {
11098                         /*
11099                          * Swap all char fields. Must unswap bytes already swapped
11100                          * by AscReadEEPWord().
11101                          */
11102                         word =
11103                             le16_to_cpu(AscReadEEPWord
11104                                         (iop_base, (uchar)s_addr));
11105                 } else {
11106                         /* Don't swap word field at the end - cntl field. */
11107                         word = AscReadEEPWord(iop_base, (uchar)s_addr);
11108                 }
11109                 if (*wbuf != word) {
11110                         n_error++;
11111                 }
11112         }
11113         /* Read checksum; Byte swapping not needed. */
11114         if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
11115                 n_error++;
11116         }
11117         return (n_error);
11118 }
11119
11120 static int __devinit
11121 AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11122 {
11123         int retry;
11124         int n_error;
11125
11126         retry = 0;
11127         while (TRUE) {
11128                 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
11129                                                    bus_type)) == 0) {
11130                         break;
11131                 }
11132                 if (++retry > ASC_EEP_MAX_RETRY) {
11133                         break;
11134                 }
11135         }
11136         return (n_error);
11137 }
11138
11139 static void
11140 AscAsyncFix(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq)
11141 {
11142         uchar dvc_type;
11143         ASC_SCSI_BIT_ID_TYPE tid_bits;
11144
11145         dvc_type = ASC_INQ_DVC_TYPE(inq);
11146         tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
11147
11148         if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
11149                 if (!(asc_dvc->init_sdtr & tid_bits)) {
11150                         if ((dvc_type == TYPE_ROM) &&
11151                             (AscCompareString((uchar *)inq->vendor_id,
11152                                               (uchar *)"HP ", 3) == 0)) {
11153                                 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
11154                         }
11155                         asc_dvc->pci_fix_asyn_xfer |= tid_bits;
11156                         if ((dvc_type == TYPE_PROCESSOR) ||
11157                             (dvc_type == TYPE_SCANNER) ||
11158                             (dvc_type == TYPE_ROM) || (dvc_type == TYPE_TAPE)) {
11159                                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
11160                         }
11161
11162                         if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
11163                                 AscSetRunChipSynRegAtID(asc_dvc->iop_base,
11164                                                         tid_no,
11165                                                         ASYN_SDTR_DATA_FIX_PCI_REV_AB);
11166                         }
11167                 }
11168         }
11169         return;
11170 }
11171
11172 static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
11173 {
11174         if ((inq->add_len >= 32) &&
11175             (AscCompareString((uchar *)inq->vendor_id,
11176                               (uchar *)"QUANTUM XP34301", 15) == 0) &&
11177             (AscCompareString((uchar *)inq->product_rev_level,
11178                               (uchar *)"1071", 4) == 0)) {
11179                 return 0;
11180         }
11181         return 1;
11182 }
11183
11184 static void
11185 AscInquiryHandling(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq)
11186 {
11187         ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
11188         ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
11189
11190         orig_init_sdtr = asc_dvc->init_sdtr;
11191         orig_use_tagged_qng = asc_dvc->use_tagged_qng;
11192
11193         asc_dvc->init_sdtr &= ~tid_bit;
11194         asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
11195         asc_dvc->use_tagged_qng &= ~tid_bit;
11196
11197         if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) {
11198                 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) {
11199                         asc_dvc->init_sdtr |= tid_bit;
11200                 }
11201                 if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) &&
11202                     ASC_INQ_CMD_QUEUE(inq)) {
11203                         if (AscTagQueuingSafe(inq)) {
11204                                 asc_dvc->use_tagged_qng |= tid_bit;
11205                                 asc_dvc->cfg->can_tagged_qng |= tid_bit;
11206                         }
11207                 }
11208         }
11209         if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
11210                 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
11211                                  asc_dvc->cfg->disc_enable);
11212                 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
11213                                  asc_dvc->use_tagged_qng);
11214                 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
11215                                  asc_dvc->cfg->can_tagged_qng);
11216
11217                 asc_dvc->max_dvc_qng[tid_no] =
11218                     asc_dvc->cfg->max_tag_qng[tid_no];
11219                 AscWriteLramByte(asc_dvc->iop_base,
11220                                  (ushort)(ASCV_MAX_DVC_QNG_BEG + tid_no),
11221                                  asc_dvc->max_dvc_qng[tid_no]);
11222         }
11223         if (orig_init_sdtr != asc_dvc->init_sdtr) {
11224                 AscAsyncFix(asc_dvc, tid_no, inq);
11225         }
11226         return;
11227 }
11228
11229 static int AscCompareString(uchar *str1, uchar *str2, int len)
11230 {
11231         int i;
11232         int diff;
11233
11234         for (i = 0; i < len; i++) {
11235                 diff = (int)(str1[i] - str2[i]);
11236                 if (diff != 0)
11237                         return (diff);
11238         }
11239         return (0);
11240 }
11241
11242 static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
11243 {
11244         uchar byte_data;
11245         ushort word_data;
11246
11247         if (isodd_word(addr)) {
11248                 AscSetChipLramAddr(iop_base, addr - 1);
11249                 word_data = AscGetChipLramData(iop_base);
11250                 byte_data = (uchar)((word_data >> 8) & 0xFF);
11251         } else {
11252                 AscSetChipLramAddr(iop_base, addr);
11253                 word_data = AscGetChipLramData(iop_base);
11254                 byte_data = (uchar)(word_data & 0xFF);
11255         }
11256         return (byte_data);
11257 }
11258
11259 static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
11260 {
11261         ushort word_data;
11262
11263         AscSetChipLramAddr(iop_base, addr);
11264         word_data = AscGetChipLramData(iop_base);
11265         return (word_data);
11266 }
11267
11268 #if CC_VERY_LONG_SG_LIST
11269 static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
11270 {
11271         ushort val_low, val_high;
11272         ASC_DCNT dword_data;
11273
11274         AscSetChipLramAddr(iop_base, addr);
11275         val_low = AscGetChipLramData(iop_base);
11276         val_high = AscGetChipLramData(iop_base);
11277         dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
11278         return (dword_data);
11279 }
11280 #endif /* CC_VERY_LONG_SG_LIST */
11281
11282 static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
11283 {
11284         AscSetChipLramAddr(iop_base, addr);
11285         AscSetChipLramData(iop_base, word_val);
11286         return;
11287 }
11288
11289 static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
11290 {
11291         ushort word_data;
11292
11293         if (isodd_word(addr)) {
11294                 addr--;
11295                 word_data = AscReadLramWord(iop_base, addr);
11296                 word_data &= 0x00FF;
11297                 word_data |= (((ushort)byte_val << 8) & 0xFF00);
11298         } else {
11299                 word_data = AscReadLramWord(iop_base, addr);
11300                 word_data &= 0xFF00;
11301                 word_data |= ((ushort)byte_val & 0x00FF);
11302         }
11303         AscWriteLramWord(iop_base, addr, word_data);
11304         return;
11305 }
11306
11307 /*
11308  * Copy 2 bytes to LRAM.
11309  *
11310  * The source data is assumed to be in little-endian order in memory
11311  * and is maintained in little-endian order when written to LRAM.
11312  */
11313 static void
11314 AscMemWordCopyPtrToLram(PortAddr iop_base,
11315                         ushort s_addr, uchar *s_buffer, int words)
11316 {
11317         int i;
11318
11319         AscSetChipLramAddr(iop_base, s_addr);
11320         for (i = 0; i < 2 * words; i += 2) {
11321                 /*
11322                  * On a little-endian system the second argument below
11323                  * produces a little-endian ushort which is written to
11324                  * LRAM in little-endian order. On a big-endian system
11325                  * the second argument produces a big-endian ushort which
11326                  * is "transparently" byte-swapped by outpw() and written
11327                  * in little-endian order to LRAM.
11328                  */
11329                 outpw(iop_base + IOP_RAM_DATA,
11330                       ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
11331         }
11332         return;
11333 }
11334
11335 /*
11336  * Copy 4 bytes to LRAM.
11337  *
11338  * The source data is assumed to be in little-endian order in memory
11339  * and is maintained in little-endian order when writen to LRAM.
11340  */
11341 static void
11342 AscMemDWordCopyPtrToLram(PortAddr iop_base,
11343                          ushort s_addr, uchar *s_buffer, int dwords)
11344 {
11345         int i;
11346
11347         AscSetChipLramAddr(iop_base, s_addr);
11348         for (i = 0; i < 4 * dwords; i += 4) {
11349                 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);   /* LSW */
11350                 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]);       /* MSW */
11351         }
11352         return;
11353 }
11354
11355 /*
11356  * Copy 2 bytes from LRAM.
11357  *
11358  * The source data is assumed to be in little-endian order in LRAM
11359  * and is maintained in little-endian order when written to memory.
11360  */
11361 static void
11362 AscMemWordCopyPtrFromLram(PortAddr iop_base,
11363                           ushort s_addr, uchar *d_buffer, int words)
11364 {
11365         int i;
11366         ushort word;
11367
11368         AscSetChipLramAddr(iop_base, s_addr);
11369         for (i = 0; i < 2 * words; i += 2) {
11370                 word = inpw(iop_base + IOP_RAM_DATA);
11371                 d_buffer[i] = word & 0xff;
11372                 d_buffer[i + 1] = (word >> 8) & 0xff;
11373         }
11374         return;
11375 }
11376
11377 static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
11378 {
11379         ASC_DCNT sum;
11380         int i;
11381
11382         sum = 0L;
11383         for (i = 0; i < words; i++, s_addr += 2) {
11384                 sum += AscReadLramWord(iop_base, s_addr);
11385         }
11386         return (sum);
11387 }
11388
11389 static void
11390 AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
11391 {
11392         int i;
11393
11394         AscSetChipLramAddr(iop_base, s_addr);
11395         for (i = 0; i < words; i++) {
11396                 AscSetChipLramData(iop_base, set_wval);
11397         }
11398         return;
11399 }
11400
11401 /*
11402  * --- Adv Library Functions
11403  */
11404
11405 /* a_mcode.h */
11406
11407 /* Microcode buffer is kept after initialization for error recovery. */
11408 static unsigned char _adv_asc3550_buf[] = {
11409         0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
11410         0x01, 0x00, 0x48, 0xe4,
11411         0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff,
11412         0x28, 0x0e, 0x9e, 0xe7,
11413         0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7,
11414         0x55, 0xf0, 0x01, 0xf6,
11415         0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
11416         0x00, 0xec, 0x85, 0xf0,
11417         0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0,
11418         0x86, 0xf0, 0xb4, 0x00,
11419         0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00,
11420         0xaa, 0x18, 0x02, 0x80,
11421         0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
11422         0x00, 0x57, 0x01, 0xea,
11423         0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80,
11424         0x03, 0xe6, 0xb6, 0x00,
11425         0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12,
11426         0x02, 0x4a, 0xb9, 0x54,
11427         0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
11428         0x3e, 0x00, 0x80, 0x00,
11429         0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
11430         0x74, 0x01, 0x76, 0x01,
11431         0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13,
11432         0x4c, 0x1c, 0xbb, 0x55,
11433         0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
11434         0x03, 0xf7, 0x06, 0xf7,
11435         0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08,
11436         0x30, 0x13, 0x64, 0x15,
11437         0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c,
11438         0x04, 0xea, 0x5d, 0xf0,
11439         0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
11440         0xcc, 0x00, 0x20, 0x01,
11441         0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13,
11442         0x40, 0x13, 0x30, 0x1c,
11443         0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
11444         0x59, 0xf0, 0xa7, 0xf0,
11445         0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
11446         0xa4, 0x00, 0xb5, 0x00,
11447         0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a,
11448         0x14, 0x0e, 0x02, 0x10,
11449         0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13,
11450         0x10, 0x15, 0x14, 0x15,
11451         0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
11452         0x91, 0x44, 0x0a, 0x45,
11453         0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58,
11454         0x83, 0x59, 0x05, 0xe6,
11455         0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8,
11456         0x02, 0xfa, 0x03, 0xfa,
11457         0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
11458         0x9e, 0x00, 0xa8, 0x00,
11459         0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01,
11460         0x7a, 0x01, 0xc0, 0x01,
11461         0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08,
11462         0x69, 0x08, 0xba, 0x08,
11463         0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
11464         0xf1, 0x10, 0x06, 0x12,
11465         0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14,
11466         0x8a, 0x15, 0xc6, 0x17,
11467         0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
11468         0x0e, 0x47, 0x48, 0x47,
11469         0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
11470         0x14, 0x56, 0x77, 0x57,
11471         0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c,
11472         0xf0, 0x29, 0x02, 0xfe,
11473         0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf,
11474         0xfe, 0x80, 0x01, 0xff,
11475         0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
11476         0x00, 0xfe, 0x57, 0x24,
11477         0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09,
11478         0x00, 0x00, 0xff, 0x08,
11479         0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
11480         0xff, 0xff, 0xff, 0x0f,
11481         0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
11482         0xfe, 0x04, 0xf7, 0xcf,
11483         0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67,
11484         0x0b, 0x3c, 0x2a, 0xfe,
11485         0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0,
11486         0xfe, 0xf0, 0x01, 0xfe,
11487         0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
11488         0x02, 0xfe, 0xd4, 0x0c,
11489         0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
11490         0x1c, 0x05, 0xfe, 0xa6,
11491         0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48,
11492         0xf0, 0xfe, 0x86, 0x02,
11493         0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
11494         0xfe, 0x46, 0xf0, 0xfe,
11495         0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
11496         0x44, 0x02, 0xfe, 0x44,
11497         0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b,
11498         0xa0, 0x17, 0x06, 0x18,
11499         0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
11500         0x1e, 0x1c, 0xfe, 0xe9,
11501         0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7,
11502         0x0a, 0x6b, 0x01, 0x9e,
11503         0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b,
11504         0x01, 0x82, 0xfe, 0xbd,
11505         0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
11506         0x58, 0x1c, 0x17, 0x06,
11507         0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21,
11508         0xfe, 0x94, 0x02, 0xfe,
11509         0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97,
11510         0x01, 0xfe, 0x54, 0x0f,
11511         0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
11512         0x69, 0x10, 0x17, 0x06,
11513         0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05,
11514         0xf6, 0xc7, 0x01, 0xfe,
11515         0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6,
11516         0x02, 0x29, 0x0a, 0x40,
11517         0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
11518         0x58, 0x0a, 0x99, 0x01,
11519         0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29,
11520         0x2a, 0x46, 0xfe, 0x02,
11521         0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc,
11522         0x01, 0xfe, 0x07, 0x4b,
11523         0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
11524         0xfe, 0x56, 0x03, 0xfe,
11525         0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10,
11526         0xfe, 0x9f, 0xf0, 0xfe,
11527         0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48,
11528         0x1c, 0xeb, 0x09, 0x04,
11529         0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
11530         0x01, 0x0e, 0xac, 0x75,
11531         0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2,
11532         0xfe, 0x82, 0xf0, 0xfe,
11533         0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25,
11534         0x32, 0x1f, 0xfe, 0xb4,
11535         0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
11536         0x0a, 0xf0, 0xfe, 0x7a,
11537         0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c,
11538         0x01, 0x33, 0x8f, 0xfe,
11539         0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8,
11540         0xf7, 0xfe, 0x48, 0x1c,
11541         0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
11542         0x0a, 0xca, 0x01, 0x0e,
11543         0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14,
11544         0x2c, 0x01, 0x33, 0x8f,
11545         0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65,
11546         0xfe, 0x3c, 0x04, 0x1f,
11547         0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
11548         0x12, 0x2b, 0xff, 0x02,
11549         0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f,
11550         0x22, 0x30, 0x2e, 0xd5,
11551         0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c,
11552         0xfe, 0x4c, 0x54, 0x64,
11553         0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
11554         0xfe, 0x2a, 0x13, 0x2f,
11555         0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
11556         0xd3, 0xfa, 0xef, 0x86,
11557         0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04,
11558         0x1d, 0xfe, 0x1c, 0x12,
11559         0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
11560         0x70, 0x0c, 0x02, 0x22,
11561         0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92,
11562         0x01, 0x33, 0x02, 0x29,
11563         0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87,
11564         0x80, 0xfe, 0x31, 0xe4,
11565         0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
11566         0xfe, 0x70, 0x12, 0x49,
11567         0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe,
11568         0x80, 0x05, 0xfe, 0x31,
11569         0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00,
11570         0x28, 0xfe, 0x42, 0x12,
11571         0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
11572         0x11, 0xfe, 0xe3, 0x00,
11573         0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
11574         0x64, 0x05, 0x83, 0x24,
11575         0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe,
11576         0x09, 0x48, 0x01, 0x08,
11577         0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
11578         0x86, 0x24, 0x06, 0x12,
11579         0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47,
11580         0x01, 0xa7, 0x14, 0x92,
11581         0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c,
11582         0x02, 0x22, 0x05, 0xfe,
11583         0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
11584         0x47, 0x01, 0xa7, 0x26,
11585         0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f,
11586         0x01, 0xfe, 0xaa, 0x14,
11587         0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00,
11588         0x05, 0x50, 0xb4, 0x0c,
11589         0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
11590         0x13, 0x01, 0xfe, 0x14,
11591         0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c,
11592         0xff, 0x02, 0x00, 0x57,
11593         0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe,
11594         0x72, 0x06, 0x49, 0x04,
11595         0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
11596         0x06, 0x11, 0x9a, 0x01,
11597         0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06,
11598         0x01, 0xa7, 0xec, 0x72,
11599         0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32,
11600         0xfe, 0x0a, 0xf0, 0xfe,
11601         0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
11602         0x8d, 0x81, 0x02, 0x22,
11603         0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00,
11604         0x01, 0x08, 0x15, 0x00,
11605         0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15,
11606         0x00, 0x02, 0xfe, 0x32,
11607         0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
11608         0xfe, 0x1b, 0x00, 0x01,
11609         0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
11610         0x08, 0x15, 0x06, 0x01,
11611         0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe,
11612         0x9a, 0x81, 0x4b, 0x1d,
11613         0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
11614         0x45, 0xfe, 0x32, 0x12,
11615         0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0,
11616         0xfe, 0x32, 0x07, 0x8d,
11617         0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a,
11618         0x06, 0x15, 0x19, 0x02,
11619         0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
11620         0x90, 0x77, 0xfe, 0xca,
11621         0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07,
11622         0x10, 0xfe, 0x0e, 0x12,
11623         0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe,
11624         0x83, 0xe7, 0xc4, 0xa1,
11625         0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
11626         0x40, 0x12, 0x58, 0x01,
11627         0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6,
11628         0x51, 0x83, 0xfb, 0xfe,
11629         0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90,
11630         0xfe, 0x40, 0x50, 0xfe,
11631         0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
11632         0xfe, 0x2a, 0x12, 0xfe,
11633         0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f,
11634         0x85, 0x01, 0xa8, 0xfe,
11635         0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56,
11636         0x18, 0x57, 0xfb, 0xfe,
11637         0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
11638         0x0c, 0x39, 0x18, 0x3a,
11639         0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e,
11640         0x11, 0x65, 0xfe, 0x48,
11641         0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73,
11642         0xdd, 0xb8, 0xfe, 0x80,
11643         0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
11644         0xfe, 0x7a, 0x08, 0x8d,
11645         0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9,
11646         0x10, 0x61, 0x04, 0x06,
11647         0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68,
11648         0x12, 0xfe, 0x2e, 0x1c,
11649         0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
11650         0x52, 0x12, 0xfe, 0x2c,
11651         0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe,
11652         0x08, 0xfe, 0x8a, 0x10,
11653         0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe,
11654         0x24, 0x0a, 0xab, 0xfe,
11655         0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
11656         0x1c, 0x12, 0xb5, 0xfe,
11657         0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb,
11658         0x1c, 0x06, 0x16, 0x9d,
11659         0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b,
11660         0x14, 0x92, 0x01, 0x33,
11661         0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
11662         0xfe, 0x74, 0x18, 0x1c,
11663         0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b,
11664         0x01, 0xe6, 0x1e, 0x27,
11665         0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a,
11666         0x09, 0x04, 0x6a, 0xfe,
11667         0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
11668         0xfe, 0x83, 0x80, 0xfe,
11669         0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63,
11670         0x27, 0xfe, 0x40, 0x59,
11671         0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18,
11672         0x7c, 0xbe, 0x54, 0xbf,
11673         0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
11674         0x79, 0x56, 0x68, 0x57,
11675         0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5,
11676         0xa2, 0x23, 0x0c, 0x7b,
11677         0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19,
11678         0x16, 0xd7, 0x79, 0x39,
11679         0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
11680         0xfe, 0x10, 0x58, 0xfe,
11681         0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04,
11682         0x19, 0x16, 0xd7, 0x09,
11683         0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f,
11684         0xfe, 0x10, 0x90, 0xfe,
11685         0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
11686         0x11, 0x9b, 0x09, 0x04,
11687         0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08,
11688         0xfe, 0x0c, 0x58, 0xfe,
11689         0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04,
11690         0x0b, 0xfe, 0x1a, 0x12,
11691         0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
11692         0x14, 0x7a, 0x01, 0x33,
11693         0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39,
11694         0xfe, 0xed, 0x19, 0xbf,
11695         0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff,
11696         0x34, 0xfe, 0x74, 0x10,
11697         0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
11698         0x84, 0x05, 0xcb, 0x1c,
11699         0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1,
11700         0xf0, 0xfe, 0xc4, 0x0a,
11701         0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe,
11702         0xce, 0xf0, 0xfe, 0xca,
11703         0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
11704         0x22, 0x00, 0x02, 0x5a,
11705         0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a,
11706         0xfe, 0xd0, 0xf0, 0xfe,
11707         0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f,
11708         0x4c, 0xfe, 0x10, 0x10,
11709         0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
11710         0x2a, 0x13, 0xfe, 0x4e,
11711         0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1,
11712         0x16, 0x32, 0x2a, 0x73,
11713         0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25,
11714         0x32, 0x8c, 0xfe, 0x48,
11715         0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
11716         0xdb, 0x10, 0x11, 0xfe,
11717         0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0,
11718         0x22, 0x30, 0x2e, 0xd8,
11719         0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1,
11720         0x45, 0x0f, 0xfe, 0x42,
11721         0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
11722         0x09, 0x04, 0x0b, 0xfe,
11723         0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28,
11724         0x00, 0x21, 0xfe, 0xa6,
11725         0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00,
11726         0xfe, 0xe2, 0x10, 0x01,
11727         0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
11728         0x01, 0x6f, 0x02, 0x29,
11729         0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10,
11730         0x01, 0x86, 0x3e, 0x0b,
11731         0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3,
11732         0x3e, 0x0b, 0x0f, 0xfe,
11733         0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
11734         0xe8, 0x59, 0x11, 0x2d,
11735         0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09,
11736         0x04, 0x0b, 0x84, 0x3e,
11737         0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12,
11738         0x09, 0x04, 0x1b, 0xfe,
11739         0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
11740         0x1c, 0x1c, 0xfe, 0x9d,
11741         0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f,
11742         0xfe, 0x15, 0x00, 0xfe,
11743         0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10,
11744         0x0f, 0xfe, 0x47, 0x00,
11745         0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
11746         0xab, 0x70, 0x05, 0x6b,
11747         0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe,
11748         0x1c, 0x42, 0x59, 0x01,
11749         0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31,
11750         0x00, 0x37, 0x97, 0x01,
11751         0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
11752         0x1d, 0xfe, 0xce, 0x45,
11753         0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75,
11754         0x57, 0x05, 0x51, 0xfe,
11755         0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48,
11756         0x46, 0x09, 0x04, 0x1d,
11757         0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
11758         0x99, 0x01, 0x0e, 0xfe,
11759         0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51,
11760         0xfe, 0xee, 0x14, 0xee,
11761         0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad,
11762         0x13, 0x02, 0x29, 0x1e,
11763         0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
11764         0xce, 0x1e, 0x2d, 0x47,
11765         0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06,
11766         0x12, 0x4d, 0x01, 0xfe,
11767         0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe,
11768         0xf0, 0x0d, 0xfe, 0x02,
11769         0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
11770         0xf6, 0xfe, 0x34, 0x01,
11771         0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13,
11772         0xaf, 0xfe, 0x02, 0xea,
11773         0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c,
11774         0x05, 0xfe, 0x38, 0x01,
11775         0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
11776         0x0c, 0xfe, 0x62, 0x01,
11777         0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06,
11778         0x03, 0x23, 0x03, 0x1e,
11779         0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe,
11780         0x71, 0x13, 0xfe, 0x24,
11781         0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
11782         0xdc, 0xfe, 0x73, 0x57,
11783         0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe,
11784         0x80, 0x5d, 0x03, 0xfe,
11785         0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6,
11786         0x75, 0x03, 0x09, 0x04,
11787         0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
11788         0xfe, 0x1e, 0x80, 0xe1,
11789         0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e,
11790         0x90, 0xa3, 0xfe, 0x3c,
11791         0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82,
11792         0x16, 0x2f, 0x07, 0x2d,
11793         0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
11794         0xe8, 0x11, 0xfe, 0xe9,
11795         0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe,
11796         0x1e, 0x1c, 0xfe, 0x14,
11797         0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01,
11798         0x09, 0x04, 0x4f, 0xfe,
11799         0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
11800         0x40, 0x12, 0x20, 0x63,
11801         0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08,
11802         0x1c, 0x05, 0xfe, 0xac,
11803         0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05,
11804         0xfe, 0xb0, 0x00, 0xfe,
11805         0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
11806         0x24, 0x69, 0x12, 0xc9,
11807         0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe,
11808         0x90, 0x4d, 0xfe, 0x91,
11809         0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c,
11810         0xfe, 0x90, 0x4d, 0xfe,
11811         0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
11812         0x46, 0x1e, 0x20, 0xed,
11813         0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea,
11814         0x70, 0xfe, 0x14, 0x1c,
11815         0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee,
11816         0xfe, 0x07, 0xe6, 0x1d,
11817         0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
11818         0xfa, 0xef, 0xfe, 0x42,
11819         0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0,
11820         0xfe, 0x36, 0x12, 0xf0,
11821         0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
11822         0x3d, 0x75, 0x07, 0x10,
11823         0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
11824         0x10, 0x07, 0x7e, 0x45,
11825         0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74,
11826         0xfe, 0x01, 0xec, 0x97,
11827         0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76,
11828         0x27, 0x01, 0xda, 0xfe,
11829         0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
11830         0xfe, 0x48, 0x12, 0x07,
11831         0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16,
11832         0xfe, 0x3e, 0x11, 0x07,
11833         0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8,
11834         0x11, 0x07, 0x19, 0xfe,
11835         0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
11836         0x01, 0x08, 0x8c, 0x43,
11837         0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11,
11838         0x7e, 0x02, 0x29, 0x2b,
11839         0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe,
11840         0xfc, 0x10, 0x09, 0x04,
11841         0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
11842         0xc6, 0x10, 0x1e, 0x58,
11843         0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c,
11844         0x54, 0x18, 0x55, 0x23,
11845         0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01,
11846         0xa5, 0xc0, 0x38, 0xc1,
11847         0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
11848         0x05, 0xfa, 0x4e, 0xfe,
11849         0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56,
11850         0x0c, 0x56, 0x18, 0x57,
11851         0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe,
11852         0x00, 0x56, 0xfe, 0xa1,
11853         0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
11854         0x58, 0xfe, 0x1f, 0x40,
11855         0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56,
11856         0x31, 0x57, 0xfe, 0x44,
11857         0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe,
11858         0x8a, 0x50, 0x05, 0x39,
11859         0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
11860         0x12, 0xcd, 0x02, 0x5b,
11861         0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44,
11862         0x2f, 0x07, 0x9b, 0x21,
11863         0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79,
11864         0x39, 0x68, 0x3a, 0xfe,
11865         0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
11866         0x51, 0xfe, 0x8e, 0x51,
11867         0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b,
11868         0x01, 0x08, 0x25, 0x32,
11869         0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b,
11870         0x3b, 0x02, 0x44, 0x01,
11871         0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
11872         0x01, 0x08, 0x1f, 0xa2,
11873         0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c,
11874         0x00, 0x28, 0x84, 0x49,
11875         0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06,
11876         0x78, 0x3d, 0xfe, 0xda,
11877         0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
11878         0x05, 0xc6, 0x28, 0x84,
11879         0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8,
11880         0x14, 0xfe, 0x03, 0x17,
11881         0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01,
11882         0xfe, 0xaa, 0x14, 0x02,
11883         0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
11884         0x21, 0x44, 0x01, 0xfe,
11885         0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87,
11886         0xfe, 0x4a, 0xf4, 0x0b,
11887         0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a,
11888         0x85, 0x02, 0x5b, 0x05,
11889         0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
11890         0xd8, 0x14, 0x02, 0x5c,
11891         0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1,
11892         0x01, 0x08, 0x23, 0x72,
11893         0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca,
11894         0x12, 0x5e, 0x2b, 0x01,
11895         0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
11896         0x1c, 0xfe, 0xff, 0x7f,
11897         0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00,
11898         0x57, 0x48, 0x8b, 0x1c,
11899         0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02,
11900         0x00, 0x57, 0x48, 0x8b,
11901         0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
11902         0x03, 0x0a, 0x50, 0x01,
11903         0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00,
11904         0x54, 0xfe, 0x00, 0xf4,
11905         0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe,
11906         0x03, 0x7c, 0x63, 0x27,
11907         0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
11908         0xfe, 0x82, 0x4a, 0xfe,
11909         0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe,
11910         0x42, 0x48, 0x5f, 0x60,
11911         0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08,
11912         0x1f, 0xfe, 0xa2, 0x14,
11913         0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
11914         0xcc, 0x12, 0x49, 0x04,
11915         0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe,
11916         0xe8, 0x13, 0x3b, 0x13,
11917         0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55,
11918         0xa1, 0xff, 0x02, 0x83,
11919         0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
11920         0x13, 0x06, 0xfe, 0x56,
11921         0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe,
11922         0x64, 0x00, 0x17, 0x93,
11923         0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe,
11924         0xc8, 0x00, 0x8e, 0xe4,
11925         0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
11926         0x01, 0xba, 0xfe, 0x4e,
11927         0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0,
11928         0xfe, 0x60, 0x14, 0xfe,
11929         0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01,
11930         0xfe, 0x22, 0x13, 0x1c,
11931         0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
11932         0xfe, 0x9c, 0x14, 0xb7,
11933         0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba,
11934         0xfe, 0x9c, 0x14, 0xb7,
11935         0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06,
11936         0xfe, 0xb4, 0x56, 0xfe,
11937         0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
11938         0xe5, 0x15, 0x0b, 0x01,
11939         0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89,
11940         0x49, 0x01, 0x08, 0x03,
11941         0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6,
11942         0x15, 0x06, 0x01, 0x08,
11943         0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
11944         0x4a, 0x01, 0x08, 0x03,
11945         0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc,
11946         0xfe, 0x49, 0xf4, 0x00,
11947         0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01,
11948         0x08, 0x2f, 0x07, 0xfe,
11949         0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
11950         0x01, 0x43, 0x1e, 0xcd,
11951         0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e,
11952         0xed, 0x88, 0x07, 0x10,
11953         0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a,
11954         0x80, 0x01, 0x0e, 0x88,
11955         0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
11956         0x88, 0x03, 0x0a, 0x42,
11957         0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e,
11958         0xfe, 0x80, 0x80, 0xf2,
11959         0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51,
11960         0x01, 0x82, 0x03, 0x17,
11961         0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
11962         0xfe, 0x24, 0x1c, 0xfe,
11963         0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0,
11964         0x91, 0x1d, 0x66, 0xfe,
11965         0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe,
11966         0xda, 0x10, 0x17, 0x10,
11967         0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
11968         0x05, 0xfe, 0x66, 0x01,
11969         0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06,
11970         0xfe, 0x3c, 0x50, 0x66,
11971         0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe,
11972         0x40, 0x16, 0xfe, 0xb6,
11973         0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
11974         0x10, 0x71, 0xfe, 0x83,
11975         0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90,
11976         0xfe, 0x62, 0x16, 0xfe,
11977         0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19,
11978         0xfe, 0x98, 0xe7, 0x00,
11979         0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
11980         0xfe, 0x30, 0xbc, 0xfe,
11981         0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
11982         0xc5, 0x90, 0xfe, 0x9a,
11983         0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe,
11984         0x42, 0x10, 0xfe, 0x02,
11985         0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
11986         0xfe, 0x1d, 0xf7, 0x4f,
11987         0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f,
11988         0x47, 0xfe, 0x83, 0x58,
11989         0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11,
11990         0xfe, 0xdd, 0x00, 0x63,
11991         0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
11992         0x06, 0x37, 0x95, 0xa9,
11993         0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e,
11994         0x18, 0x1c, 0x1a, 0x5d,
11995         0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe,
11996         0xe1, 0x10, 0x78, 0x2c,
11997         0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
11998         0x13, 0x3c, 0x8a, 0x0a,
11999         0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
12000         0xe3, 0xfe, 0x00, 0xcc,
12001         0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01,
12002         0x0e, 0xf2, 0x01, 0x6f,
12003         0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
12004         0xf6, 0xfe, 0xd6, 0xf0,
12005         0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe,
12006         0x15, 0x00, 0x59, 0x76,
12007         0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35,
12008         0x11, 0x2d, 0x01, 0x6f,
12009         0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
12010         0xc8, 0xfe, 0x48, 0x55,
12011         0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a,
12012         0x99, 0x01, 0x0e, 0xf0,
12013         0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73,
12014         0x75, 0x03, 0x0a, 0x42,
12015         0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
12016         0x0e, 0x73, 0x75, 0x03,
12017         0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00,
12018         0xfe, 0x3a, 0x45, 0x5b,
12019         0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00,
12020         0xfe, 0x02, 0xe6, 0x1b,
12021         0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
12022         0xfe, 0x94, 0x00, 0xfe,
12023         0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02,
12024         0xe6, 0x2c, 0xfe, 0x4e,
12025         0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69,
12026         0x03, 0x07, 0x7a, 0xfe,
12027         0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
12028         0x07, 0x1b, 0xfe, 0x5a,
12029         0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d,
12030         0x24, 0x2c, 0xdc, 0x07,
12031         0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d,
12032         0x9f, 0xad, 0x03, 0x14,
12033         0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
12034         0x03, 0x25, 0xfe, 0xca,
12035         0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a,
12036         0x00, 0x00,
12037 };
12038
12039 static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf);     /* 0x13AD */
12040 static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL;     /* Expanded little-endian checksum. */
12041
12042 /* Microcode buffer is kept after initialization for error recovery. */
12043 static unsigned char _adv_asc38C0800_buf[] = {
12044         0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
12045         0x01, 0x00, 0x48, 0xe4,
12046         0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff,
12047         0x1c, 0x0f, 0x00, 0xf6,
12048         0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6,
12049         0x09, 0xe7, 0x55, 0xf0,
12050         0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
12051         0x18, 0xf4, 0x08, 0x00,
12052         0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6,
12053         0x86, 0xf0, 0xb1, 0xf0,
12054         0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c,
12055         0x3c, 0x00, 0xbb, 0x00,
12056         0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
12057         0xba, 0x13, 0x18, 0x40,
12058         0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01,
12059         0x6e, 0x01, 0x74, 0x01,
12060         0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00,
12061         0xc0, 0x00, 0x01, 0x01,
12062         0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
12063         0x08, 0x12, 0x02, 0x4a,
12064         0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4,
12065         0x5d, 0xf0, 0x02, 0xfa,
12066         0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01,
12067         0x68, 0x01, 0x6a, 0x01,
12068         0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
12069         0x06, 0x13, 0x4c, 0x1c,
12070         0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00,
12071         0x0f, 0x00, 0x47, 0x00,
12072         0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c,
12073         0x4e, 0x1c, 0x10, 0x44,
12074         0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
12075         0x05, 0x00, 0x34, 0x00,
12076         0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b,
12077         0x42, 0x0c, 0x12, 0x0f,
12078         0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48,
12079         0x00, 0x4e, 0x42, 0x54,
12080         0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
12081         0x59, 0xf0, 0xb8, 0xf0,
12082         0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00,
12083         0x19, 0x00, 0x33, 0x00,
12084         0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00,
12085         0xe7, 0x00, 0xe2, 0x03,
12086         0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
12087         0x12, 0x13, 0x24, 0x14,
12088         0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c,
12089         0x36, 0x1c, 0x08, 0x44,
12090         0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54,
12091         0x3a, 0x55, 0x83, 0x55,
12092         0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
12093         0x0c, 0xf0, 0x04, 0xf8,
12094         0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00,
12095         0xa8, 0x00, 0xaa, 0x00,
12096         0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01,
12097         0xc4, 0x01, 0xc6, 0x01,
12098         0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
12099         0x68, 0x08, 0x69, 0x08,
12100         0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10,
12101         0xed, 0x10, 0xf1, 0x10,
12102         0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13,
12103         0x1e, 0x13, 0x46, 0x14,
12104         0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
12105         0xca, 0x18, 0xe6, 0x19,
12106         0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c,
12107         0xf0, 0x2b, 0x02, 0xfe,
12108         0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6,
12109         0xfe, 0x84, 0x01, 0xff,
12110         0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
12111         0x00, 0xfe, 0x57, 0x24,
12112         0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09,
12113         0x00, 0x00, 0xff, 0x08,
12114         0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
12115         0xff, 0xff, 0xff, 0x11,
12116         0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
12117         0xfe, 0x04, 0xf7, 0xd6,
12118         0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99,
12119         0x0a, 0x42, 0x2c, 0xfe,
12120         0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0,
12121         0xfe, 0xf4, 0x01, 0xfe,
12122         0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
12123         0x02, 0xfe, 0xc8, 0x0d,
12124         0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
12125         0x1c, 0x03, 0xfe, 0xa6,
12126         0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48,
12127         0xf0, 0xfe, 0x8a, 0x02,
12128         0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
12129         0xfe, 0x46, 0xf0, 0xfe,
12130         0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
12131         0x48, 0x02, 0xfe, 0x44,
12132         0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a,
12133         0xaa, 0x18, 0x06, 0x14,
12134         0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
12135         0x1e, 0x1c, 0xfe, 0xe9,
12136         0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce,
12137         0x09, 0x70, 0x01, 0xa8,
12138         0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70,
12139         0x01, 0x87, 0xfe, 0xbd,
12140         0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
12141         0x58, 0x1c, 0x18, 0x06,
12142         0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23,
12143         0xfe, 0x98, 0x02, 0xfe,
12144         0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2,
12145         0x01, 0xfe, 0x48, 0x10,
12146         0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
12147         0x69, 0x10, 0x18, 0x06,
12148         0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05,
12149         0xf6, 0xce, 0x01, 0xfe,
12150         0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe,
12151         0x82, 0x16, 0x02, 0x2b,
12152         0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
12153         0xfe, 0x41, 0x58, 0x09,
12154         0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe,
12155         0x82, 0x16, 0x02, 0x2b,
12156         0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43,
12157         0xfe, 0x77, 0x57, 0xfe,
12158         0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
12159         0xfe, 0x40, 0x1c, 0x1c,
12160         0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48,
12161         0x03, 0xfe, 0x11, 0xf0,
12162         0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10,
12163         0xfe, 0x11, 0x00, 0x02,
12164         0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
12165         0x21, 0x22, 0xa3, 0xb7,
12166         0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16,
12167         0x12, 0xd1, 0x1c, 0xd9,
12168         0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12,
12169         0xfe, 0xe4, 0x00, 0x27,
12170         0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
12171         0x06, 0xf0, 0xfe, 0xc8,
12172         0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03,
12173         0x70, 0x28, 0x17, 0xfe,
12174         0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8,
12175         0xf9, 0x2c, 0x99, 0x19,
12176         0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
12177         0x74, 0x01, 0xaf, 0x8c,
12178         0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e,
12179         0x8d, 0x51, 0x64, 0x79,
12180         0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b,
12181         0xfe, 0x6a, 0x02, 0x02,
12182         0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
12183         0xfe, 0x3c, 0x04, 0x3b,
12184         0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02,
12185         0x00, 0x10, 0x01, 0x0b,
12186         0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde,
12187         0xfe, 0x4c, 0x44, 0xfe,
12188         0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
12189         0xda, 0x4f, 0x79, 0x2a,
12190         0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b,
12191         0xfe, 0x2a, 0x13, 0x32,
12192         0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c,
12193         0x54, 0x6b, 0xda, 0xfe,
12194         0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
12195         0x08, 0x13, 0x32, 0x07,
12196         0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d,
12197         0x08, 0x05, 0x06, 0x4d,
12198         0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24,
12199         0x2d, 0x12, 0xfe, 0xe6,
12200         0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
12201         0x02, 0x2b, 0xfe, 0x42,
12202         0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
12203         0xfe, 0x87, 0x80, 0xfe,
12204         0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80,
12205         0x07, 0x19, 0xfe, 0x7c,
12206         0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
12207         0x17, 0xfe, 0x90, 0x05,
12208         0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe,
12209         0xa0, 0x00, 0x28, 0xfe,
12210         0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c,
12211         0x34, 0xfe, 0x89, 0x48,
12212         0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
12213         0x12, 0xfe, 0xe3, 0x00,
12214         0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
12215         0x70, 0x05, 0x88, 0x25,
12216         0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe,
12217         0x09, 0x48, 0xff, 0x02,
12218         0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
12219         0x08, 0x53, 0x05, 0xcb,
12220         0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08,
12221         0x05, 0x1b, 0xfe, 0x22,
12222         0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe,
12223         0x0d, 0x00, 0x01, 0x36,
12224         0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
12225         0x03, 0x5c, 0x28, 0xfe,
12226         0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53,
12227         0x05, 0x1f, 0xfe, 0x02,
12228         0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5,
12229         0x01, 0x4b, 0x12, 0xfe,
12230         0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
12231         0x12, 0x03, 0x45, 0x28,
12232         0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe,
12233         0x43, 0x48, 0xc4, 0xcc,
12234         0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4,
12235         0x6e, 0x41, 0x01, 0xb2,
12236         0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
12237         0xfe, 0xcc, 0x15, 0x1d,
12238         0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03,
12239         0x45, 0xc1, 0x0c, 0x45,
12240         0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe,
12241         0xe2, 0x00, 0x27, 0xdb,
12242         0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
12243         0xfe, 0x06, 0xf0, 0xfe,
12244         0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12,
12245         0x16, 0x19, 0x01, 0x0b,
12246         0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
12247         0xfe, 0x99, 0xa4, 0x01,
12248         0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
12249         0x12, 0x08, 0x05, 0x1a,
12250         0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
12251         0x0b, 0x16, 0x00, 0x01,
12252         0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02,
12253         0xe2, 0x6c, 0x58, 0xbe,
12254         0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
12255         0xfe, 0x09, 0x6f, 0xba,
12256         0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27,
12257         0xfe, 0x54, 0x07, 0x1c,
12258         0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c,
12259         0x07, 0x02, 0x24, 0x01,
12260         0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
12261         0x2c, 0x90, 0xfe, 0xae,
12262         0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a,
12263         0x37, 0x22, 0x20, 0x07,
12264         0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a,
12265         0xfe, 0x06, 0x10, 0xfe,
12266         0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
12267         0x37, 0x01, 0xb3, 0xb8,
12268         0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a,
12269         0x50, 0xfe, 0x44, 0x51,
12270         0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e,
12271         0x14, 0x5f, 0xfe, 0x0c,
12272         0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
12273         0x14, 0x3e, 0xfe, 0x4a,
12274         0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
12275         0x90, 0x0c, 0x60, 0x14,
12276         0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62,
12277         0xfe, 0x44, 0x90, 0xfe,
12278         0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
12279         0x0c, 0x5e, 0x14, 0x5f,
12280         0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e,
12281         0x14, 0x3c, 0x21, 0x0c,
12282         0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11,
12283         0x27, 0xdd, 0xfe, 0x9e,
12284         0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
12285         0x9a, 0x08, 0xc6, 0xfe,
12286         0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08,
12287         0x95, 0x86, 0x02, 0x24,
12288         0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05,
12289         0x06, 0xfe, 0x10, 0x12,
12290         0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
12291         0x1c, 0x02, 0xfe, 0x18,
12292         0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe,
12293         0x2c, 0x1c, 0xfe, 0xaa,
12294         0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe,
12295         0xde, 0x09, 0xfe, 0xb7,
12296         0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
12297         0xfe, 0xf1, 0x18, 0xfe,
12298         0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe,
12299         0x14, 0x59, 0xfe, 0x95,
12300         0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0,
12301         0xfe, 0xf0, 0x08, 0xb5,
12302         0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
12303         0x0b, 0xb6, 0xfe, 0xbf,
12304         0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c,
12305         0x12, 0xc2, 0xfe, 0xd2,
12306         0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e,
12307         0x06, 0x17, 0x85, 0xc5,
12308         0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
12309         0x9d, 0x01, 0x36, 0x10,
12310         0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe,
12311         0x98, 0x80, 0xfe, 0x19,
12312         0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18,
12313         0xfe, 0x44, 0x54, 0xbe,
12314         0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
12315         0x02, 0x4a, 0x08, 0x05,
12316         0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e,
12317         0x9c, 0x3c, 0xfe, 0x6c,
12318         0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f,
12319         0x3b, 0x40, 0x03, 0x49,
12320         0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
12321         0x8f, 0xfe, 0xe3, 0x54,
12322         0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe,
12323         0xda, 0x09, 0xfe, 0x8b,
12324         0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa,
12325         0x0a, 0x3a, 0x49, 0x3b,
12326         0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
12327         0xad, 0xfe, 0x01, 0x59,
12328         0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a,
12329         0x49, 0x8f, 0xfe, 0xe3,
12330         0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02,
12331         0x4a, 0x3a, 0x49, 0x3b,
12332         0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
12333         0x02, 0x4a, 0x08, 0x05,
12334         0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62,
12335         0xb7, 0xfe, 0x03, 0xa1,
12336         0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
12337         0xfe, 0x86, 0x91, 0x6a,
12338         0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
12339         0x61, 0x0c, 0x7f, 0x14,
12340         0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62,
12341         0x9b, 0x2e, 0x9c, 0x3c,
12342         0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05,
12343         0xfa, 0x3c, 0x01, 0xef,
12344         0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
12345         0xe4, 0x08, 0x05, 0x1f,
12346         0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37,
12347         0x03, 0x5e, 0x29, 0x5f,
12348         0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe,
12349         0xf4, 0x09, 0x08, 0x05,
12350         0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
12351         0x81, 0x50, 0xfe, 0x10,
12352         0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe,
12353         0x08, 0x09, 0x12, 0xa6,
12354         0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe,
12355         0x08, 0x09, 0xfe, 0x0c,
12356         0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
12357         0x08, 0x05, 0x0a, 0xfe,
12358         0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1,
12359         0xf0, 0xe2, 0x15, 0x7e,
12360         0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19,
12361         0x57, 0x3d, 0xfe, 0xed,
12362         0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
12363         0x00, 0xff, 0x35, 0xfe,
12364         0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18,
12365         0x1e, 0x19, 0x8a, 0x03,
12366         0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65,
12367         0xfe, 0xd1, 0xf0, 0xfe,
12368         0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
12369         0x10, 0xfe, 0xce, 0xf0,
12370         0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b,
12371         0x10, 0xfe, 0x22, 0x00,
12372         0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00,
12373         0x02, 0x65, 0xfe, 0xd0,
12374         0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
12375         0x0b, 0x10, 0x58, 0xfe,
12376         0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe,
12377         0x12, 0x00, 0x2c, 0x0f,
12378         0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14,
12379         0x0c, 0xbc, 0x17, 0x34,
12380         0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
12381         0x0c, 0x1c, 0x34, 0x94,
12382         0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01,
12383         0x4b, 0xfe, 0xdb, 0x10,
12384         0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe,
12385         0x89, 0xf0, 0x24, 0x33,
12386         0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
12387         0x33, 0x31, 0xdf, 0xbc,
12388         0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49,
12389         0x17, 0xfe, 0x2c, 0x0d,
12390         0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54,
12391         0x12, 0x55, 0xfe, 0x28,
12392         0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
12393         0x44, 0xfe, 0x28, 0x00,
12394         0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26,
12395         0x0f, 0x64, 0x12, 0x2f,
12396         0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44,
12397         0x0a, 0xfe, 0xb4, 0x10,
12398         0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
12399         0xfe, 0x34, 0x46, 0xac,
12400         0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a,
12401         0x37, 0x01, 0xf5, 0x01,
12402         0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02,
12403         0xfe, 0x2e, 0x03, 0x08,
12404         0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
12405         0x1a, 0xfe, 0x58, 0x12,
12406         0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
12407         0xfe, 0x50, 0x0d, 0xfe,
12408         0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37,
12409         0xfe, 0xa9, 0x10, 0x10,
12410         0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
12411         0xfe, 0x13, 0x00, 0xfe,
12412         0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe,
12413         0x24, 0x00, 0x8c, 0xb5,
12414         0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a,
12415         0xfe, 0x9d, 0x41, 0xfe,
12416         0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
12417         0xb4, 0x15, 0xfe, 0x31,
12418         0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06,
12419         0xec, 0xd0, 0xfc, 0x44,
12420         0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47,
12421         0x4b, 0x91, 0xfe, 0x75,
12422         0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
12423         0x0e, 0xfe, 0x44, 0x48,
12424         0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41,
12425         0xfe, 0x41, 0x58, 0x09,
12426         0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe,
12427         0x2e, 0x03, 0x09, 0x5d,
12428         0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
12429         0xce, 0x47, 0xfe, 0xad,
12430         0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13,
12431         0x59, 0x13, 0x9f, 0x13,
12432         0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe,
12433         0xe0, 0x0e, 0x0f, 0x06,
12434         0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
12435         0x3a, 0x01, 0x56, 0xfe,
12436         0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec,
12437         0x20, 0x4f, 0xfe, 0x05,
12438         0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe,
12439         0x48, 0xf4, 0x0d, 0xfe,
12440         0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
12441         0x15, 0x1a, 0x39, 0xa0,
12442         0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff,
12443         0x0c, 0xfe, 0x60, 0x01,
12444         0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25,
12445         0x06, 0x13, 0x2f, 0x12,
12446         0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
12447         0x22, 0x9f, 0xb7, 0x13,
12448         0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39,
12449         0xa0, 0xb4, 0xfe, 0xd9,
12450         0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04,
12451         0xc3, 0xfe, 0x03, 0xdc,
12452         0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
12453         0xfe, 0x00, 0xcc, 0x04,
12454         0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13,
12455         0xfe, 0x1c, 0x80, 0x07,
12456         0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae,
12457         0xfe, 0x0c, 0x90, 0xfe,
12458         0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
12459         0x0a, 0xfe, 0x3c, 0x50,
12460         0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4,
12461         0x16, 0x08, 0x05, 0x1b,
12462         0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58,
12463         0xfe, 0x2c, 0x13, 0x01,
12464         0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
12465         0x0c, 0xfe, 0x64, 0x01,
12466         0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03,
12467         0x80, 0x8d, 0xfe, 0x01,
12468         0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64,
12469         0x22, 0x20, 0xfb, 0x79,
12470         0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
12471         0x03, 0xfe, 0xae, 0x00,
12472
12473         0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe,
12474         0xb2, 0x00, 0xfe, 0x09,
12475         0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c,
12476         0x45, 0x0f, 0x46, 0x52,
12477         0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
12478         0x0f, 0x44, 0x11, 0x0f,
12479         0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4,
12480         0x25, 0x11, 0x13, 0x20,
12481         0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14,
12482         0x56, 0xfe, 0xd6, 0xf0,
12483         0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
12484         0x18, 0x1c, 0x04, 0x42,
12485         0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe,
12486         0xf5, 0x13, 0x04, 0x01,
12487         0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
12488         0x13, 0x32, 0x07, 0x2f,
12489         0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
12490         0x41, 0x48, 0xfe, 0x45,
12491         0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78,
12492         0x07, 0x11, 0xac, 0x09,
12493         0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07,
12494         0x82, 0x4e, 0xfe, 0x14,
12495         0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
12496         0xfe, 0x01, 0xec, 0xa2,
12497         0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79,
12498         0x2a, 0x01, 0xe3, 0xfe,
12499         0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a,
12500         0xfe, 0x48, 0x12, 0x07,
12501         0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
12502         0xfe, 0x32, 0x12, 0x07,
12503         0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07,
12504         0x1f, 0xfe, 0x12, 0x12,
12505         0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b,
12506         0x94, 0x4b, 0x04, 0x2d,
12507         0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
12508         0x32, 0x07, 0xa6, 0xfe,
12509         0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05,
12510         0x5a, 0xfe, 0x72, 0x12,
12511         0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62,
12512         0xfe, 0x26, 0x13, 0x03,
12513         0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
12514         0x0c, 0x7f, 0x0c, 0x80,
12515         0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c,
12516         0x3c, 0xfe, 0x04, 0x55,
12517         0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe,
12518         0x91, 0x10, 0x03, 0x3f,
12519         0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
12520         0x88, 0x9b, 0x2e, 0x9c,
12521         0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
12522         0x56, 0x0c, 0x5e, 0x14,
12523         0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40,
12524         0x03, 0x60, 0x29, 0x61,
12525         0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
12526         0x50, 0xfe, 0xc6, 0x50,
12527         0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d,
12528         0x29, 0x3e, 0xfe, 0x40,
12529         0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72,
12530         0x2d, 0x01, 0x0b, 0x1d,
12531         0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
12532         0x72, 0x01, 0xaf, 0x1e,
12533         0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe,
12534         0x0a, 0x55, 0x35, 0xfe,
12535         0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51,
12536         0x02, 0x72, 0xfe, 0x19,
12537         0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
12538         0x1d, 0xe8, 0x33, 0x31,
12539         0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01,
12540         0x0b, 0x1c, 0x34, 0x1d,
12541         0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8,
12542         0x33, 0x31, 0xfe, 0xe8,
12543         0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
12544         0x05, 0x1f, 0x35, 0xa9,
12545         0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda,
12546         0x14, 0x01, 0xaf, 0x8c,
12547         0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a,
12548         0x03, 0x45, 0x28, 0x35,
12549         0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
12550         0x03, 0x5c, 0xc1, 0x0c,
12551         0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02,
12552         0x89, 0x01, 0x0b, 0x1c,
12553         0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1,
12554         0xfe, 0x42, 0x58, 0xf1,
12555         0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
12556         0xf4, 0x06, 0xea, 0x32,
12557         0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d,
12558         0x01, 0x0b, 0x26, 0x89,
12559         0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13,
12560         0x26, 0xfe, 0xd4, 0x13,
12561         0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
12562         0x13, 0x1c, 0xfe, 0xd0,
12563         0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10,
12564         0x0f, 0x71, 0xff, 0x02,
12565         0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe,
12566         0x00, 0x5c, 0x04, 0x0f,
12567         0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
12568         0xfe, 0x00, 0x5c, 0x04,
12569         0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff,
12570         0x02, 0x00, 0x57, 0x52,
12571         0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01,
12572         0x87, 0x04, 0xfe, 0x03,
12573         0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
12574         0xfe, 0x00, 0x7d, 0xfe,
12575         0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e,
12576         0x14, 0x5f, 0x57, 0x3f,
12577         0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83,
12578         0x5a, 0x8d, 0x04, 0x01,
12579         0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
12580         0xfe, 0x96, 0x15, 0x33,
12581         0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8,
12582         0x0a, 0xfe, 0xc1, 0x59,
12583         0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13,
12584         0x21, 0x69, 0x1a, 0xee,
12585         0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
12586         0x30, 0xfe, 0x78, 0x10,
12587         0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae,
12588         0x98, 0xfe, 0x30, 0x00,
12589         0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed,
12590         0x98, 0xfe, 0x64, 0x00,
12591         0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
12592         0x10, 0x69, 0x06, 0xfe,
12593         0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00,
12594         0x18, 0x59, 0x0f, 0x06,
12595         0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe,
12596         0x43, 0xf4, 0x9f, 0xfe,
12597         0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
12598         0x9e, 0xfe, 0xf3, 0x10,
12599         0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00,
12600         0x17, 0xfe, 0x4d, 0xe4,
12601         0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00,
12602         0x17, 0xfe, 0x4d, 0xe4,
12603         0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
12604         0xf4, 0x00, 0xe9, 0x91,
12605         0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a,
12606         0x04, 0x16, 0x06, 0x01,
12607         0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01,
12608         0x0b, 0x26, 0xf3, 0x76,
12609         0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
12610         0x16, 0x19, 0x01, 0x0b,
12611         0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01,
12612         0x0b, 0x26, 0xb1, 0x76,
12613         0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06,
12614         0xfe, 0x48, 0x13, 0xb8,
12615         0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
12616         0xec, 0xfe, 0x27, 0x01,
12617         0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32,
12618         0x07, 0xfe, 0xe3, 0x00,
12619         0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b,
12620         0x22, 0xd4, 0x07, 0x06,
12621         0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
12622         0x07, 0x11, 0xae, 0x09,
12623         0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01,
12624         0x0e, 0x8e, 0xfe, 0x80,
12625         0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04,
12626         0x09, 0x48, 0x01, 0x0e,
12627         0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
12628         0x80, 0xfe, 0x80, 0x4c,
12629         0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c,
12630         0x09, 0x5d, 0x01, 0x87,
12631         0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe,
12632         0x19, 0xde, 0xfe, 0x24,
12633         0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
12634         0x17, 0xad, 0x9a, 0x1b,
12635         0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde,
12636         0x16, 0xfe, 0xda, 0x10,
12637         0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe,
12638         0x18, 0x58, 0x03, 0xfe,
12639         0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
12640         0xf4, 0x06, 0xfe, 0x3c,
12641         0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f,
12642         0x97, 0xfe, 0x38, 0x17,
12643         0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c,
12644         0x10, 0x18, 0x11, 0x75,
12645         0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
12646         0x2e, 0x97, 0xfe, 0x5a,
12647         0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19,
12648         0xfe, 0x98, 0xe7, 0x00,
12649         0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75,
12650         0xfe, 0x30, 0xbc, 0xfe,
12651         0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
12652         0xcb, 0x97, 0xfe, 0x92,
12653         0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe,
12654         0x42, 0x10, 0xfe, 0x02,
12655         0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe,
12656         0x03, 0xa1, 0xfe, 0x1d,
12657         0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
12658         0x9a, 0x5b, 0x41, 0xfe,
12659         0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7,
12660         0x11, 0x12, 0xfe, 0xdd,
12661         0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8,
12662         0x17, 0x15, 0x06, 0x39,
12663         0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
12664         0xfe, 0x7e, 0x18, 0x1e,
12665         0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef,
12666         0x12, 0xfe, 0xe1, 0x10,
12667         0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42,
12668         0x13, 0x42, 0x92, 0x09,
12669         0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
12670         0xf0, 0xfe, 0x00, 0xcc,
12671         0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01,
12672         0x0e, 0xfe, 0x80, 0x4c,
12673         0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe,
12674         0x24, 0x12, 0xfe, 0x14,
12675         0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
12676         0xe7, 0x0a, 0x10, 0xfe,
12677         0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92,
12678         0x08, 0x54, 0x1b, 0x37,
12679         0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba,
12680         0x90, 0x3a, 0xce, 0x3b,
12681         0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
12682         0x13, 0xa3, 0x04, 0x09,
12683         0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49,
12684         0x44, 0x17, 0xfe, 0xe8,
12685         0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09,
12686         0x5d, 0x01, 0xa8, 0x09,
12687         0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
12688         0x1c, 0x19, 0x03, 0xfe,
12689         0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9,
12690         0x6b, 0xfe, 0x2e, 0x19,
12691         0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4,
12692         0xfe, 0x0b, 0x00, 0x6b,
12693         0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
12694         0x08, 0x10, 0x03, 0xfe,
12695         0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff,
12696         0x04, 0x68, 0x54, 0xe7,
12697         0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe,
12698         0x1a, 0xf4, 0xfe, 0x00,
12699         0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
12700         0x04, 0x07, 0x7e, 0xfe,
12701         0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
12702         0x07, 0x1a, 0xfe, 0x5a,
12703         0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66,
12704         0x25, 0x6d, 0xe5, 0x07,
12705         0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
12706         0xa9, 0xb8, 0x04, 0x15,
12707         0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe,
12708         0x40, 0x5c, 0x04, 0x1c,
12709         0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b,
12710         0xf7, 0xfe, 0x82, 0xf0,
12711         0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
12712 };
12713
12714 static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf);       /* 0x14E1 */
12715 static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL;  /* Expanded little-endian checksum. */
12716
12717 /* Microcode buffer is kept after initialization for error recovery. */
12718 static unsigned char _adv_asc38C1600_buf[] = {
12719         0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
12720         0x18, 0xe4, 0x01, 0x00,
12721         0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00,
12722         0x07, 0x17, 0xc0, 0x5f,
12723         0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7,
12724         0x85, 0xf0, 0x86, 0xf0,
12725         0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
12726         0x98, 0x57, 0x01, 0xe6,
12727         0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d,
12728         0x38, 0x54, 0x32, 0xf0,
12729         0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4,
12730         0x00, 0xe6, 0xb1, 0xf0,
12731         0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
12732         0x06, 0x13, 0x0c, 0x1c,
12733         0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12,
12734         0xb9, 0x54, 0x00, 0x80,
12735         0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56,
12736         0x03, 0xe6, 0x01, 0xea,
12737         0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
12738         0x04, 0x13, 0xbb, 0x55,
12739         0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00,
12740         0xbb, 0x00, 0xc0, 0x00,
12741         0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12,
12742         0x4c, 0x1c, 0x4e, 0x1c,
12743         0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
12744         0x24, 0x01, 0x3c, 0x01,
12745         0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01,
12746         0x78, 0x01, 0x7c, 0x01,
12747         0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c,
12748         0x6e, 0x1e, 0x02, 0x48,
12749         0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
12750         0x03, 0xfc, 0x06, 0x00,
12751         0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a,
12752         0x30, 0x1c, 0x38, 0x1c,
12753         0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea,
12754         0x5d, 0xf0, 0xa7, 0xf0,
12755         0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
12756         0x33, 0x00, 0x34, 0x00,
12757         0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01,
12758         0x79, 0x01, 0x3c, 0x09,
12759         0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13,
12760         0x40, 0x16, 0x50, 0x16,
12761         0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
12762         0x05, 0xf0, 0x09, 0xf0,
12763         0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00,
12764         0x9c, 0x00, 0xa4, 0x00,
12765         0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08,
12766         0xe9, 0x09, 0x5c, 0x0c,
12767         0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
12768         0x42, 0x1d, 0x08, 0x44,
12769         0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54,
12770         0x83, 0x55, 0x83, 0x59,
12771         0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0,
12772         0x4b, 0xf4, 0x04, 0xf8,
12773         0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
12774         0xa8, 0x00, 0xaa, 0x00,
12775         0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01,
12776         0x7a, 0x01, 0x82, 0x01,
12777         0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07,
12778         0x68, 0x08, 0x10, 0x0d,
12779         0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
12780         0xf3, 0x10, 0x06, 0x12,
12781         0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c,
12782         0xf0, 0x35, 0x05, 0xfe,
12783         0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8,
12784         0xfe, 0x88, 0x01, 0xff,
12785         0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
12786         0x00, 0xfe, 0x57, 0x24,
12787         0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09,
12788         0x00, 0x00, 0xff, 0x08,
12789         0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
12790         0xff, 0xff, 0xff, 0x13,
12791         0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
12792         0xfe, 0x04, 0xf7, 0xe8,
12793         0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d,
12794         0x0d, 0x51, 0x37, 0xfe,
12795         0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0,
12796         0xfe, 0xf8, 0x01, 0xfe,
12797         0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
12798         0x05, 0xfe, 0x08, 0x0f,
12799         0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe,
12800         0x28, 0x1c, 0x03, 0xfe,
12801         0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe,
12802         0x48, 0xf0, 0xfe, 0x90,
12803         0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
12804         0x02, 0xfe, 0x46, 0xf0,
12805         0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0,
12806         0xfe, 0x4e, 0x02, 0xfe,
12807         0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c,
12808         0x0d, 0xa2, 0x1c, 0x07,
12809         0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
12810         0x1c, 0xf5, 0xfe, 0x1e,
12811         0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc,
12812         0xde, 0x0a, 0x81, 0x01,
12813         0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a,
12814         0x81, 0x01, 0x5c, 0xfe,
12815         0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
12816         0xfe, 0x58, 0x1c, 0x1c,
12817         0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02,
12818         0x2b, 0xfe, 0x9e, 0x02,
12819         0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30,
12820         0x00, 0x47, 0xb8, 0x01,
12821         0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
12822         0x1a, 0x31, 0xfe, 0x69,
12823         0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe,
12824         0x1e, 0x1e, 0x20, 0x2c,
12825         0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a,
12826         0x44, 0x15, 0x56, 0x51,
12827         0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
12828         0x01, 0x18, 0x09, 0x00,
12829         0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01,
12830         0x18, 0xfe, 0xc8, 0x54,
12831         0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60,
12832         0xfe, 0x02, 0xe8, 0x30,
12833         0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
12834         0xfe, 0xe4, 0x01, 0xfe,
12835         0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe,
12836         0x26, 0xf0, 0xfe, 0x66,
12837         0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe,
12838         0xef, 0x10, 0xfe, 0x9f,
12839         0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
12840         0x70, 0x37, 0xfe, 0x48,
12841         0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26,
12842         0x21, 0xb9, 0xc7, 0x20,
12843         0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15,
12844         0xe1, 0x2a, 0xeb, 0xfe,
12845         0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
12846         0x15, 0xfe, 0xe4, 0x00,
12847         0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41,
12848         0xfe, 0x06, 0xf0, 0xfe,
12849         0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29,
12850         0x03, 0x81, 0x1e, 0x1b,
12851         0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
12852         0xea, 0xfe, 0x46, 0x1c,
12853         0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
12854         0xfe, 0x48, 0x1c, 0x75,
12855         0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a,
12856         0xe1, 0x01, 0x18, 0x77,
12857         0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
12858         0x8f, 0xfe, 0x70, 0x02,
12859         0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04,
12860         0x16, 0xfe, 0x4a, 0x04,
12861         0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff,
12862         0x02, 0x00, 0x10, 0x01,
12863         0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
12864         0xee, 0xfe, 0x4c, 0x44,
12865         0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54,
12866         0x7b, 0xec, 0x60, 0x8d,
12867         0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01,
12868         0x0c, 0x06, 0x28, 0xfe,
12869         0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
12870         0x13, 0x34, 0xfe, 0x4c,
12871         0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54,
12872         0x13, 0x01, 0x0c, 0x06,
12873         0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06,
12874         0x28, 0xf9, 0x1f, 0x7f,
12875         0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
12876         0xfe, 0xa4, 0x0e, 0x05,
12877         0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe,
12878         0x9c, 0x93, 0x3a, 0x0b,
12879         0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b,
12880         0x7d, 0x1d, 0xfe, 0x46,
12881         0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
12882         0xfe, 0x87, 0x83, 0xfe,
12883         0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98,
12884         0x13, 0x0f, 0xfe, 0x20,
12885         0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84,
12886         0x12, 0x01, 0x38, 0x06,
12887         0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
12888         0x05, 0xd0, 0x54, 0x01,
12889         0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe,
12890         0x50, 0x12, 0x5e, 0xff,
12891         0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02,
12892         0x00, 0x10, 0x2f, 0xfe,
12893         0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
12894         0x38, 0xfe, 0x4a, 0xf0,
12895         0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe,
12896         0x21, 0x00, 0xf1, 0x2e,
12897         0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00,
12898         0x10, 0x2f, 0xfe, 0xd0,
12899         0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
12900         0x1c, 0x00, 0x4d, 0x01,
12901         0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06,
12902         0x28, 0xfe, 0x24, 0x12,
12903         0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe,
12904         0x0d, 0x00, 0x01, 0x42,
12905         0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
12906         0x03, 0xb6, 0x1e, 0xfe,
12907         0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17,
12908         0xfe, 0x72, 0x06, 0x0a,
12909         0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56,
12910         0x19, 0x16, 0xfe, 0x68,
12911         0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
12912         0x03, 0x9a, 0x1e, 0xfe,
12913         0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12,
12914         0x48, 0xfe, 0x92, 0x06,
12915         0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13,
12916         0x58, 0xff, 0x02, 0x00,
12917         0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
12918         0xfe, 0xea, 0x06, 0x01,
12919         0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16,
12920         0xfe, 0xe0, 0x06, 0x15,
12921         0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07,
12922         0x01, 0x84, 0xfe, 0xae,
12923         0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
12924         0x1e, 0xfe, 0x1a, 0x12,
12925         0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
12926         0x43, 0x48, 0x62, 0x80,
12927         0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24,
12928         0x36, 0xfe, 0x02, 0xf6,
12929         0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
12930         0xd0, 0x0d, 0x17, 0xfe,
12931         0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20,
12932         0x9e, 0x15, 0x82, 0x01,
12933         0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58,
12934         0x57, 0x10, 0xe6, 0x05,
12935         0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
12936         0xfe, 0x9c, 0x32, 0x5f,
12937         0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c,
12938         0xfe, 0x0a, 0xf0, 0xfe,
12939         0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08,
12940         0xaf, 0xa0, 0x05, 0x29,
12941         0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
12942         0x00, 0x01, 0x08, 0x14,
12943         0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08,
12944         0x14, 0x00, 0x05, 0xfe,
12945         0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06,
12946         0x12, 0xfe, 0x30, 0x13,
12947         0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
12948         0x01, 0x08, 0x14, 0x00,
12949         0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a,
12950         0x78, 0x4f, 0x0f, 0xfe,
12951         0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d,
12952         0x28, 0x48, 0xfe, 0x6c,
12953         0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
12954         0x12, 0x53, 0x63, 0x4e,
12955         0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe,
12956         0x6c, 0x08, 0xaf, 0xa0,
12957         0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24,
12958         0x05, 0xed, 0xfe, 0x9c,
12959         0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
12960         0x1e, 0xfe, 0x99, 0x58,
12961         0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a,
12962         0x22, 0x6b, 0x01, 0x0c,
12963         0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e,
12964         0x1e, 0x47, 0x2c, 0x7a,
12965         0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
12966         0x01, 0x0c, 0x61, 0x65,
12967         0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a,
12968         0x16, 0xfe, 0x08, 0x50,
12969         0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10,
12970         0x01, 0xfe, 0xce, 0x1e,
12971         0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
12972         0x01, 0xfe, 0xfe, 0x1e,
12973         0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a,
12974         0x10, 0x01, 0x0c, 0x06,
12975         0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e,
12976         0x10, 0x6a, 0x22, 0x6b,
12977         0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
12978         0xfe, 0x9f, 0x83, 0x33,
12979         0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93,
12980         0x3a, 0x0b, 0xfe, 0xc6,
12981         0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d,
12982         0x01, 0xfe, 0xce, 0x1e,
12983         0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
12984         0x04, 0xfe, 0xc0, 0x93,
12985         0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e,
12986         0x10, 0x4b, 0x22, 0x4c,
12987         0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe,
12988         0x4e, 0x11, 0x2f, 0xfe,
12989         0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
12990         0x3c, 0x37, 0x88, 0xf5,
12991         0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a,
12992         0xd3, 0xfe, 0x42, 0x0a,
12993         0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0,
12994         0x05, 0x29, 0x01, 0x41,
12995         0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
12996         0xfe, 0x14, 0x12, 0x01,
12997         0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe,
12998         0x2e, 0x1c, 0x05, 0xfe,
12999         0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41,
13000         0xfe, 0x2c, 0x1c, 0xfe,
13001         0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
13002         0x92, 0x10, 0xc4, 0xf6,
13003         0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe,
13004         0xe7, 0x10, 0xfe, 0x2b,
13005         0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12,
13006         0xac, 0xfe, 0xd2, 0xf0,
13007         0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
13008         0x1b, 0xbf, 0xd4, 0x5b,
13009         0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75,
13010         0x5e, 0x32, 0x1f, 0x7f,
13011         0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98,
13012         0x05, 0x70, 0xfe, 0x74,
13013         0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
13014         0x0f, 0x4d, 0x01, 0xfe,
13015         0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06,
13016         0x0d, 0x2b, 0xfe, 0xe2,
13017         0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24,
13018         0xfe, 0x88, 0x13, 0x21,
13019         0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
13020         0x83, 0x83, 0xfe, 0xc9,
13021         0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04,
13022         0x91, 0x04, 0xfe, 0x84,
13023         0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93,
13024         0xfe, 0xcb, 0x57, 0x0b,
13025         0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
13026         0x6a, 0x3b, 0x6b, 0x10,
13027         0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30,
13028         0x20, 0x6e, 0xdb, 0x64,
13029         0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55,
13030         0xfe, 0x04, 0xfa, 0x64,
13031         0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
13032         0x10, 0x98, 0x91, 0x6c,
13033         0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91,
13034         0x4b, 0x7e, 0x4c, 0x01,
13035         0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10,
13036         0x58, 0xfe, 0x91, 0x58,
13037         0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
13038         0x1b, 0x40, 0x01, 0x0c,
13039         0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f,
13040         0xfe, 0x10, 0x90, 0x04,
13041         0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93,
13042         0x79, 0x0b, 0x0e, 0xfe,
13043         0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
13044         0x01, 0x0c, 0x06, 0x0d,
13045         0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe,
13046         0x0c, 0x58, 0xfe, 0x8d,
13047         0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99,
13048         0x83, 0x33, 0x0b, 0x0e,
13049         0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
13050         0x19, 0xfe, 0x19, 0x41,
13051         0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42,
13052         0x19, 0xfe, 0x44, 0x00,
13053         0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda,
13054         0x4c, 0xfe, 0x0c, 0x51,
13055         0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
13056         0x76, 0x10, 0xac, 0xfe,
13057         0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03,
13058         0xe3, 0x23, 0x07, 0xfe,
13059         0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe,
13060         0xcc, 0x0c, 0x1f, 0x92,
13061         0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
13062         0x0c, 0xfe, 0x3e, 0x10,
13063         0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70,
13064         0xfe, 0xcb, 0xf0, 0xfe,
13065         0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe,
13066         0xf4, 0x0c, 0x19, 0x94,
13067         0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
13068         0xfe, 0xcc, 0xf0, 0xef,
13069         0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe,
13070         0x4e, 0x11, 0x2f, 0xfe,
13071         0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b,
13072         0x3c, 0x37, 0x88, 0xf5,
13073         0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
13074         0x2f, 0xfe, 0x3e, 0x0d,
13075         0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f,
13076         0xd2, 0x9f, 0xd3, 0x9f,
13077         0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4,
13078         0xc5, 0x75, 0xd7, 0x99,
13079         0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
13080         0x9c, 0x2f, 0xfe, 0x8c,
13081         0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe,
13082         0x42, 0x00, 0x05, 0x70,
13083         0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06,
13084         0x0d, 0xfe, 0x44, 0x13,
13085         0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
13086         0xfe, 0xda, 0x0e, 0x0a,
13087         0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa,
13088         0x10, 0x01, 0xfe, 0xf4,
13089         0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40,
13090         0x15, 0x56, 0x01, 0x85,
13091         0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
13092         0xcc, 0x10, 0x01, 0xa7,
13093         0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04,
13094         0xfe, 0x99, 0x83, 0xfe,
13095         0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe,
13096         0x43, 0x00, 0xfe, 0xa2,
13097         0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
13098         0x00, 0x1d, 0x40, 0x15,
13099         0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05,
13100         0xfe, 0x3a, 0x03, 0x01,
13101         0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01,
13102         0x76, 0x06, 0x12, 0xfe,
13103         0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
13104         0xfe, 0x9d, 0xf0, 0xfe,
13105         0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01,
13106         0x0c, 0x61, 0x12, 0x44,
13107         0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f,
13108         0xfe, 0x2e, 0x10, 0x19,
13109         0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
13110         0xfe, 0x41, 0x00, 0xa2,
13111         0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b,
13112         0xea, 0x4f, 0xfe, 0x04,
13113         0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05,
13114         0x35, 0xfe, 0x12, 0x1c,
13115         0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
13116         0xfe, 0xd4, 0x11, 0x05,
13117         0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe,
13118         0xce, 0x45, 0x31, 0x51,
13119         0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03,
13120         0x67, 0xfe, 0x98, 0x56,
13121         0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
13122         0x0c, 0x06, 0x28, 0xfe,
13123         0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba,
13124         0xfe, 0xfa, 0x14, 0xfe,
13125         0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67,
13126         0xfe, 0xe0, 0x14, 0xfe,
13127         0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
13128         0xfe, 0xad, 0x13, 0x05,
13129         0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20,
13130         0xe7, 0xfe, 0x08, 0x1c,
13131         0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe,
13132         0x48, 0x55, 0xa5, 0x3b,
13133         0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
13134         0xf0, 0x1a, 0x03, 0xfe,
13135         0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02,
13136         0xec, 0xe7, 0x53, 0x00,
13137         0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
13138         0x01, 0xfe, 0x62, 0x1b,
13139         0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
13140         0xea, 0xe7, 0x53, 0x92,
13141         0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03,
13142         0xfe, 0x38, 0x01, 0x23,
13143         0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62,
13144         0x01, 0x01, 0xfe, 0x1e,
13145         0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
13146         0x26, 0x02, 0x21, 0x96,
13147         0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5,
13148         0xc3, 0xfe, 0xe1, 0x10,
13149         0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf,
13150         0xfe, 0x03, 0xdc, 0xfe,
13151         0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
13152         0x00, 0xcc, 0x02, 0xfe,
13153         0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13,
13154         0x0f, 0xfe, 0x1c, 0x80,
13155         0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13,
13156         0x0f, 0xfe, 0x1e, 0x80,
13157         0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
13158         0x1d, 0x80, 0x04, 0xfe,
13159         0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee,
13160         0x1e, 0xac, 0xfe, 0x14,
13161         0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e,
13162         0x1f, 0xfe, 0x30, 0xf4,
13163         0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
13164         0x56, 0xfb, 0x01, 0xfe,
13165         0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01,
13166         0xfe, 0x00, 0x1d, 0x15,
13167         0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe,
13168         0x22, 0x1b, 0xfe, 0x1e,
13169         0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
13170         0x96, 0x90, 0x04, 0xfe,
13171         0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66,
13172         0x01, 0x01, 0x0c, 0x06,
13173         0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b,
13174         0x0e, 0x77, 0xfe, 0x01,
13175         0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
13176         0x21, 0x2c, 0xfe, 0x00,
13177         0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe,
13178         0x06, 0x58, 0x03, 0xfe,
13179         0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58,
13180         0x03, 0xfe, 0xb2, 0x00,
13181         0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
13182         0x66, 0x10, 0x55, 0x10,
13183         0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91,
13184         0x54, 0x2b, 0xfe, 0x88,
13185         0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe,
13186         0x91, 0x54, 0x2b, 0xfe,
13187         0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
13188         0x00, 0x40, 0x8d, 0x2c,
13189         0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe,
13190         0x12, 0x1c, 0x75, 0xfe,
13191         0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c,
13192         0x14, 0xfe, 0x0e, 0x47,
13193         0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
13194         0xa7, 0x90, 0x34, 0x60,
13195         0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80,
13196         0x09, 0x56, 0xfe, 0x34,
13197         0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48,
13198         0xfe, 0x45, 0x48, 0x01,
13199         0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
13200         0x09, 0x1a, 0xa5, 0x0a,
13201         0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4,
13202         0xfe, 0x14, 0x56, 0xfe,
13203         0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01,
13204         0xec, 0xb8, 0xfe, 0x9e,
13205         0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
13206         0xf4, 0xfe, 0xdd, 0x10,
13207         0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48,
13208         0x12, 0x09, 0x0d, 0xfe,
13209         0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4,
13210         0x13, 0x09, 0xfe, 0x23,
13211         0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
13212         0x24, 0xfe, 0x12, 0x12,
13213         0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08,
13214         0xae, 0x41, 0x02, 0x32,
13215         0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05,
13216         0x35, 0x32, 0x01, 0x43,
13217         0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
13218         0x13, 0x01, 0x0c, 0x06,
13219         0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe,
13220         0xe5, 0x55, 0xb0, 0xfe,
13221         0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e,
13222         0xfe, 0xb6, 0x0e, 0x10,
13223         0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
13224         0x88, 0x20, 0x6e, 0x01,
13225         0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5,
13226         0x55, 0xfe, 0x04, 0xfa,
13227         0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d,
13228         0xfe, 0x40, 0x56, 0xfe,
13229         0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
13230         0x44, 0x55, 0xfe, 0xe5,
13231         0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10,
13232         0x68, 0x22, 0x69, 0x01,
13233         0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b,
13234         0x6b, 0xfe, 0x2c, 0x50,
13235         0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
13236         0x50, 0x03, 0x68, 0x3b,
13237         0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe,
13238         0x40, 0x50, 0xfe, 0xc2,
13239         0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08,
13240         0x16, 0x3d, 0x27, 0x25,
13241         0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
13242         0xa6, 0x23, 0x3f, 0x1b,
13243         0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c,
13244         0xfe, 0x0a, 0x55, 0x31,
13245         0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e,
13246         0x51, 0x05, 0x72, 0x01,
13247         0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
13248         0x2a, 0x3c, 0x16, 0xc0,
13249         0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b,
13250         0xfe, 0x66, 0x15, 0x05,
13251         0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d,
13252         0x2b, 0x3d, 0x01, 0x08,
13253         0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
13254         0xb6, 0x1e, 0x83, 0x01,
13255         0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46,
13256         0x07, 0x90, 0x3f, 0x01,
13257         0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13,
13258         0x01, 0x43, 0x09, 0x82,
13259         0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
13260         0x05, 0x72, 0xfe, 0xc0,
13261         0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e,
13262         0x32, 0x01, 0x08, 0x17,
13263         0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16,
13264         0x3d, 0x27, 0x25, 0xbd,
13265         0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
13266         0xe8, 0x14, 0x01, 0xa6,
13267         0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe,
13268         0x0e, 0x12, 0x01, 0x43,
13269         0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32,
13270         0x01, 0x08, 0x17, 0x73,
13271         0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
13272         0x27, 0x25, 0xbd, 0x09,
13273         0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe,
13274         0xb6, 0x14, 0x86, 0xa8,
13275         0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09,
13276         0x82, 0x4e, 0x05, 0x72,
13277         0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
13278         0xfe, 0xc0, 0x19, 0x05,
13279         0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f,
13280         0xcc, 0x01, 0x08, 0x26,
13281         0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe,
13282         0xcc, 0x15, 0x5e, 0x32,
13283         0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
13284         0xad, 0x23, 0xfe, 0xff,
13285         0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02,
13286         0x00, 0x57, 0x52, 0xad,
13287         0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff,
13288         0x02, 0x00, 0x57, 0x52,
13289         0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
13290         0x02, 0x13, 0x58, 0xff,
13291         0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01,
13292         0x5c, 0x0a, 0x55, 0x01,
13293         0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a,
13294         0xff, 0x03, 0x00, 0x54,
13295         0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
13296         0x7c, 0x3a, 0x0b, 0x0e,
13297         0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19,
13298         0xfe, 0x1a, 0xf7, 0x00,
13299         0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c,
13300         0xda, 0x6d, 0x02, 0xfe,
13301         0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
13302         0x02, 0x01, 0xc6, 0xfe,
13303         0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27,
13304         0x25, 0xbe, 0x01, 0x08,
13305         0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59,
13306         0x03, 0x9a, 0x1e, 0xfe,
13307         0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
13308         0x48, 0xfe, 0x08, 0x17,
13309         0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26,
13310         0x17, 0x4d, 0x13, 0x07,
13311         0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1,
13312         0xff, 0x02, 0x83, 0x55,
13313         0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
13314         0x17, 0x1c, 0x63, 0x13,
13315         0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64,
13316         0x00, 0xb0, 0xfe, 0x80,
13317         0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10,
13318         0x53, 0x07, 0xfe, 0x60,
13319         0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
13320         0x00, 0x1c, 0x95, 0x13,
13321         0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3,
13322         0xfe, 0x43, 0xf4, 0x96,
13323         0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43,
13324         0xf4, 0x94, 0xf6, 0x8b,
13325         0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
13326         0xda, 0x17, 0x62, 0x49,
13327         0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80,
13328         0x71, 0x50, 0x26, 0xfe,
13329         0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3,
13330         0x58, 0x02, 0x50, 0x13,
13331         0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
13332         0x25, 0xbe, 0xfe, 0x03,
13333         0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9,
13334         0x0a, 0x01, 0x08, 0x16,
13335         0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01,
13336         0x01, 0x08, 0x16, 0xa9,
13337         0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
13338         0x08, 0x16, 0xa9, 0x27,
13339         0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83,
13340         0x01, 0x38, 0x06, 0x24,
13341         0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1,
13342         0x78, 0x03, 0x9a, 0x1e,
13343         0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
13344         0xfe, 0x40, 0x5a, 0x23,
13345         0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c,
13346         0x80, 0x48, 0xfe, 0xaa,
13347         0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01,
13348         0xfe, 0xac, 0x1d, 0xfe,
13349         0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
13350         0x43, 0x48, 0x2d, 0x93,
13351         0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4,
13352         0x36, 0xfe, 0x34, 0xf4,
13353         0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe,
13354         0x28, 0x10, 0xfe, 0xc0,
13355         0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
13356         0x18, 0x45, 0xfe, 0x1c,
13357         0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c,
13358         0x19, 0xfe, 0x04, 0xf4,
13359         0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d,
13360         0x21, 0xfe, 0x7f, 0x01,
13361         0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
13362         0x7e, 0x01, 0xfe, 0xc8,
13363         0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa,
13364         0x21, 0xfe, 0x81, 0x01,
13365         0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50,
13366         0x13, 0x0d, 0x02, 0x14,
13367         0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
13368         0xfe, 0x82, 0x19, 0x14,
13369         0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01,
13370         0x08, 0x02, 0x14, 0x07,
13371         0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07,
13372         0x01, 0x08, 0x17, 0xc1,
13373         0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
13374         0x08, 0x02, 0x50, 0x02,
13375         0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74,
13376         0x14, 0x12, 0x01, 0x08,
13377         0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01,
13378         0x08, 0x17, 0x74, 0xfe,
13379         0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
13380         0x74, 0x5f, 0xcc, 0x01,
13381         0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4,
13382         0xfe, 0x49, 0xf4, 0x00,
13383         0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff,
13384         0x02, 0x00, 0x10, 0x2f,
13385         0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
13386         0x16, 0xfe, 0x64, 0x1a,
13387         0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c,
13388         0x61, 0x07, 0x44, 0x02,
13389         0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12,
13390         0x13, 0x0a, 0x9d, 0x01,
13391         0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
13392         0xfe, 0x80, 0xe7, 0x1a,
13393         0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02,
13394         0x0a, 0x5a, 0x01, 0x18,
13395         0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe,
13396         0x7e, 0x1e, 0xfe, 0x80,
13397         0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
13398         0xfe, 0x80, 0x4c, 0x0a,
13399         0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf,
13400         0xfe, 0x19, 0xde, 0xfe,
13401         0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe,
13402         0x2a, 0x1c, 0xfa, 0xb3,
13403         0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
13404         0xf4, 0x1a, 0xfe, 0xfa,
13405         0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24,
13406         0xfe, 0x18, 0x58, 0x03,
13407         0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f,
13408         0xfe, 0x30, 0xf4, 0x07,
13409         0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
13410         0xf7, 0x24, 0xb1, 0xfe,
13411         0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b,
13412         0xfe, 0xba, 0x10, 0x1c,
13413         0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
13414         0x1d, 0xf7, 0x54, 0xb1,
13415         0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
13416         0xaf, 0x19, 0xfe, 0x98,
13417         0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c,
13418         0x1a, 0x87, 0x8b, 0x0f,
13419         0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58,
13420         0xfe, 0x32, 0x90, 0x04,
13421         0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
13422         0x7c, 0x12, 0xfe, 0x0f,
13423         0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14,
13424         0x31, 0x02, 0xc9, 0x2b,
13425         0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe,
13426         0x6a, 0xfe, 0x19, 0xfe,
13427         0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
13428         0x1b, 0xfe, 0x36, 0x14,
13429         0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19,
13430         0xfe, 0x80, 0xe7, 0x1a,
13431         0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a,
13432         0x30, 0xfe, 0x12, 0x45,
13433         0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
13434         0x39, 0xf0, 0x75, 0x26,
13435         0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03,
13436         0xe3, 0x23, 0x07, 0xfe,
13437         0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09,
13438         0x56, 0xfe, 0x3c, 0x13,
13439         0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
13440         0x01, 0x18, 0xcb, 0xfe,
13441         0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16,
13442         0xfe, 0x00, 0xcc, 0xcb,
13443         0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18,
13444         0xfe, 0x80, 0x4c, 0x01,
13445         0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
13446         0x12, 0xfe, 0x14, 0x56,
13447         0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7,
13448         0x0d, 0x19, 0xfe, 0x15,
13449         0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06,
13450         0x83, 0xfe, 0x18, 0x80,
13451         0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
13452         0x90, 0xfe, 0xba, 0x90,
13453         0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02,
13454         0x21, 0xb9, 0x88, 0x20,
13455         0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01,
13456         0x18, 0xfe, 0x49, 0x44,
13457         0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
13458         0x1a, 0xa4, 0x0a, 0x67,
13459         0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4,
13460         0x1d, 0x7b, 0xfe, 0x52,
13461         0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe,
13462         0x4e, 0xe4, 0xdd, 0x7b,
13463         0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
13464         0xfe, 0x4e, 0xe4, 0xfe,
13465         0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24,
13466         0xfe, 0x08, 0x10, 0x03,
13467         0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04,
13468         0x68, 0x54, 0xfe, 0xf1,
13469         0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
13470         0xfe, 0x1a, 0xf4, 0xfe,
13471         0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02,
13472         0x09, 0x92, 0xfe, 0x5a,
13473         0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe,
13474         0x5a, 0xf0, 0xfe, 0xc8,
13475         0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
13476         0x1a, 0x10, 0x09, 0x0d,
13477         0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02,
13478         0x1f, 0x93, 0x01, 0x42,
13479         0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e,
13480         0xfe, 0x14, 0xf0, 0x08,
13481         0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
13482         0xfe, 0x82, 0xf0, 0xfe,
13483         0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e,
13484         0x02, 0x0f, 0xfe, 0x18,
13485         0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02,
13486         0x80, 0x04, 0xfe, 0x82,
13487         0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
13488         0x83, 0x33, 0x0b, 0x0e,
13489         0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e,
13490         0x02, 0x0f, 0xfe, 0x04,
13491         0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80,
13492         0x80, 0x04, 0xfe, 0x80,
13493         0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
13494         0xfe, 0x99, 0x83, 0xfe,
13495         0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86,
13496         0x83, 0xfe, 0xce, 0x47,
13497         0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a,
13498         0x0b, 0x0e, 0x02, 0x0f,
13499         0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13500         0xfe, 0x08, 0x90, 0x04,
13501         0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04,
13502         0xfe, 0x8a, 0x93, 0x79,
13503         0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a,
13504         0x0b, 0x0e, 0x02, 0x0f,
13505         0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13506         0xfe, 0x3c, 0x90, 0x04,
13507         0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80,
13508         0x04, 0xfe, 0x83, 0x83,
13509         0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
13510 };
13511
13512 static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf);       /* 0x1673 */
13513 static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL;  /* Expanded little-endian checksum. */
13514
13515 /* a_init.c */
13516 /*
13517  * EEPROM Configuration.
13518  *
13519  * All drivers should use this structure to set the default EEPROM
13520  * configuration. The BIOS now uses this structure when it is built.
13521  * Additional structure information can be found in a_condor.h where
13522  * the structure is defined.
13523  *
13524  * The *_Field_IsChar structs are needed to correct for endianness.
13525  * These values are read from the board 16 bits at a time directly
13526  * into the structs. Because some fields are char, the values will be
13527  * in the wrong order. The *_Field_IsChar tells when to flip the
13528  * bytes. Data read and written to PCI memory is automatically swapped
13529  * on big-endian platforms so char fields read as words are actually being
13530  * unswapped on big-endian platforms.
13531  */
13532 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
13533         ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
13534         0x0000,                 /* cfg_msw */
13535         0xFFFF,                 /* disc_enable */
13536         0xFFFF,                 /* wdtr_able */
13537         0xFFFF,                 /* sdtr_able */
13538         0xFFFF,                 /* start_motor */
13539         0xFFFF,                 /* tagqng_able */
13540         0xFFFF,                 /* bios_scan */
13541         0,                      /* scam_tolerant */
13542         7,                      /* adapter_scsi_id */
13543         0,                      /* bios_boot_delay */
13544         3,                      /* scsi_reset_delay */
13545         0,                      /* bios_id_lun */
13546         0,                      /* termination */
13547         0,                      /* reserved1 */
13548         0xFFE7,                 /* bios_ctrl */
13549         0xFFFF,                 /* ultra_able */
13550         0,                      /* reserved2 */
13551         ASC_DEF_MAX_HOST_QNG,   /* max_host_qng */
13552         ASC_DEF_MAX_DVC_QNG,    /* max_dvc_qng */
13553         0,                      /* dvc_cntl */
13554         0,                      /* bug_fix */
13555         0,                      /* serial_number_word1 */
13556         0,                      /* serial_number_word2 */
13557         0,                      /* serial_number_word3 */
13558         0,                      /* check_sum */
13559         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13560         ,                       /* oem_name[16] */
13561         0,                      /* dvc_err_code */
13562         0,                      /* adv_err_code */
13563         0,                      /* adv_err_addr */
13564         0,                      /* saved_dvc_err_code */
13565         0,                      /* saved_adv_err_code */
13566         0,                      /* saved_adv_err_addr */
13567         0                       /* num_of_err */
13568 };
13569
13570 static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
13571         0,                      /* cfg_lsw */
13572         0,                      /* cfg_msw */
13573         0,                      /* -disc_enable */
13574         0,                      /* wdtr_able */
13575         0,                      /* sdtr_able */
13576         0,                      /* start_motor */
13577         0,                      /* tagqng_able */
13578         0,                      /* bios_scan */
13579         0,                      /* scam_tolerant */
13580         1,                      /* adapter_scsi_id */
13581         1,                      /* bios_boot_delay */
13582         1,                      /* scsi_reset_delay */
13583         1,                      /* bios_id_lun */
13584         1,                      /* termination */
13585         1,                      /* reserved1 */
13586         0,                      /* bios_ctrl */
13587         0,                      /* ultra_able */
13588         0,                      /* reserved2 */
13589         1,                      /* max_host_qng */
13590         1,                      /* max_dvc_qng */
13591         0,                      /* dvc_cntl */
13592         0,                      /* bug_fix */
13593         0,                      /* serial_number_word1 */
13594         0,                      /* serial_number_word2 */
13595         0,                      /* serial_number_word3 */
13596         0,                      /* check_sum */
13597         {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13598         ,                       /* oem_name[16] */
13599         0,                      /* dvc_err_code */
13600         0,                      /* adv_err_code */
13601         0,                      /* adv_err_addr */
13602         0,                      /* saved_dvc_err_code */
13603         0,                      /* saved_adv_err_code */
13604         0,                      /* saved_adv_err_addr */
13605         0                       /* num_of_err */
13606 };
13607
13608 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
13609         ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13610         0x0000,                 /* 01 cfg_msw */
13611         0xFFFF,                 /* 02 disc_enable */
13612         0xFFFF,                 /* 03 wdtr_able */
13613         0x4444,                 /* 04 sdtr_speed1 */
13614         0xFFFF,                 /* 05 start_motor */
13615         0xFFFF,                 /* 06 tagqng_able */
13616         0xFFFF,                 /* 07 bios_scan */
13617         0,                      /* 08 scam_tolerant */
13618         7,                      /* 09 adapter_scsi_id */
13619         0,                      /*    bios_boot_delay */
13620         3,                      /* 10 scsi_reset_delay */
13621         0,                      /*    bios_id_lun */
13622         0,                      /* 11 termination_se */
13623         0,                      /*    termination_lvd */
13624         0xFFE7,                 /* 12 bios_ctrl */
13625         0x4444,                 /* 13 sdtr_speed2 */
13626         0x4444,                 /* 14 sdtr_speed3 */
13627         ASC_DEF_MAX_HOST_QNG,   /* 15 max_host_qng */
13628         ASC_DEF_MAX_DVC_QNG,    /*    max_dvc_qng */
13629         0,                      /* 16 dvc_cntl */
13630         0x4444,                 /* 17 sdtr_speed4 */
13631         0,                      /* 18 serial_number_word1 */
13632         0,                      /* 19 serial_number_word2 */
13633         0,                      /* 20 serial_number_word3 */
13634         0,                      /* 21 check_sum */
13635         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13636         ,                       /* 22-29 oem_name[16] */
13637         0,                      /* 30 dvc_err_code */
13638         0,                      /* 31 adv_err_code */
13639         0,                      /* 32 adv_err_addr */
13640         0,                      /* 33 saved_dvc_err_code */
13641         0,                      /* 34 saved_adv_err_code */
13642         0,                      /* 35 saved_adv_err_addr */
13643         0,                      /* 36 reserved */
13644         0,                      /* 37 reserved */
13645         0,                      /* 38 reserved */
13646         0,                      /* 39 reserved */
13647         0,                      /* 40 reserved */
13648         0,                      /* 41 reserved */
13649         0,                      /* 42 reserved */
13650         0,                      /* 43 reserved */
13651         0,                      /* 44 reserved */
13652         0,                      /* 45 reserved */
13653         0,                      /* 46 reserved */
13654         0,                      /* 47 reserved */
13655         0,                      /* 48 reserved */
13656         0,                      /* 49 reserved */
13657         0,                      /* 50 reserved */
13658         0,                      /* 51 reserved */
13659         0,                      /* 52 reserved */
13660         0,                      /* 53 reserved */
13661         0,                      /* 54 reserved */
13662         0,                      /* 55 reserved */
13663         0,                      /* 56 cisptr_lsw */
13664         0,                      /* 57 cisprt_msw */
13665         PCI_VENDOR_ID_ASP,      /* 58 subsysvid */
13666         PCI_DEVICE_ID_38C0800_REV1,     /* 59 subsysid */
13667         0,                      /* 60 reserved */
13668         0,                      /* 61 reserved */
13669         0,                      /* 62 reserved */
13670         0                       /* 63 reserved */
13671 };
13672
13673 static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
13674         0,                      /* 00 cfg_lsw */
13675         0,                      /* 01 cfg_msw */
13676         0,                      /* 02 disc_enable */
13677         0,                      /* 03 wdtr_able */
13678         0,                      /* 04 sdtr_speed1 */
13679         0,                      /* 05 start_motor */
13680         0,                      /* 06 tagqng_able */
13681         0,                      /* 07 bios_scan */
13682         0,                      /* 08 scam_tolerant */
13683         1,                      /* 09 adapter_scsi_id */
13684         1,                      /*    bios_boot_delay */
13685         1,                      /* 10 scsi_reset_delay */
13686         1,                      /*    bios_id_lun */
13687         1,                      /* 11 termination_se */
13688         1,                      /*    termination_lvd */
13689         0,                      /* 12 bios_ctrl */
13690         0,                      /* 13 sdtr_speed2 */
13691         0,                      /* 14 sdtr_speed3 */
13692         1,                      /* 15 max_host_qng */
13693         1,                      /*    max_dvc_qng */
13694         0,                      /* 16 dvc_cntl */
13695         0,                      /* 17 sdtr_speed4 */
13696         0,                      /* 18 serial_number_word1 */
13697         0,                      /* 19 serial_number_word2 */
13698         0,                      /* 20 serial_number_word3 */
13699         0,                      /* 21 check_sum */
13700         {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13701         ,                       /* 22-29 oem_name[16] */
13702         0,                      /* 30 dvc_err_code */
13703         0,                      /* 31 adv_err_code */
13704         0,                      /* 32 adv_err_addr */
13705         0,                      /* 33 saved_dvc_err_code */
13706         0,                      /* 34 saved_adv_err_code */
13707         0,                      /* 35 saved_adv_err_addr */
13708         0,                      /* 36 reserved */
13709         0,                      /* 37 reserved */
13710         0,                      /* 38 reserved */
13711         0,                      /* 39 reserved */
13712         0,                      /* 40 reserved */
13713         0,                      /* 41 reserved */
13714         0,                      /* 42 reserved */
13715         0,                      /* 43 reserved */
13716         0,                      /* 44 reserved */
13717         0,                      /* 45 reserved */
13718         0,                      /* 46 reserved */
13719         0,                      /* 47 reserved */
13720         0,                      /* 48 reserved */
13721         0,                      /* 49 reserved */
13722         0,                      /* 50 reserved */
13723         0,                      /* 51 reserved */
13724         0,                      /* 52 reserved */
13725         0,                      /* 53 reserved */
13726         0,                      /* 54 reserved */
13727         0,                      /* 55 reserved */
13728         0,                      /* 56 cisptr_lsw */
13729         0,                      /* 57 cisprt_msw */
13730         0,                      /* 58 subsysvid */
13731         0,                      /* 59 subsysid */
13732         0,                      /* 60 reserved */
13733         0,                      /* 61 reserved */
13734         0,                      /* 62 reserved */
13735         0                       /* 63 reserved */
13736 };
13737
13738 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
13739         ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13740         0x0000,                 /* 01 cfg_msw */
13741         0xFFFF,                 /* 02 disc_enable */
13742         0xFFFF,                 /* 03 wdtr_able */
13743         0x5555,                 /* 04 sdtr_speed1 */
13744         0xFFFF,                 /* 05 start_motor */
13745         0xFFFF,                 /* 06 tagqng_able */
13746         0xFFFF,                 /* 07 bios_scan */
13747         0,                      /* 08 scam_tolerant */
13748         7,                      /* 09 adapter_scsi_id */
13749         0,                      /*    bios_boot_delay */
13750         3,                      /* 10 scsi_reset_delay */
13751         0,                      /*    bios_id_lun */
13752         0,                      /* 11 termination_se */
13753         0,                      /*    termination_lvd */
13754         0xFFE7,                 /* 12 bios_ctrl */
13755         0x5555,                 /* 13 sdtr_speed2 */
13756         0x5555,                 /* 14 sdtr_speed3 */
13757         ASC_DEF_MAX_HOST_QNG,   /* 15 max_host_qng */
13758         ASC_DEF_MAX_DVC_QNG,    /*    max_dvc_qng */
13759         0,                      /* 16 dvc_cntl */
13760         0x5555,                 /* 17 sdtr_speed4 */
13761         0,                      /* 18 serial_number_word1 */
13762         0,                      /* 19 serial_number_word2 */
13763         0,                      /* 20 serial_number_word3 */
13764         0,                      /* 21 check_sum */
13765         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13766         ,                       /* 22-29 oem_name[16] */
13767         0,                      /* 30 dvc_err_code */
13768         0,                      /* 31 adv_err_code */
13769         0,                      /* 32 adv_err_addr */
13770         0,                      /* 33 saved_dvc_err_code */
13771         0,                      /* 34 saved_adv_err_code */
13772         0,                      /* 35 saved_adv_err_addr */
13773         0,                      /* 36 reserved */
13774         0,                      /* 37 reserved */
13775         0,                      /* 38 reserved */
13776         0,                      /* 39 reserved */
13777         0,                      /* 40 reserved */
13778         0,                      /* 41 reserved */
13779         0,                      /* 42 reserved */
13780         0,                      /* 43 reserved */
13781         0,                      /* 44 reserved */
13782         0,                      /* 45 reserved */
13783         0,                      /* 46 reserved */
13784         0,                      /* 47 reserved */
13785         0,                      /* 48 reserved */
13786         0,                      /* 49 reserved */
13787         0,                      /* 50 reserved */
13788         0,                      /* 51 reserved */
13789         0,                      /* 52 reserved */
13790         0,                      /* 53 reserved */
13791         0,                      /* 54 reserved */
13792         0,                      /* 55 reserved */
13793         0,                      /* 56 cisptr_lsw */
13794         0,                      /* 57 cisprt_msw */
13795         PCI_VENDOR_ID_ASP,      /* 58 subsysvid */
13796         PCI_DEVICE_ID_38C1600_REV1,     /* 59 subsysid */
13797         0,                      /* 60 reserved */
13798         0,                      /* 61 reserved */
13799         0,                      /* 62 reserved */
13800         0                       /* 63 reserved */
13801 };
13802
13803 static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
13804         0,                      /* 00 cfg_lsw */
13805         0,                      /* 01 cfg_msw */
13806         0,                      /* 02 disc_enable */
13807         0,                      /* 03 wdtr_able */
13808         0,                      /* 04 sdtr_speed1 */
13809         0,                      /* 05 start_motor */
13810         0,                      /* 06 tagqng_able */
13811         0,                      /* 07 bios_scan */
13812         0,                      /* 08 scam_tolerant */
13813         1,                      /* 09 adapter_scsi_id */
13814         1,                      /*    bios_boot_delay */
13815         1,                      /* 10 scsi_reset_delay */
13816         1,                      /*    bios_id_lun */
13817         1,                      /* 11 termination_se */
13818         1,                      /*    termination_lvd */
13819         0,                      /* 12 bios_ctrl */
13820         0,                      /* 13 sdtr_speed2 */
13821         0,                      /* 14 sdtr_speed3 */
13822         1,                      /* 15 max_host_qng */
13823         1,                      /*    max_dvc_qng */
13824         0,                      /* 16 dvc_cntl */
13825         0,                      /* 17 sdtr_speed4 */
13826         0,                      /* 18 serial_number_word1 */
13827         0,                      /* 19 serial_number_word2 */
13828         0,                      /* 20 serial_number_word3 */
13829         0,                      /* 21 check_sum */
13830         {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13831         ,                       /* 22-29 oem_name[16] */
13832         0,                      /* 30 dvc_err_code */
13833         0,                      /* 31 adv_err_code */
13834         0,                      /* 32 adv_err_addr */
13835         0,                      /* 33 saved_dvc_err_code */
13836         0,                      /* 34 saved_adv_err_code */
13837         0,                      /* 35 saved_adv_err_addr */
13838         0,                      /* 36 reserved */
13839         0,                      /* 37 reserved */
13840         0,                      /* 38 reserved */
13841         0,                      /* 39 reserved */
13842         0,                      /* 40 reserved */
13843         0,                      /* 41 reserved */
13844         0,                      /* 42 reserved */
13845         0,                      /* 43 reserved */
13846         0,                      /* 44 reserved */
13847         0,                      /* 45 reserved */
13848         0,                      /* 46 reserved */
13849         0,                      /* 47 reserved */
13850         0,                      /* 48 reserved */
13851         0,                      /* 49 reserved */
13852         0,                      /* 50 reserved */
13853         0,                      /* 51 reserved */
13854         0,                      /* 52 reserved */
13855         0,                      /* 53 reserved */
13856         0,                      /* 54 reserved */
13857         0,                      /* 55 reserved */
13858         0,                      /* 56 cisptr_lsw */
13859         0,                      /* 57 cisprt_msw */
13860         0,                      /* 58 subsysvid */
13861         0,                      /* 59 subsysid */
13862         0,                      /* 60 reserved */
13863         0,                      /* 61 reserved */
13864         0,                      /* 62 reserved */
13865         0                       /* 63 reserved */
13866 };
13867
13868 /*
13869  * Initialize the ADV_DVC_VAR structure.
13870  *
13871  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13872  *
13873  * For a non-fatal error return a warning code. If there are no warnings
13874  * then 0 is returned.
13875  */
13876 static int __devinit AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
13877 {
13878         ushort warn_code;
13879         AdvPortAddr iop_base;
13880         uchar pci_cmd_reg;
13881         int status;
13882
13883         warn_code = 0;
13884         asc_dvc->err_code = 0;
13885         iop_base = asc_dvc->iop_base;
13886
13887         /*
13888          * PCI Command Register
13889          *
13890          * Note: AscPCICmdRegBits_BusMastering definition (0x0007) includes
13891          * I/O Space Control, Memory Space Control and Bus Master Control bits.
13892          */
13893
13894         if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
13895                                                     AscPCIConfigCommandRegister))
13896              & AscPCICmdRegBits_BusMastering)
13897             != AscPCICmdRegBits_BusMastering) {
13898                 pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
13899
13900                 DvcAdvWritePCIConfigByte(asc_dvc,
13901                                          AscPCIConfigCommandRegister,
13902                                          pci_cmd_reg);
13903
13904                 if (((DvcAdvReadPCIConfigByte
13905                       (asc_dvc, AscPCIConfigCommandRegister))
13906                      & AscPCICmdRegBits_BusMastering)
13907                     != AscPCICmdRegBits_BusMastering) {
13908                         warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
13909                 }
13910         }
13911
13912         /*
13913          * PCI Latency Timer
13914          *
13915          * If the "latency timer" register is 0x20 or above, then we don't need
13916          * to change it.  Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
13917          * comes up less than 0x20).
13918          */
13919         if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
13920                 DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer,
13921                                          0x20);
13922                 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) <
13923                     0x20) {
13924                         warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
13925                 }
13926         }
13927
13928         /*
13929          * Save the state of the PCI Configuration Command Register
13930          * "Parity Error Response Control" Bit. If the bit is clear (0),
13931          * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
13932          * DMA parity errors.
13933          */
13934         asc_dvc->cfg->control_flag = 0;
13935         if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
13936               & AscPCICmdRegBits_ParErrRespCtrl)) == 0) {
13937                 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
13938         }
13939
13940         asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
13941             ADV_LIB_VERSION_MINOR;
13942         asc_dvc->cfg->chip_version =
13943             AdvGetChipVersion(iop_base, asc_dvc->bus_type);
13944
13945         ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
13946                  (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
13947                  (ushort)ADV_CHIP_ID_BYTE);
13948
13949         ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
13950                  (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
13951                  (ushort)ADV_CHIP_ID_WORD);
13952
13953         /*
13954          * Reset the chip to start and allow register writes.
13955          */
13956         if (AdvFindSignature(iop_base) == 0) {
13957                 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
13958                 return ADV_ERROR;
13959         } else {
13960                 /*
13961                  * The caller must set 'chip_type' to a valid setting.
13962                  */
13963                 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
13964                     asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
13965                     asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
13966                         asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
13967                         return ADV_ERROR;
13968                 }
13969
13970                 /*
13971                  * Reset Chip.
13972                  */
13973                 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13974                                      ADV_CTRL_REG_CMD_RESET);
13975                 DvcSleepMilliSecond(100);
13976                 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13977                                      ADV_CTRL_REG_CMD_WR_IO_REG);
13978
13979                 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13980                         if ((status =
13981                              AdvInitFrom38C1600EEP(asc_dvc)) == ADV_ERROR) {
13982                                 return ADV_ERROR;
13983                         }
13984                 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13985                         if ((status =
13986                              AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR) {
13987                                 return ADV_ERROR;
13988                         }
13989                 } else {
13990                         if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR) {
13991                                 return ADV_ERROR;
13992                         }
13993                 }
13994                 warn_code |= status;
13995         }
13996
13997         return warn_code;
13998 }
13999
14000 /*
14001  * Initialize the ASC-3550.
14002  *
14003  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14004  *
14005  * For a non-fatal error return a warning code. If there are no warnings
14006  * then 0 is returned.
14007  *
14008  * Needed after initialization for error recovery.
14009  */
14010 static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
14011 {
14012         AdvPortAddr iop_base;
14013         ushort warn_code;
14014         ADV_DCNT sum;
14015         int begin_addr;
14016         int end_addr;
14017         ushort code_sum;
14018         int word;
14019         int j;
14020         int adv_asc3550_expanded_size;
14021         ADV_CARR_T *carrp;
14022         ADV_DCNT contig_len;
14023         ADV_SDCNT buf_size;
14024         ADV_PADDR carr_paddr;
14025         int i;
14026         ushort scsi_cfg1;
14027         uchar tid;
14028         ushort bios_mem[ASC_MC_BIOSLEN / 2];    /* BIOS RISC Memory 0x40-0x8F. */
14029         ushort wdtr_able = 0, sdtr_able, tagqng_able;
14030         uchar max_cmd[ADV_MAX_TID + 1];
14031
14032         /* If there is already an error, don't continue. */
14033         if (asc_dvc->err_code != 0) {
14034                 return ADV_ERROR;
14035         }
14036
14037         /*
14038          * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
14039          */
14040         if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
14041                 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14042                 return ADV_ERROR;
14043         }
14044
14045         warn_code = 0;
14046         iop_base = asc_dvc->iop_base;
14047
14048         /*
14049          * Save the RISC memory BIOS region before writing the microcode.
14050          * The BIOS may already be loaded and using its RISC LRAM region
14051          * so its region must be saved and restored.
14052          *
14053          * Note: This code makes the assumption, which is currently true,
14054          * that a chip reset does not clear RISC LRAM.
14055          */
14056         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14057                 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14058                                 bios_mem[i]);
14059         }
14060
14061         /*
14062          * Save current per TID negotiated values.
14063          */
14064         if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
14065                 ushort bios_version, major, minor;
14066
14067                 bios_version =
14068                     bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
14069                 major = (bios_version >> 12) & 0xF;
14070                 minor = (bios_version >> 8) & 0xF;
14071                 if (major < 3 || (major == 3 && minor == 1)) {
14072                         /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
14073                         AdvReadWordLram(iop_base, 0x120, wdtr_able);
14074                 } else {
14075                         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14076                 }
14077         }
14078         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14079         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14080         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14081                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14082                                 max_cmd[tid]);
14083         }
14084
14085         /*
14086          * Load the Microcode
14087          *
14088          * Write the microcode image to RISC memory starting at address 0.
14089          */
14090         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14091         /* Assume the following compressed format of the microcode buffer:
14092          *
14093          *  254 word (508 byte) table indexed by byte code followed
14094          *  by the following byte codes:
14095          *
14096          *    1-Byte Code:
14097          *      00: Emit word 0 in table.
14098          *      01: Emit word 1 in table.
14099          *      .
14100          *      FD: Emit word 253 in table.
14101          *
14102          *    Multi-Byte Code:
14103          *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14104          *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14105          */
14106         word = 0;
14107         for (i = 253 * 2; i < _adv_asc3550_size; i++) {
14108                 if (_adv_asc3550_buf[i] == 0xff) {
14109                         for (j = 0; j < _adv_asc3550_buf[i + 1]; j++) {
14110                                 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14111                                                                     _adv_asc3550_buf
14112                                                                     [i +
14113                                                                      3] << 8) |
14114                                                                    _adv_asc3550_buf
14115                                                                    [i + 2]));
14116                                 word++;
14117                         }
14118                         i += 3;
14119                 } else if (_adv_asc3550_buf[i] == 0xfe) {
14120                         AdvWriteWordAutoIncLram(iop_base, (((ushort)
14121                                                             _adv_asc3550_buf[i +
14122                                                                              2]
14123                                                             << 8) |
14124                                                            _adv_asc3550_buf[i +
14125                                                                             1]));
14126                         i += 2;
14127                         word++;
14128                 } else {
14129                         AdvWriteWordAutoIncLram(iop_base, (((ushort)
14130                                                             _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) | _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
14131                         word++;
14132                 }
14133         }
14134
14135         /*
14136          * Set 'word' for later use to clear the rest of memory and save
14137          * the expanded mcode size.
14138          */
14139         word *= 2;
14140         adv_asc3550_expanded_size = word;
14141
14142         /*
14143          * Clear the rest of ASC-3550 Internal RAM (8KB).
14144          */
14145         for (; word < ADV_3550_MEMSIZE; word += 2) {
14146                 AdvWriteWordAutoIncLram(iop_base, 0);
14147         }
14148
14149         /*
14150          * Verify the microcode checksum.
14151          */
14152         sum = 0;
14153         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14154
14155         for (word = 0; word < adv_asc3550_expanded_size; word += 2) {
14156                 sum += AdvReadWordAutoIncLram(iop_base);
14157         }
14158
14159         if (sum != _adv_asc3550_chksum) {
14160                 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14161                 return ADV_ERROR;
14162         }
14163
14164         /*
14165          * Restore the RISC memory BIOS region.
14166          */
14167         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14168                 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14169                                  bios_mem[i]);
14170         }
14171
14172         /*
14173          * Calculate and write the microcode code checksum to the microcode
14174          * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14175          */
14176         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14177         AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14178         code_sum = 0;
14179         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14180         for (word = begin_addr; word < end_addr; word += 2) {
14181                 code_sum += AdvReadWordAutoIncLram(iop_base);
14182         }
14183         AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14184
14185         /*
14186          * Read and save microcode version and date.
14187          */
14188         AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
14189                         asc_dvc->cfg->mcode_date);
14190         AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
14191                         asc_dvc->cfg->mcode_version);
14192
14193         /*
14194          * Set the chip type to indicate the ASC3550.
14195          */
14196         AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
14197
14198         /*
14199          * If the PCI Configuration Command Register "Parity Error Response
14200          * Control" Bit was clear (0), then set the microcode variable
14201          * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14202          * to ignore DMA parity errors.
14203          */
14204         if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
14205                 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14206                 word |= CONTROL_FLAG_IGNORE_PERR;
14207                 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14208         }
14209
14210         /*
14211          * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
14212          * threshold of 128 bytes. This register is only accessible to the host.
14213          */
14214         AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14215                              START_CTL_EMFU | READ_CMD_MRM);
14216
14217         /*
14218          * Microcode operating variables for WDTR, SDTR, and command tag
14219          * queuing will be set in AdvInquiryHandling() based on what a
14220          * device reports it is capable of in Inquiry byte 7.
14221          *
14222          * If SCSI Bus Resets have been disabled, then directly set
14223          * SDTR and WDTR from the EEPROM configuration. This will allow
14224          * the BIOS and warm boot to work without a SCSI bus hang on
14225          * the Inquiry caused by host and target mismatched DTR values.
14226          * Without the SCSI Bus Reset, before an Inquiry a device can't
14227          * be assumed to be in Asynchronous, Narrow mode.
14228          */
14229         if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
14230                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
14231                                  asc_dvc->wdtr_able);
14232                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
14233                                  asc_dvc->sdtr_able);
14234         }
14235
14236         /*
14237          * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
14238          * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
14239          * bitmask. These values determine the maximum SDTR speed negotiated
14240          * with a device.
14241          *
14242          * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14243          * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14244          * without determining here whether the device supports SDTR.
14245          *
14246          * 4-bit speed  SDTR speed name
14247          * ===========  ===============
14248          * 0000b (0x0)  SDTR disabled
14249          * 0001b (0x1)  5 Mhz
14250          * 0010b (0x2)  10 Mhz
14251          * 0011b (0x3)  20 Mhz (Ultra)
14252          * 0100b (0x4)  40 Mhz (LVD/Ultra2)
14253          * 0101b (0x5)  80 Mhz (LVD2/Ultra3)
14254          * 0110b (0x6)  Undefined
14255          * .
14256          * 1111b (0xF)  Undefined
14257          */
14258         word = 0;
14259         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14260                 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
14261                         /* Set Ultra speed for TID 'tid'. */
14262                         word |= (0x3 << (4 * (tid % 4)));
14263                 } else {
14264                         /* Set Fast speed for TID 'tid'. */
14265                         word |= (0x2 << (4 * (tid % 4)));
14266                 }
14267                 if (tid == 3) { /* Check if done with sdtr_speed1. */
14268                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
14269                         word = 0;
14270                 } else if (tid == 7) {  /* Check if done with sdtr_speed2. */
14271                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
14272                         word = 0;
14273                 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
14274                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
14275                         word = 0;
14276                 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
14277                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
14278                         /* End of loop. */
14279                 }
14280         }
14281
14282         /*
14283          * Set microcode operating variable for the disconnect per TID bitmask.
14284          */
14285         AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
14286                          asc_dvc->cfg->disc_enable);
14287
14288         /*
14289          * Set SCSI_CFG0 Microcode Default Value.
14290          *
14291          * The microcode will set the SCSI_CFG0 register using this value
14292          * after it is started below.
14293          */
14294         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14295                          PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14296                          asc_dvc->chip_scsi_id);
14297
14298         /*
14299          * Determine SCSI_CFG1 Microcode Default Value.
14300          *
14301          * The microcode will set the SCSI_CFG1 register using this value
14302          * after it is started below.
14303          */
14304
14305         /* Read current SCSI_CFG1 Register value. */
14306         scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14307
14308         /*
14309          * If all three connectors are in use, return an error.
14310          */
14311         if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
14312             (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
14313                 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
14314                 return ADV_ERROR;
14315         }
14316
14317         /*
14318          * If the internal narrow cable is reversed all of the SCSI_CTRL
14319          * register signals will be set. Check for and return an error if
14320          * this condition is found.
14321          */
14322         if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
14323                 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14324                 return ADV_ERROR;
14325         }
14326
14327         /*
14328          * If this is a differential board and a single-ended device
14329          * is attached to one of the connectors, return an error.
14330          */
14331         if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
14332                 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
14333                 return ADV_ERROR;
14334         }
14335
14336         /*
14337          * If automatic termination control is enabled, then set the
14338          * termination value based on a table listed in a_condor.h.
14339          *
14340          * If manual termination was specified with an EEPROM setting
14341          * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
14342          * is ready to be 'ored' into SCSI_CFG1.
14343          */
14344         if (asc_dvc->cfg->termination == 0) {
14345                 /*
14346                  * The software always controls termination by setting TERM_CTL_SEL.
14347                  * If TERM_CTL_SEL were set to 0, the hardware would set termination.
14348                  */
14349                 asc_dvc->cfg->termination |= TERM_CTL_SEL;
14350
14351                 switch (scsi_cfg1 & CABLE_DETECT) {
14352                         /* TERM_CTL_H: on, TERM_CTL_L: on */
14353                 case 0x3:
14354                 case 0x7:
14355                 case 0xB:
14356                 case 0xD:
14357                 case 0xE:
14358                 case 0xF:
14359                         asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
14360                         break;
14361
14362                         /* TERM_CTL_H: on, TERM_CTL_L: off */
14363                 case 0x1:
14364                 case 0x5:
14365                 case 0x9:
14366                 case 0xA:
14367                 case 0xC:
14368                         asc_dvc->cfg->termination |= TERM_CTL_H;
14369                         break;
14370
14371                         /* TERM_CTL_H: off, TERM_CTL_L: off */
14372                 case 0x2:
14373                 case 0x6:
14374                         break;
14375                 }
14376         }
14377
14378         /*
14379          * Clear any set TERM_CTL_H and TERM_CTL_L bits.
14380          */
14381         scsi_cfg1 &= ~TERM_CTL;
14382
14383         /*
14384          * Invert the TERM_CTL_H and TERM_CTL_L bits and then
14385          * set 'scsi_cfg1'. The TERM_POL bit does not need to be
14386          * referenced, because the hardware internally inverts
14387          * the Termination High and Low bits if TERM_POL is set.
14388          */
14389         scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
14390
14391         /*
14392          * Set SCSI_CFG1 Microcode Default Value
14393          *
14394          * Set filter value and possibly modified termination control
14395          * bits in the Microcode SCSI_CFG1 Register Value.
14396          *
14397          * The microcode will set the SCSI_CFG1 register using this value
14398          * after it is started below.
14399          */
14400         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
14401                          FLTR_DISABLE | scsi_cfg1);
14402
14403         /*
14404          * Set MEM_CFG Microcode Default Value
14405          *
14406          * The microcode will set the MEM_CFG register using this value
14407          * after it is started below.
14408          *
14409          * MEM_CFG may be accessed as a word or byte, but only bits 0-7
14410          * are defined.
14411          *
14412          * ASC-3550 has 8KB internal memory.
14413          */
14414         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
14415                          BIOS_EN | RAM_SZ_8KB);
14416
14417         /*
14418          * Set SEL_MASK Microcode Default Value
14419          *
14420          * The microcode will set the SEL_MASK register using this value
14421          * after it is started below.
14422          */
14423         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
14424                          ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
14425
14426         /*
14427          * Build carrier freelist.
14428          *
14429          * Driver must have already allocated memory and set 'carrier_buf'.
14430          */
14431         ASC_ASSERT(asc_dvc->carrier_buf != NULL);
14432
14433         carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
14434         asc_dvc->carr_freelist = NULL;
14435         if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
14436                 buf_size = ADV_CARRIER_BUFSIZE;
14437         } else {
14438                 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
14439         }
14440
14441         do {
14442                 /*
14443                  * Get physical address of the carrier 'carrp'.
14444                  */
14445                 contig_len = sizeof(ADV_CARR_T);
14446                 carr_paddr =
14447                     cpu_to_le32(DvcGetPhyAddr
14448                                 (asc_dvc, NULL, (uchar *)carrp,
14449                                  (ADV_SDCNT *)&contig_len,
14450                                  ADV_IS_CARRIER_FLAG));
14451
14452                 buf_size -= sizeof(ADV_CARR_T);
14453
14454                 /*
14455                  * If the current carrier is not physically contiguous, then
14456                  * maybe there was a page crossing. Try the next carrier aligned
14457                  * start address.
14458                  */
14459                 if (contig_len < sizeof(ADV_CARR_T)) {
14460                         carrp++;
14461                         continue;
14462                 }
14463
14464                 carrp->carr_pa = carr_paddr;
14465                 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
14466
14467                 /*
14468                  * Insert the carrier at the beginning of the freelist.
14469                  */
14470                 carrp->next_vpa =
14471                     cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
14472                 asc_dvc->carr_freelist = carrp;
14473
14474                 carrp++;
14475         }
14476         while (buf_size > 0);
14477
14478         /*
14479          * Set-up the Host->RISC Initiator Command Queue (ICQ).
14480          */
14481
14482         if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
14483                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14484                 return ADV_ERROR;
14485         }
14486         asc_dvc->carr_freelist = (ADV_CARR_T *)
14487             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
14488
14489         /*
14490          * The first command issued will be placed in the stopper carrier.
14491          */
14492         asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14493
14494         /*
14495          * Set RISC ICQ physical address start value.
14496          */
14497         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
14498
14499         /*
14500          * Set-up the RISC->Host Initiator Response Queue (IRQ).
14501          */
14502         if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
14503                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14504                 return ADV_ERROR;
14505         }
14506         asc_dvc->carr_freelist = (ADV_CARR_T *)
14507             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
14508
14509         /*
14510          * The first command completed by the RISC will be placed in
14511          * the stopper.
14512          *
14513          * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
14514          * completed the RISC will set the ASC_RQ_STOPPER bit.
14515          */
14516         asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14517
14518         /*
14519          * Set RISC IRQ physical address start value.
14520          */
14521         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
14522         asc_dvc->carr_pending_cnt = 0;
14523
14524         AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
14525                              (ADV_INTR_ENABLE_HOST_INTR |
14526                               ADV_INTR_ENABLE_GLOBAL_INTR));
14527
14528         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
14529         AdvWriteWordRegister(iop_base, IOPW_PC, word);
14530
14531         /* finally, finally, gentlemen, start your engine */
14532         AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
14533
14534         /*
14535          * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
14536          * Resets should be performed. The RISC has to be running
14537          * to issue a SCSI Bus Reset.
14538          */
14539         if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
14540                 /*
14541                  * If the BIOS Signature is present in memory, restore the
14542                  * BIOS Handshake Configuration Table and do not perform
14543                  * a SCSI Bus Reset.
14544                  */
14545                 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
14546                     0x55AA) {
14547                         /*
14548                          * Restore per TID negotiated values.
14549                          */
14550                         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14551                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14552                         AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
14553                                          tagqng_able);
14554                         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14555                                 AdvWriteByteLram(iop_base,
14556                                                  ASC_MC_NUMBER_OF_MAX_CMD + tid,
14557                                                  max_cmd[tid]);
14558                         }
14559                 } else {
14560                         if (AdvResetSB(asc_dvc) != ADV_TRUE) {
14561                                 warn_code = ASC_WARN_BUSRESET_ERROR;
14562                         }
14563                 }
14564         }
14565
14566         return warn_code;
14567 }
14568
14569 /*
14570  * Initialize the ASC-38C0800.
14571  *
14572  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14573  *
14574  * For a non-fatal error return a warning code. If there are no warnings
14575  * then 0 is returned.
14576  *
14577  * Needed after initialization for error recovery.
14578  */
14579 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
14580 {
14581         AdvPortAddr iop_base;
14582         ushort warn_code;
14583         ADV_DCNT sum;
14584         int begin_addr;
14585         int end_addr;
14586         ushort code_sum;
14587         int word;
14588         int j;
14589         int adv_asc38C0800_expanded_size;
14590         ADV_CARR_T *carrp;
14591         ADV_DCNT contig_len;
14592         ADV_SDCNT buf_size;
14593         ADV_PADDR carr_paddr;
14594         int i;
14595         ushort scsi_cfg1;
14596         uchar byte;
14597         uchar tid;
14598         ushort bios_mem[ASC_MC_BIOSLEN / 2];    /* BIOS RISC Memory 0x40-0x8F. */
14599         ushort wdtr_able, sdtr_able, tagqng_able;
14600         uchar max_cmd[ADV_MAX_TID + 1];
14601
14602         /* If there is already an error, don't continue. */
14603         if (asc_dvc->err_code != 0) {
14604                 return ADV_ERROR;
14605         }
14606
14607         /*
14608          * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
14609          */
14610         if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
14611                 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
14612                 return ADV_ERROR;
14613         }
14614
14615         warn_code = 0;
14616         iop_base = asc_dvc->iop_base;
14617
14618         /*
14619          * Save the RISC memory BIOS region before writing the microcode.
14620          * The BIOS may already be loaded and using its RISC LRAM region
14621          * so its region must be saved and restored.
14622          *
14623          * Note: This code makes the assumption, which is currently true,
14624          * that a chip reset does not clear RISC LRAM.
14625          */
14626         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14627                 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14628                                 bios_mem[i]);
14629         }
14630
14631         /*
14632          * Save current per TID negotiated values.
14633          */
14634         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14635         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14636         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14637         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14638                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14639                                 max_cmd[tid]);
14640         }
14641
14642         /*
14643          * RAM BIST (RAM Built-In Self Test)
14644          *
14645          * Address : I/O base + offset 0x38h register (byte).
14646          * Function: Bit 7-6(RW) : RAM mode
14647          *                          Normal Mode   : 0x00
14648          *                          Pre-test Mode : 0x40
14649          *                          RAM Test Mode : 0x80
14650          *           Bit 5       : unused
14651          *           Bit 4(RO)   : Done bit
14652          *           Bit 3-0(RO) : Status
14653          *                          Host Error    : 0x08
14654          *                          Int_RAM Error : 0x04
14655          *                          RISC Error    : 0x02
14656          *                          SCSI Error    : 0x01
14657          *                          No Error      : 0x00
14658          *
14659          * Note: RAM BIST code should be put right here, before loading the
14660          * microcode and after saving the RISC memory BIOS region.
14661          */
14662
14663         /*
14664          * LRAM Pre-test
14665          *
14666          * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
14667          * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
14668          * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
14669          * to NORMAL_MODE, return an error too.
14670          */
14671         for (i = 0; i < 2; i++) {
14672                 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
14673                 DvcSleepMilliSecond(10);        /* Wait for 10ms before reading back. */
14674                 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14675                 if ((byte & RAM_TEST_DONE) == 0
14676                     || (byte & 0x0F) != PRE_TEST_VALUE) {
14677                         asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14678                         return ADV_ERROR;
14679                 }
14680
14681                 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14682                 DvcSleepMilliSecond(10);        /* Wait for 10ms before reading back. */
14683                 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
14684                     != NORMAL_VALUE) {
14685                         asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14686                         return ADV_ERROR;
14687                 }
14688         }
14689
14690         /*
14691          * LRAM Test - It takes about 1.5 ms to run through the test.
14692          *
14693          * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
14694          * If Done bit not set or Status not 0, save register byte, set the
14695          * err_code, and return an error.
14696          */
14697         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
14698         DvcSleepMilliSecond(10);        /* Wait for 10ms before checking status. */
14699
14700         byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14701         if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
14702                 /* Get here if Done bit not set or Status not 0. */
14703                 asc_dvc->bist_err_code = byte;  /* for BIOS display message */
14704                 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
14705                 return ADV_ERROR;
14706         }
14707
14708         /* We need to reset back to normal mode after LRAM test passes. */
14709         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14710
14711         /*
14712          * Load the Microcode
14713          *
14714          * Write the microcode image to RISC memory starting at address 0.
14715          *
14716          */
14717         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14718
14719         /* Assume the following compressed format of the microcode buffer:
14720          *
14721          *  254 word (508 byte) table indexed by byte code followed
14722          *  by the following byte codes:
14723          *
14724          *    1-Byte Code:
14725          *      00: Emit word 0 in table.
14726          *      01: Emit word 1 in table.
14727          *      .
14728          *      FD: Emit word 253 in table.
14729          *
14730          *    Multi-Byte Code:
14731          *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14732          *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14733          */
14734         word = 0;
14735         for (i = 253 * 2; i < _adv_asc38C0800_size; i++) {
14736                 if (_adv_asc38C0800_buf[i] == 0xff) {
14737                         for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++) {
14738                                 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14739                                                                     _adv_asc38C0800_buf
14740                                                                     [i +
14741                                                                      3] << 8) |
14742                                                                    _adv_asc38C0800_buf
14743                                                                    [i + 2]));
14744                                 word++;
14745                         }
14746                         i += 3;
14747                 } else if (_adv_asc38C0800_buf[i] == 0xfe) {
14748                         AdvWriteWordAutoIncLram(iop_base, (((ushort)
14749                                                             _adv_asc38C0800_buf
14750                                                             [i +
14751                                                              2] << 8) |
14752                                                            _adv_asc38C0800_buf[i
14753                                                                                +
14754                                                                                1]));
14755                         i += 2;
14756                         word++;
14757                 } else {
14758                         AdvWriteWordAutoIncLram(iop_base, (((ushort)
14759                                                             _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) | _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
14760                         word++;
14761                 }
14762         }
14763
14764         /*
14765          * Set 'word' for later use to clear the rest of memory and save
14766          * the expanded mcode size.
14767          */
14768         word *= 2;
14769         adv_asc38C0800_expanded_size = word;
14770
14771         /*
14772          * Clear the rest of ASC-38C0800 Internal RAM (16KB).
14773          */
14774         for (; word < ADV_38C0800_MEMSIZE; word += 2) {
14775                 AdvWriteWordAutoIncLram(iop_base, 0);
14776         }
14777
14778         /*
14779          * Verify the microcode checksum.
14780          */
14781         sum = 0;
14782         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14783
14784         for (word = 0; word < adv_asc38C0800_expanded_size; word += 2) {
14785                 sum += AdvReadWordAutoIncLram(iop_base);
14786         }
14787         ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
14788
14789         ASC_DBG2(1,
14790                  "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
14791                  (ulong)sum, (ulong)_adv_asc38C0800_chksum);
14792
14793         if (sum != _adv_asc38C0800_chksum) {
14794                 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14795                 return ADV_ERROR;
14796         }
14797
14798         /*
14799          * Restore the RISC memory BIOS region.
14800          */
14801         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14802                 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14803                                  bios_mem[i]);
14804         }
14805
14806         /*
14807          * Calculate and write the microcode code checksum to the microcode
14808          * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14809          */
14810         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14811         AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14812         code_sum = 0;
14813         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14814         for (word = begin_addr; word < end_addr; word += 2) {
14815                 code_sum += AdvReadWordAutoIncLram(iop_base);
14816         }
14817         AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14818
14819         /*
14820          * Read microcode version and date.
14821          */
14822         AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
14823                         asc_dvc->cfg->mcode_date);
14824         AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
14825                         asc_dvc->cfg->mcode_version);
14826
14827         /*
14828          * Set the chip type to indicate the ASC38C0800.
14829          */
14830         AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
14831
14832         /*
14833          * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
14834          * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
14835          * cable detection and then we are able to read C_DET[3:0].
14836          *
14837          * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
14838          * Microcode Default Value' section below.
14839          */
14840         scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14841         AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
14842                              scsi_cfg1 | DIS_TERM_DRV);
14843
14844         /*
14845          * If the PCI Configuration Command Register "Parity Error Response
14846          * Control" Bit was clear (0), then set the microcode variable
14847          * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14848          * to ignore DMA parity errors.
14849          */
14850         if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
14851                 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14852                 word |= CONTROL_FLAG_IGNORE_PERR;
14853                 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14854         }
14855
14856         /*
14857          * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
14858          * bits for the default FIFO threshold.
14859          *
14860          * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
14861          *
14862          * For DMA Errata #4 set the BC_THRESH_ENB bit.
14863          */
14864         AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14865                              BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
14866                              READ_CMD_MRM);
14867
14868         /*
14869          * Microcode operating variables for WDTR, SDTR, and command tag
14870          * queuing will be set in AdvInquiryHandling() based on what a
14871          * device reports it is capable of in Inquiry byte 7.
14872          *
14873          * If SCSI Bus Resets have been disabled, then directly set
14874          * SDTR and WDTR from the EEPROM configuration. This will allow
14875          * the BIOS and warm boot to work without a SCSI bus hang on
14876          * the Inquiry caused by host and target mismatched DTR values.
14877          * Without the SCSI Bus Reset, before an Inquiry a device can't
14878          * be assumed to be in Asynchronous, Narrow mode.
14879          */
14880         if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
14881                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
14882                                  asc_dvc->wdtr_able);
14883                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
14884                                  asc_dvc->sdtr_able);
14885         }
14886
14887         /*
14888          * Set microcode operating variables for DISC and SDTR_SPEED1,
14889          * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
14890          * configuration values.
14891          *
14892          * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14893          * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14894          * without determining here whether the device supports SDTR.
14895          */
14896         AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
14897                          asc_dvc->cfg->disc_enable);
14898         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
14899         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
14900         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
14901         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
14902
14903         /*
14904          * Set SCSI_CFG0 Microcode Default Value.
14905          *
14906          * The microcode will set the SCSI_CFG0 register using this value
14907          * after it is started below.
14908          */
14909         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14910                          PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14911                          asc_dvc->chip_scsi_id);
14912
14913         /*
14914          * Determine SCSI_CFG1 Microcode Default Value.
14915          *
14916          * The microcode will set the SCSI_CFG1 register using this value
14917          * after it is started below.
14918          */
14919
14920         /* Read current SCSI_CFG1 Register value. */
14921         scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14922
14923         /*
14924          * If the internal narrow cable is reversed all of the SCSI_CTRL
14925          * register signals will be set. Check for and return an error if
14926          * this condition is found.
14927          */
14928         if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
14929                 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14930                 return ADV_ERROR;
14931         }
14932
14933         /*
14934          * All kind of combinations of devices attached to one of four connectors
14935          * are acceptable except HVD device attached. For example, LVD device can
14936          * be attached to SE connector while SE device attached to LVD connector.
14937          * If LVD device attached to SE connector, it only runs up to Ultra speed.
14938          *
14939          * If an HVD device is attached to one of LVD connectors, return an error.
14940          * However, there is no way to detect HVD device attached to SE connectors.
14941          */
14942         if (scsi_cfg1 & HVD) {
14943                 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
14944                 return ADV_ERROR;
14945         }
14946
14947         /*
14948          * If either SE or LVD automatic termination control is enabled, then
14949          * set the termination value based on a table listed in a_condor.h.
14950          *
14951          * If manual termination was specified with an EEPROM setting then
14952          * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
14953          * be 'ored' into SCSI_CFG1.
14954          */
14955         if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
14956                 /* SE automatic termination control is enabled. */
14957                 switch (scsi_cfg1 & C_DET_SE) {
14958                         /* TERM_SE_HI: on, TERM_SE_LO: on */
14959                 case 0x1:
14960                 case 0x2:
14961                 case 0x3:
14962                         asc_dvc->cfg->termination |= TERM_SE;
14963                         break;
14964
14965                         /* TERM_SE_HI: on, TERM_SE_LO: off */
14966                 case 0x0:
14967                         asc_dvc->cfg->termination |= TERM_SE_HI;
14968                         break;
14969                 }
14970         }
14971
14972         if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
14973                 /* LVD automatic termination control is enabled. */
14974                 switch (scsi_cfg1 & C_DET_LVD) {
14975                         /* TERM_LVD_HI: on, TERM_LVD_LO: on */
14976                 case 0x4:
14977                 case 0x8:
14978                 case 0xC:
14979                         asc_dvc->cfg->termination |= TERM_LVD;
14980                         break;
14981
14982                         /* TERM_LVD_HI: off, TERM_LVD_LO: off */
14983                 case 0x0:
14984                         break;
14985                 }
14986         }
14987
14988         /*
14989          * Clear any set TERM_SE and TERM_LVD bits.
14990          */
14991         scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
14992
14993         /*
14994          * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
14995          */
14996         scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
14997
14998         /*
14999          * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
15000          * and set possibly modified termination control bits in the Microcode
15001          * SCSI_CFG1 Register Value.
15002          */
15003         scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
15004
15005         /*
15006          * Set SCSI_CFG1 Microcode Default Value
15007          *
15008          * Set possibly modified termination control and reset DIS_TERM_DRV
15009          * bits in the Microcode SCSI_CFG1 Register Value.
15010          *
15011          * The microcode will set the SCSI_CFG1 register using this value
15012          * after it is started below.
15013          */
15014         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15015
15016         /*
15017          * Set MEM_CFG Microcode Default Value
15018          *
15019          * The microcode will set the MEM_CFG register using this value
15020          * after it is started below.
15021          *
15022          * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15023          * are defined.
15024          *
15025          * ASC-38C0800 has 16KB internal memory.
15026          */
15027         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15028                          BIOS_EN | RAM_SZ_16KB);
15029
15030         /*
15031          * Set SEL_MASK Microcode Default Value
15032          *
15033          * The microcode will set the SEL_MASK register using this value
15034          * after it is started below.
15035          */
15036         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15037                          ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15038
15039         /*
15040          * Build the carrier freelist.
15041          *
15042          * Driver must have already allocated memory and set 'carrier_buf'.
15043          */
15044         ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15045
15046         carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15047         asc_dvc->carr_freelist = NULL;
15048         if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
15049                 buf_size = ADV_CARRIER_BUFSIZE;
15050         } else {
15051                 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15052         }
15053
15054         do {
15055                 /*
15056                  * Get physical address for the carrier 'carrp'.
15057                  */
15058                 contig_len = sizeof(ADV_CARR_T);
15059                 carr_paddr =
15060                     cpu_to_le32(DvcGetPhyAddr
15061                                 (asc_dvc, NULL, (uchar *)carrp,
15062                                  (ADV_SDCNT *)&contig_len,
15063                                  ADV_IS_CARRIER_FLAG));
15064
15065                 buf_size -= sizeof(ADV_CARR_T);
15066
15067                 /*
15068                  * If the current carrier is not physically contiguous, then
15069                  * maybe there was a page crossing. Try the next carrier aligned
15070                  * start address.
15071                  */
15072                 if (contig_len < sizeof(ADV_CARR_T)) {
15073                         carrp++;
15074                         continue;
15075                 }
15076
15077                 carrp->carr_pa = carr_paddr;
15078                 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15079
15080                 /*
15081                  * Insert the carrier at the beginning of the freelist.
15082                  */
15083                 carrp->next_vpa =
15084                     cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15085                 asc_dvc->carr_freelist = carrp;
15086
15087                 carrp++;
15088         }
15089         while (buf_size > 0);
15090
15091         /*
15092          * Set-up the Host->RISC Initiator Command Queue (ICQ).
15093          */
15094
15095         if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
15096                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15097                 return ADV_ERROR;
15098         }
15099         asc_dvc->carr_freelist = (ADV_CARR_T *)
15100             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15101
15102         /*
15103          * The first command issued will be placed in the stopper carrier.
15104          */
15105         asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15106
15107         /*
15108          * Set RISC ICQ physical address start value.
15109          * carr_pa is LE, must be native before write
15110          */
15111         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15112
15113         /*
15114          * Set-up the RISC->Host Initiator Response Queue (IRQ).
15115          */
15116         if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
15117                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15118                 return ADV_ERROR;
15119         }
15120         asc_dvc->carr_freelist = (ADV_CARR_T *)
15121             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15122
15123         /*
15124          * The first command completed by the RISC will be placed in
15125          * the stopper.
15126          *
15127          * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15128          * completed the RISC will set the ASC_RQ_STOPPER bit.
15129          */
15130         asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15131
15132         /*
15133          * Set RISC IRQ physical address start value.
15134          *
15135          * carr_pa is LE, must be native before write *
15136          */
15137         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15138         asc_dvc->carr_pending_cnt = 0;
15139
15140         AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15141                              (ADV_INTR_ENABLE_HOST_INTR |
15142                               ADV_INTR_ENABLE_GLOBAL_INTR));
15143
15144         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15145         AdvWriteWordRegister(iop_base, IOPW_PC, word);
15146
15147         /* finally, finally, gentlemen, start your engine */
15148         AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15149
15150         /*
15151          * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15152          * Resets should be performed. The RISC has to be running
15153          * to issue a SCSI Bus Reset.
15154          */
15155         if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
15156                 /*
15157                  * If the BIOS Signature is present in memory, restore the
15158                  * BIOS Handshake Configuration Table and do not perform
15159                  * a SCSI Bus Reset.
15160                  */
15161                 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
15162                     0x55AA) {
15163                         /*
15164                          * Restore per TID negotiated values.
15165                          */
15166                         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15167                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15168                         AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
15169                                          tagqng_able);
15170                         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
15171                                 AdvWriteByteLram(iop_base,
15172                                                  ASC_MC_NUMBER_OF_MAX_CMD + tid,
15173                                                  max_cmd[tid]);
15174                         }
15175                 } else {
15176                         if (AdvResetSB(asc_dvc) != ADV_TRUE) {
15177                                 warn_code = ASC_WARN_BUSRESET_ERROR;
15178                         }
15179                 }
15180         }
15181
15182         return warn_code;
15183 }
15184
15185 /*
15186  * Initialize the ASC-38C1600.
15187  *
15188  * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
15189  *
15190  * For a non-fatal error return a warning code. If there are no warnings
15191  * then 0 is returned.
15192  *
15193  * Needed after initialization for error recovery.
15194  */
15195 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
15196 {
15197         AdvPortAddr iop_base;
15198         ushort warn_code;
15199         ADV_DCNT sum;
15200         int begin_addr;
15201         int end_addr;
15202         ushort code_sum;
15203         long word;
15204         int j;
15205         int adv_asc38C1600_expanded_size;
15206         ADV_CARR_T *carrp;
15207         ADV_DCNT contig_len;
15208         ADV_SDCNT buf_size;
15209         ADV_PADDR carr_paddr;
15210         int i;
15211         ushort scsi_cfg1;
15212         uchar byte;
15213         uchar tid;
15214         ushort bios_mem[ASC_MC_BIOSLEN / 2];    /* BIOS RISC Memory 0x40-0x8F. */
15215         ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
15216         uchar max_cmd[ASC_MAX_TID + 1];
15217
15218         /* If there is already an error, don't continue. */
15219         if (asc_dvc->err_code != 0) {
15220                 return ADV_ERROR;
15221         }
15222
15223         /*
15224          * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
15225          */
15226         if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
15227                 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
15228                 return ADV_ERROR;
15229         }
15230
15231         warn_code = 0;
15232         iop_base = asc_dvc->iop_base;
15233
15234         /*
15235          * Save the RISC memory BIOS region before writing the microcode.
15236          * The BIOS may already be loaded and using its RISC LRAM region
15237          * so its region must be saved and restored.
15238          *
15239          * Note: This code makes the assumption, which is currently true,
15240          * that a chip reset does not clear RISC LRAM.
15241          */
15242         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15243                 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15244                                 bios_mem[i]);
15245         }
15246
15247         /*
15248          * Save current per TID negotiated values.
15249          */
15250         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15251         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15252         AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15253         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15254         for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15255                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15256                                 max_cmd[tid]);
15257         }
15258
15259         /*
15260          * RAM BIST (Built-In Self Test)
15261          *
15262          * Address : I/O base + offset 0x38h register (byte).
15263          * Function: Bit 7-6(RW) : RAM mode
15264          *                          Normal Mode   : 0x00
15265          *                          Pre-test Mode : 0x40
15266          *                          RAM Test Mode : 0x80
15267          *           Bit 5       : unused
15268          *           Bit 4(RO)   : Done bit
15269          *           Bit 3-0(RO) : Status
15270          *                          Host Error    : 0x08
15271          *                          Int_RAM Error : 0x04
15272          *                          RISC Error    : 0x02
15273          *                          SCSI Error    : 0x01
15274          *                          No Error      : 0x00
15275          *
15276          * Note: RAM BIST code should be put right here, before loading the
15277          * microcode and after saving the RISC memory BIOS region.
15278          */
15279
15280         /*
15281          * LRAM Pre-test
15282          *
15283          * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15284          * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15285          * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15286          * to NORMAL_MODE, return an error too.
15287          */
15288         for (i = 0; i < 2; i++) {
15289                 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15290                 DvcSleepMilliSecond(10);        /* Wait for 10ms before reading back. */
15291                 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15292                 if ((byte & RAM_TEST_DONE) == 0
15293                     || (byte & 0x0F) != PRE_TEST_VALUE) {
15294                         asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15295                         return ADV_ERROR;
15296                 }
15297
15298                 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15299                 DvcSleepMilliSecond(10);        /* Wait for 10ms before reading back. */
15300                 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15301                     != NORMAL_VALUE) {
15302                         asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15303                         return ADV_ERROR;
15304                 }
15305         }
15306
15307         /*
15308          * LRAM Test - It takes about 1.5 ms to run through the test.
15309          *
15310          * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15311          * If Done bit not set or Status not 0, save register byte, set the
15312          * err_code, and return an error.
15313          */
15314         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15315         DvcSleepMilliSecond(10);        /* Wait for 10ms before checking status. */
15316
15317         byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15318         if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
15319                 /* Get here if Done bit not set or Status not 0. */
15320                 asc_dvc->bist_err_code = byte;  /* for BIOS display message */
15321                 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15322                 return ADV_ERROR;
15323         }
15324
15325         /* We need to reset back to normal mode after LRAM test passes. */
15326         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15327
15328         /*
15329          * Load the Microcode
15330          *
15331          * Write the microcode image to RISC memory starting at address 0.
15332          *
15333          */
15334         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15335
15336         /*
15337          * Assume the following compressed format of the microcode buffer:
15338          *
15339          *  254 word (508 byte) table indexed by byte code followed
15340          *  by the following byte codes:
15341          *
15342          *    1-Byte Code:
15343          *      00: Emit word 0 in table.
15344          *      01: Emit word 1 in table.
15345          *      .
15346          *      FD: Emit word 253 in table.
15347          *
15348          *    Multi-Byte Code:
15349          *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15350          *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15351          */
15352         word = 0;
15353         for (i = 253 * 2; i < _adv_asc38C1600_size; i++) {
15354                 if (_adv_asc38C1600_buf[i] == 0xff) {
15355                         for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++) {
15356                                 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15357                                                                     _adv_asc38C1600_buf
15358                                                                     [i +
15359                                                                      3] << 8) |
15360                                                                    _adv_asc38C1600_buf
15361                                                                    [i + 2]));
15362                                 word++;
15363                         }
15364                         i += 3;
15365                 } else if (_adv_asc38C1600_buf[i] == 0xfe) {
15366                         AdvWriteWordAutoIncLram(iop_base, (((ushort)
15367                                                             _adv_asc38C1600_buf
15368                                                             [i +
15369                                                              2] << 8) |
15370                                                            _adv_asc38C1600_buf[i
15371                                                                                +
15372                                                                                1]));
15373                         i += 2;
15374                         word++;
15375                 } else {
15376                         AdvWriteWordAutoIncLram(iop_base, (((ushort)
15377                                                             _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) | _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
15378                         word++;
15379                 }
15380         }
15381
15382         /*
15383          * Set 'word' for later use to clear the rest of memory and save
15384          * the expanded mcode size.
15385          */
15386         word *= 2;
15387         adv_asc38C1600_expanded_size = word;
15388
15389         /*
15390          * Clear the rest of ASC-38C1600 Internal RAM (32KB).
15391          */
15392         for (; word < ADV_38C1600_MEMSIZE; word += 2) {
15393                 AdvWriteWordAutoIncLram(iop_base, 0);
15394         }
15395
15396         /*
15397          * Verify the microcode checksum.
15398          */
15399         sum = 0;
15400         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15401
15402         for (word = 0; word < adv_asc38C1600_expanded_size; word += 2) {
15403                 sum += AdvReadWordAutoIncLram(iop_base);
15404         }
15405
15406         if (sum != _adv_asc38C1600_chksum) {
15407                 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15408                 return ADV_ERROR;
15409         }
15410
15411         /*
15412          * Restore the RISC memory BIOS region.
15413          */
15414         for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15415                 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15416                                  bios_mem[i]);
15417         }
15418
15419         /*
15420          * Calculate and write the microcode code checksum to the microcode
15421          * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15422          */
15423         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15424         AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15425         code_sum = 0;
15426         AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15427         for (word = begin_addr; word < end_addr; word += 2) {
15428                 code_sum += AdvReadWordAutoIncLram(iop_base);
15429         }
15430         AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15431
15432         /*
15433          * Read microcode version and date.
15434          */
15435         AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
15436                         asc_dvc->cfg->mcode_date);
15437         AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
15438                         asc_dvc->cfg->mcode_version);
15439
15440         /*
15441          * Set the chip type to indicate the ASC38C1600.
15442          */
15443         AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
15444
15445         /*
15446          * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15447          * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15448          * cable detection and then we are able to read C_DET[3:0].
15449          *
15450          * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15451          * Microcode Default Value' section below.
15452          */
15453         scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15454         AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
15455                              scsi_cfg1 | DIS_TERM_DRV);
15456
15457         /*
15458          * If the PCI Configuration Command Register "Parity Error Response
15459          * Control" Bit was clear (0), then set the microcode variable
15460          * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15461          * to ignore DMA parity errors.
15462          */
15463         if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
15464                 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15465                 word |= CONTROL_FLAG_IGNORE_PERR;
15466                 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15467         }
15468
15469         /*
15470          * If the BIOS control flag AIPP (Asynchronous Information
15471          * Phase Protection) disable bit is not set, then set the firmware
15472          * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
15473          * AIPP checking and encoding.
15474          */
15475         if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
15476                 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15477                 word |= CONTROL_FLAG_ENABLE_AIPP;
15478                 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15479         }
15480
15481         /*
15482          * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
15483          * and START_CTL_TH [3:2].
15484          */
15485         AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15486                              FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
15487
15488         /*
15489          * Microcode operating variables for WDTR, SDTR, and command tag
15490          * queuing will be set in AdvInquiryHandling() based on what a
15491          * device reports it is capable of in Inquiry byte 7.
15492          *
15493          * If SCSI Bus Resets have been disabled, then directly set
15494          * SDTR and WDTR from the EEPROM configuration. This will allow
15495          * the BIOS and warm boot to work without a SCSI bus hang on
15496          * the Inquiry caused by host and target mismatched DTR values.
15497          * Without the SCSI Bus Reset, before an Inquiry a device can't
15498          * be assumed to be in Asynchronous, Narrow mode.
15499          */
15500         if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
15501                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
15502                                  asc_dvc->wdtr_able);
15503                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
15504                                  asc_dvc->sdtr_able);
15505         }
15506
15507         /*
15508          * Set microcode operating variables for DISC and SDTR_SPEED1,
15509          * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15510          * configuration values.
15511          *
15512          * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15513          * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15514          * without determining here whether the device supports SDTR.
15515          */
15516         AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
15517                          asc_dvc->cfg->disc_enable);
15518         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15519         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15520         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15521         AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15522
15523         /*
15524          * Set SCSI_CFG0 Microcode Default Value.
15525          *
15526          * The microcode will set the SCSI_CFG0 register using this value
15527          * after it is started below.
15528          */
15529         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15530                          PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15531                          asc_dvc->chip_scsi_id);
15532
15533         /*
15534          * Calculate SCSI_CFG1 Microcode Default Value.
15535          *
15536          * The microcode will set the SCSI_CFG1 register using this value
15537          * after it is started below.
15538          *
15539          * Each ASC-38C1600 function has only two cable detect bits.
15540          * The bus mode override bits are in IOPB_SOFT_OVER_WR.
15541          */
15542         scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15543
15544         /*
15545          * If the cable is reversed all of the SCSI_CTRL register signals
15546          * will be set. Check for and return an error if this condition is
15547          * found.
15548          */
15549         if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
15550                 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15551                 return ADV_ERROR;
15552         }
15553
15554         /*
15555          * Each ASC-38C1600 function has two connectors. Only an HVD device
15556          * can not be connected to either connector. An LVD device or SE device
15557          * may be connected to either connecor. If an SE device is connected,
15558          * then at most Ultra speed (20 Mhz) can be used on both connectors.
15559          *
15560          * If an HVD device is attached, return an error.
15561          */
15562         if (scsi_cfg1 & HVD) {
15563                 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15564                 return ADV_ERROR;
15565         }
15566
15567         /*
15568          * Each function in the ASC-38C1600 uses only the SE cable detect and
15569          * termination because there are two connectors for each function. Each
15570          * function may use either LVD or SE mode. Corresponding the SE automatic
15571          * termination control EEPROM bits are used for each function. Each
15572          * function has its own EEPROM. If SE automatic control is enabled for
15573          * the function, then set the termination value based on a table listed
15574          * in a_condor.h.
15575          *
15576          * If manual termination is specified in the EEPROM for the function,
15577          * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
15578          * ready to be 'ored' into SCSI_CFG1.
15579          */
15580         if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
15581                 /* SE automatic termination control is enabled. */
15582                 switch (scsi_cfg1 & C_DET_SE) {
15583                         /* TERM_SE_HI: on, TERM_SE_LO: on */
15584                 case 0x1:
15585                 case 0x2:
15586                 case 0x3:
15587                         asc_dvc->cfg->termination |= TERM_SE;
15588                         break;
15589
15590                 case 0x0:
15591                         if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0) {
15592                                 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
15593                         } else {
15594                                 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
15595                                 asc_dvc->cfg->termination |= TERM_SE_HI;
15596                         }
15597                         break;
15598                 }
15599         }
15600
15601         /*
15602          * Clear any set TERM_SE bits.
15603          */
15604         scsi_cfg1 &= ~TERM_SE;
15605
15606         /*
15607          * Invert the TERM_SE bits and then set 'scsi_cfg1'.
15608          */
15609         scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
15610
15611         /*
15612          * Clear Big Endian and Terminator Polarity bits and set possibly
15613          * modified termination control bits in the Microcode SCSI_CFG1
15614          * Register Value.
15615          *
15616          * Big Endian bit is not used even on big endian machines.
15617          */
15618         scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
15619
15620         /*
15621          * Set SCSI_CFG1 Microcode Default Value
15622          *
15623          * Set possibly modified termination control bits in the Microcode
15624          * SCSI_CFG1 Register Value.
15625          *
15626          * The microcode will set the SCSI_CFG1 register using this value
15627          * after it is started below.
15628          */
15629         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15630
15631         /*
15632          * Set MEM_CFG Microcode Default Value
15633          *
15634          * The microcode will set the MEM_CFG register using this value
15635          * after it is started below.
15636          *
15637          * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15638          * are defined.
15639          *
15640          * ASC-38C1600 has 32KB internal memory.
15641          *
15642          * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
15643          * out a special 16K Adv Library and Microcode version. After the issue
15644          * resolved, we should turn back to the 32K support. Both a_condor.h and
15645          * mcode.sas files also need to be updated.
15646          *
15647          * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15648          *  BIOS_EN | RAM_SZ_32KB);
15649          */
15650         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15651                          BIOS_EN | RAM_SZ_16KB);
15652
15653         /*
15654          * Set SEL_MASK Microcode Default Value
15655          *
15656          * The microcode will set the SEL_MASK register using this value
15657          * after it is started below.
15658          */
15659         AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15660                          ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15661
15662         /*
15663          * Build the carrier freelist.
15664          *
15665          * Driver must have already allocated memory and set 'carrier_buf'.
15666          */
15667
15668         ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15669
15670         carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15671         asc_dvc->carr_freelist = NULL;
15672         if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
15673                 buf_size = ADV_CARRIER_BUFSIZE;
15674         } else {
15675                 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15676         }
15677
15678         do {
15679                 /*
15680                  * Get physical address for the carrier 'carrp'.
15681                  */
15682                 contig_len = sizeof(ADV_CARR_T);
15683                 carr_paddr =
15684                     cpu_to_le32(DvcGetPhyAddr
15685                                 (asc_dvc, NULL, (uchar *)carrp,
15686                                  (ADV_SDCNT *)&contig_len,
15687                                  ADV_IS_CARRIER_FLAG));
15688
15689                 buf_size -= sizeof(ADV_CARR_T);
15690
15691                 /*
15692                  * If the current carrier is not physically contiguous, then
15693                  * maybe there was a page crossing. Try the next carrier aligned
15694                  * start address.
15695                  */
15696                 if (contig_len < sizeof(ADV_CARR_T)) {
15697                         carrp++;
15698                         continue;
15699                 }
15700
15701                 carrp->carr_pa = carr_paddr;
15702                 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15703
15704                 /*
15705                  * Insert the carrier at the beginning of the freelist.
15706                  */
15707                 carrp->next_vpa =
15708                     cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15709                 asc_dvc->carr_freelist = carrp;
15710
15711                 carrp++;
15712         }
15713         while (buf_size > 0);
15714
15715         /*
15716          * Set-up the Host->RISC Initiator Command Queue (ICQ).
15717          */
15718         if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
15719                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15720                 return ADV_ERROR;
15721         }
15722         asc_dvc->carr_freelist = (ADV_CARR_T *)
15723             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15724
15725         /*
15726          * The first command issued will be placed in the stopper carrier.
15727          */
15728         asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15729
15730         /*
15731          * Set RISC ICQ physical address start value. Initialize the
15732          * COMMA register to the same value otherwise the RISC will
15733          * prematurely detect a command is available.
15734          */
15735         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15736         AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
15737                               le32_to_cpu(asc_dvc->icq_sp->carr_pa));
15738
15739         /*
15740          * Set-up the RISC->Host Initiator Response Queue (IRQ).
15741          */
15742         if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
15743                 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15744                 return ADV_ERROR;
15745         }
15746         asc_dvc->carr_freelist = (ADV_CARR_T *)
15747             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15748
15749         /*
15750          * The first command completed by the RISC will be placed in
15751          * the stopper.
15752          *
15753          * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15754          * completed the RISC will set the ASC_RQ_STOPPER bit.
15755          */
15756         asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15757
15758         /*
15759          * Set RISC IRQ physical address start value.
15760          */
15761         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15762         asc_dvc->carr_pending_cnt = 0;
15763
15764         AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15765                              (ADV_INTR_ENABLE_HOST_INTR |
15766                               ADV_INTR_ENABLE_GLOBAL_INTR));
15767         AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15768         AdvWriteWordRegister(iop_base, IOPW_PC, word);
15769
15770         /* finally, finally, gentlemen, start your engine */
15771         AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15772
15773         /*
15774          * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15775          * Resets should be performed. The RISC has to be running
15776          * to issue a SCSI Bus Reset.
15777          */
15778         if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
15779                 /*
15780                  * If the BIOS Signature is present in memory, restore the
15781                  * per TID microcode operating variables.
15782                  */
15783                 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
15784                     0x55AA) {
15785                         /*
15786                          * Restore per TID negotiated values.
15787                          */
15788                         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15789                         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15790                         AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15791                         AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
15792                                          tagqng_able);
15793                         for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15794                                 AdvWriteByteLram(iop_base,
15795                                                  ASC_MC_NUMBER_OF_MAX_CMD + tid,
15796                                                  max_cmd[tid]);
15797                         }
15798                 } else {
15799                         if (AdvResetSB(asc_dvc) != ADV_TRUE) {
15800                                 warn_code = ASC_WARN_BUSRESET_ERROR;
15801                         }
15802                 }
15803         }
15804
15805         return warn_code;
15806 }
15807
15808 /*
15809  * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
15810  * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
15811  * all of this is done.
15812  *
15813  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15814  *
15815  * For a non-fatal error return a warning code. If there are no warnings
15816  * then 0 is returned.
15817  *
15818  * Note: Chip is stopped on entry.
15819  */
15820 static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
15821 {
15822         AdvPortAddr iop_base;
15823         ushort warn_code;
15824         ADVEEP_3550_CONFIG eep_config;
15825         int i;
15826
15827         iop_base = asc_dvc->iop_base;
15828
15829         warn_code = 0;
15830
15831         /*
15832          * Read the board's EEPROM configuration.
15833          *
15834          * Set default values if a bad checksum is found.
15835          */
15836         if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
15837                 warn_code |= ASC_WARN_EEPROM_CHKSUM;
15838
15839                 /*
15840                  * Set EEPROM default values.
15841                  */
15842                 for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++) {
15843                         *((uchar *)&eep_config + i) =
15844                             *((uchar *)&Default_3550_EEPROM_Config + i);
15845                 }
15846
15847                 /*
15848                  * Assume the 6 byte board serial number that was read
15849                  * from EEPROM is correct even if the EEPROM checksum
15850                  * failed.
15851                  */
15852                 eep_config.serial_number_word3 =
15853                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
15854
15855                 eep_config.serial_number_word2 =
15856                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
15857
15858                 eep_config.serial_number_word1 =
15859                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
15860
15861                 AdvSet3550EEPConfig(iop_base, &eep_config);
15862         }
15863         /*
15864          * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
15865          * EEPROM configuration that was read.
15866          *
15867          * This is the mapping of EEPROM fields to Adv Library fields.
15868          */
15869         asc_dvc->wdtr_able = eep_config.wdtr_able;
15870         asc_dvc->sdtr_able = eep_config.sdtr_able;
15871         asc_dvc->ultra_able = eep_config.ultra_able;
15872         asc_dvc->tagqng_able = eep_config.tagqng_able;
15873         asc_dvc->cfg->disc_enable = eep_config.disc_enable;
15874         asc_dvc->max_host_qng = eep_config.max_host_qng;
15875         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15876         asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
15877         asc_dvc->start_motor = eep_config.start_motor;
15878         asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
15879         asc_dvc->bios_ctrl = eep_config.bios_ctrl;
15880         asc_dvc->no_scam = eep_config.scam_tolerant;
15881         asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
15882         asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
15883         asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
15884
15885         /*
15886          * Set the host maximum queuing (max. 253, min. 16) and the per device
15887          * maximum queuing (max. 63, min. 4).
15888          */
15889         if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
15890                 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15891         } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
15892                 /* If the value is zero, assume it is uninitialized. */
15893                 if (eep_config.max_host_qng == 0) {
15894                         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15895                 } else {
15896                         eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
15897                 }
15898         }
15899
15900         if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
15901                 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15902         } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
15903                 /* If the value is zero, assume it is uninitialized. */
15904                 if (eep_config.max_dvc_qng == 0) {
15905                         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15906                 } else {
15907                         eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
15908                 }
15909         }
15910
15911         /*
15912          * If 'max_dvc_qng' is greater than 'max_host_qng', then
15913          * set 'max_dvc_qng' to 'max_host_qng'.
15914          */
15915         if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
15916                 eep_config.max_dvc_qng = eep_config.max_host_qng;
15917         }
15918
15919         /*
15920          * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
15921          * values based on possibly adjusted EEPROM values.
15922          */
15923         asc_dvc->max_host_qng = eep_config.max_host_qng;
15924         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15925
15926         /*
15927          * If the EEPROM 'termination' field is set to automatic (0), then set
15928          * the ADV_DVC_CFG 'termination' field to automatic also.
15929          *
15930          * If the termination is specified with a non-zero 'termination'
15931          * value check that a legal value is set and set the ADV_DVC_CFG
15932          * 'termination' field appropriately.
15933          */
15934         if (eep_config.termination == 0) {
15935                 asc_dvc->cfg->termination = 0;  /* auto termination */
15936         } else {
15937                 /* Enable manual control with low off / high off. */
15938                 if (eep_config.termination == 1) {
15939                         asc_dvc->cfg->termination = TERM_CTL_SEL;
15940
15941                         /* Enable manual control with low off / high on. */
15942                 } else if (eep_config.termination == 2) {
15943                         asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
15944
15945                         /* Enable manual control with low on / high on. */
15946                 } else if (eep_config.termination == 3) {
15947                         asc_dvc->cfg->termination =
15948                             TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
15949                 } else {
15950                         /*
15951                          * The EEPROM 'termination' field contains a bad value. Use
15952                          * automatic termination instead.
15953                          */
15954                         asc_dvc->cfg->termination = 0;
15955                         warn_code |= ASC_WARN_EEPROM_TERMINATION;
15956                 }
15957         }
15958
15959         return warn_code;
15960 }
15961
15962 /*
15963  * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
15964  * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
15965  * all of this is done.
15966  *
15967  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15968  *
15969  * For a non-fatal error return a warning code. If there are no warnings
15970  * then 0 is returned.
15971  *
15972  * Note: Chip is stopped on entry.
15973  */
15974 static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
15975 {
15976         AdvPortAddr iop_base;
15977         ushort warn_code;
15978         ADVEEP_38C0800_CONFIG eep_config;
15979         int i;
15980         uchar tid, termination;
15981         ushort sdtr_speed = 0;
15982
15983         iop_base = asc_dvc->iop_base;
15984
15985         warn_code = 0;
15986
15987         /*
15988          * Read the board's EEPROM configuration.
15989          *
15990          * Set default values if a bad checksum is found.
15991          */
15992         if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
15993             eep_config.check_sum) {
15994                 warn_code |= ASC_WARN_EEPROM_CHKSUM;
15995
15996                 /*
15997                  * Set EEPROM default values.
15998                  */
15999                 for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++) {
16000                         *((uchar *)&eep_config + i) =
16001                             *((uchar *)&Default_38C0800_EEPROM_Config + i);
16002                 }
16003
16004                 /*
16005                  * Assume the 6 byte board serial number that was read
16006                  * from EEPROM is correct even if the EEPROM checksum
16007                  * failed.
16008                  */
16009                 eep_config.serial_number_word3 =
16010                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16011
16012                 eep_config.serial_number_word2 =
16013                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16014
16015                 eep_config.serial_number_word1 =
16016                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16017
16018                 AdvSet38C0800EEPConfig(iop_base, &eep_config);
16019         }
16020         /*
16021          * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
16022          * EEPROM configuration that was read.
16023          *
16024          * This is the mapping of EEPROM fields to Adv Library fields.
16025          */
16026         asc_dvc->wdtr_able = eep_config.wdtr_able;
16027         asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16028         asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16029         asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16030         asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16031         asc_dvc->tagqng_able = eep_config.tagqng_able;
16032         asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16033         asc_dvc->max_host_qng = eep_config.max_host_qng;
16034         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16035         asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16036         asc_dvc->start_motor = eep_config.start_motor;
16037         asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16038         asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16039         asc_dvc->no_scam = eep_config.scam_tolerant;
16040         asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16041         asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16042         asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16043
16044         /*
16045          * For every Target ID if any of its 'sdtr_speed[1234]' bits
16046          * are set, then set an 'sdtr_able' bit for it.
16047          */
16048         asc_dvc->sdtr_able = 0;
16049         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
16050                 if (tid == 0) {
16051                         sdtr_speed = asc_dvc->sdtr_speed1;
16052                 } else if (tid == 4) {
16053                         sdtr_speed = asc_dvc->sdtr_speed2;
16054                 } else if (tid == 8) {
16055                         sdtr_speed = asc_dvc->sdtr_speed3;
16056                 } else if (tid == 12) {
16057                         sdtr_speed = asc_dvc->sdtr_speed4;
16058                 }
16059                 if (sdtr_speed & ADV_MAX_TID) {
16060                         asc_dvc->sdtr_able |= (1 << tid);
16061                 }
16062                 sdtr_speed >>= 4;
16063         }
16064
16065         /*
16066          * Set the host maximum queuing (max. 253, min. 16) and the per device
16067          * maximum queuing (max. 63, min. 4).
16068          */
16069         if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
16070                 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16071         } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
16072                 /* If the value is zero, assume it is uninitialized. */
16073                 if (eep_config.max_host_qng == 0) {
16074                         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16075                 } else {
16076                         eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16077                 }
16078         }
16079
16080         if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
16081                 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16082         } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
16083                 /* If the value is zero, assume it is uninitialized. */
16084                 if (eep_config.max_dvc_qng == 0) {
16085                         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16086                 } else {
16087                         eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16088                 }
16089         }
16090
16091         /*
16092          * If 'max_dvc_qng' is greater than 'max_host_qng', then
16093          * set 'max_dvc_qng' to 'max_host_qng'.
16094          */
16095         if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
16096                 eep_config.max_dvc_qng = eep_config.max_host_qng;
16097         }
16098
16099         /*
16100          * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16101          * values based on possibly adjusted EEPROM values.
16102          */
16103         asc_dvc->max_host_qng = eep_config.max_host_qng;
16104         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16105
16106         /*
16107          * If the EEPROM 'termination' field is set to automatic (0), then set
16108          * the ADV_DVC_CFG 'termination' field to automatic also.
16109          *
16110          * If the termination is specified with a non-zero 'termination'
16111          * value check that a legal value is set and set the ADV_DVC_CFG
16112          * 'termination' field appropriately.
16113          */
16114         if (eep_config.termination_se == 0) {
16115                 termination = 0;        /* auto termination for SE */
16116         } else {
16117                 /* Enable manual control with low off / high off. */
16118                 if (eep_config.termination_se == 1) {
16119                         termination = 0;
16120
16121                         /* Enable manual control with low off / high on. */
16122                 } else if (eep_config.termination_se == 2) {
16123                         termination = TERM_SE_HI;
16124
16125                         /* Enable manual control with low on / high on. */
16126                 } else if (eep_config.termination_se == 3) {
16127                         termination = TERM_SE;
16128                 } else {
16129                         /*
16130                          * The EEPROM 'termination_se' field contains a bad value.
16131                          * Use automatic termination instead.
16132                          */
16133                         termination = 0;
16134                         warn_code |= ASC_WARN_EEPROM_TERMINATION;
16135                 }
16136         }
16137
16138         if (eep_config.termination_lvd == 0) {
16139                 asc_dvc->cfg->termination = termination;        /* auto termination for LVD */
16140         } else {
16141                 /* Enable manual control with low off / high off. */
16142                 if (eep_config.termination_lvd == 1) {
16143                         asc_dvc->cfg->termination = termination;
16144
16145                         /* Enable manual control with low off / high on. */
16146                 } else if (eep_config.termination_lvd == 2) {
16147                         asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16148
16149                         /* Enable manual control with low on / high on. */
16150                 } else if (eep_config.termination_lvd == 3) {
16151                         asc_dvc->cfg->termination = termination | TERM_LVD;
16152                 } else {
16153                         /*
16154                          * The EEPROM 'termination_lvd' field contains a bad value.
16155                          * Use automatic termination instead.
16156                          */
16157                         asc_dvc->cfg->termination = termination;
16158                         warn_code |= ASC_WARN_EEPROM_TERMINATION;
16159                 }
16160         }
16161
16162         return warn_code;
16163 }
16164
16165 /*
16166  * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
16167  * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
16168  * all of this is done.
16169  *
16170  * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
16171  *
16172  * For a non-fatal error return a warning code. If there are no warnings
16173  * then 0 is returned.
16174  *
16175  * Note: Chip is stopped on entry.
16176  */
16177 static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
16178 {
16179         AdvPortAddr iop_base;
16180         ushort warn_code;
16181         ADVEEP_38C1600_CONFIG eep_config;
16182         int i;
16183         uchar tid, termination;
16184         ushort sdtr_speed = 0;
16185
16186         iop_base = asc_dvc->iop_base;
16187
16188         warn_code = 0;
16189
16190         /*
16191          * Read the board's EEPROM configuration.
16192          *
16193          * Set default values if a bad checksum is found.
16194          */
16195         if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
16196             eep_config.check_sum) {
16197                 warn_code |= ASC_WARN_EEPROM_CHKSUM;
16198
16199                 /*
16200                  * Set EEPROM default values.
16201                  */
16202                 for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++) {
16203                         if (i == 1
16204                             && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) !=
16205                             0) {
16206                                 /*
16207                                  * Set Function 1 EEPROM Word 0 MSB
16208                                  *
16209                                  * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11)
16210                                  * EEPROM bits.
16211                                  *
16212                                  * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and
16213                                  * old Mac system booting problem. The Expansion ROM must
16214                                  * be disabled in Function 1 for these systems.
16215                                  *
16216                                  */
16217                                 *((uchar *)&eep_config + i) =
16218                                     ((*
16219                                       ((uchar *)&Default_38C1600_EEPROM_Config
16220                                        +
16221                                        i)) &
16222                                      (~
16223                                       (((ADV_EEPROM_BIOS_ENABLE |
16224                                          ADV_EEPROM_INTAB) >> 8) & 0xFF)));
16225
16226                                 /*
16227                                  * Set the INTAB (bit 11) if the GPIO 0 input indicates
16228                                  * the Function 1 interrupt line is wired to INTA.
16229                                  *
16230                                  * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
16231                                  *   1 - Function 1 interrupt line wired to INT A.
16232                                  *   0 - Function 1 interrupt line wired to INT B.
16233                                  *
16234                                  * Note: Adapter boards always have Function 0 wired to INTA.
16235                                  * Put all 5 GPIO bits in input mode and then read
16236                                  * their input values.
16237                                  */
16238                                 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL,
16239                                                      0);
16240                                 if (AdvReadByteRegister
16241                                     (iop_base, IOPB_GPIO_DATA) & 0x01) {
16242                                         /* Function 1 interrupt wired to INTA; Set EEPROM bit. */
16243                                         *((uchar *)&eep_config + i) |=
16244                                             ((ADV_EEPROM_INTAB >> 8) & 0xFF);
16245                                 }
16246                         } else {
16247                                 *((uchar *)&eep_config + i) =
16248                                     *((uchar *)&Default_38C1600_EEPROM_Config
16249                                       + i);
16250                         }
16251                 }
16252
16253                 /*
16254                  * Assume the 6 byte board serial number that was read
16255                  * from EEPROM is correct even if the EEPROM checksum
16256                  * failed.
16257                  */
16258                 eep_config.serial_number_word3 =
16259                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16260
16261                 eep_config.serial_number_word2 =
16262                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16263
16264                 eep_config.serial_number_word1 =
16265                     AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16266
16267                 AdvSet38C1600EEPConfig(iop_base, &eep_config);
16268         }
16269
16270         /*
16271          * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16272          * EEPROM configuration that was read.
16273          *
16274          * This is the mapping of EEPROM fields to Adv Library fields.
16275          */
16276         asc_dvc->wdtr_able = eep_config.wdtr_able;
16277         asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16278         asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16279         asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16280         asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16281         asc_dvc->ppr_able = 0;
16282         asc_dvc->tagqng_able = eep_config.tagqng_able;
16283         asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16284         asc_dvc->max_host_qng = eep_config.max_host_qng;
16285         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16286         asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
16287         asc_dvc->start_motor = eep_config.start_motor;
16288         asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16289         asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16290         asc_dvc->no_scam = eep_config.scam_tolerant;
16291
16292         /*
16293          * For every Target ID if any of its 'sdtr_speed[1234]' bits
16294          * are set, then set an 'sdtr_able' bit for it.
16295          */
16296         asc_dvc->sdtr_able = 0;
16297         for (tid = 0; tid <= ASC_MAX_TID; tid++) {
16298                 if (tid == 0) {
16299                         sdtr_speed = asc_dvc->sdtr_speed1;
16300                 } else if (tid == 4) {
16301                         sdtr_speed = asc_dvc->sdtr_speed2;
16302                 } else if (tid == 8) {
16303                         sdtr_speed = asc_dvc->sdtr_speed3;
16304                 } else if (tid == 12) {
16305                         sdtr_speed = asc_dvc->sdtr_speed4;
16306                 }
16307                 if (sdtr_speed & ASC_MAX_TID) {
16308                         asc_dvc->sdtr_able |= (1 << tid);
16309                 }
16310                 sdtr_speed >>= 4;
16311         }
16312
16313         /*
16314          * Set the host maximum queuing (max. 253, min. 16) and the per device
16315          * maximum queuing (max. 63, min. 4).
16316          */
16317         if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
16318                 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16319         } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
16320                 /* If the value is zero, assume it is uninitialized. */
16321                 if (eep_config.max_host_qng == 0) {
16322                         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16323                 } else {
16324                         eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16325                 }
16326         }
16327
16328         if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
16329                 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16330         } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
16331                 /* If the value is zero, assume it is uninitialized. */
16332                 if (eep_config.max_dvc_qng == 0) {
16333                         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16334                 } else {
16335                         eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16336                 }
16337         }
16338
16339         /*
16340          * If 'max_dvc_qng' is greater than 'max_host_qng', then
16341          * set 'max_dvc_qng' to 'max_host_qng'.
16342          */
16343         if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
16344                 eep_config.max_dvc_qng = eep_config.max_host_qng;
16345         }
16346
16347         /*
16348          * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
16349          * values based on possibly adjusted EEPROM values.
16350          */
16351         asc_dvc->max_host_qng = eep_config.max_host_qng;
16352         asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16353
16354         /*
16355          * If the EEPROM 'termination' field is set to automatic (0), then set
16356          * the ASC_DVC_CFG 'termination' field to automatic also.
16357          *
16358          * If the termination is specified with a non-zero 'termination'
16359          * value check that a legal value is set and set the ASC_DVC_CFG
16360          * 'termination' field appropriately.
16361          */
16362         if (eep_config.termination_se == 0) {
16363                 termination = 0;        /* auto termination for SE */
16364         } else {
16365                 /* Enable manual control with low off / high off. */
16366                 if (eep_config.termination_se == 1) {
16367                         termination = 0;
16368
16369                         /* Enable manual control with low off / high on. */
16370                 } else if (eep_config.termination_se == 2) {
16371                         termination = TERM_SE_HI;
16372
16373                         /* Enable manual control with low on / high on. */
16374                 } else if (eep_config.termination_se == 3) {
16375                         termination = TERM_SE;
16376                 } else {
16377                         /*
16378                          * The EEPROM 'termination_se' field contains a bad value.
16379                          * Use automatic termination instead.
16380                          */
16381                         termination = 0;
16382                         warn_code |= ASC_WARN_EEPROM_TERMINATION;
16383                 }
16384         }
16385
16386         if (eep_config.termination_lvd == 0) {
16387                 asc_dvc->cfg->termination = termination;        /* auto termination for LVD */
16388         } else {
16389                 /* Enable manual control with low off / high off. */
16390                 if (eep_config.termination_lvd == 1) {
16391                         asc_dvc->cfg->termination = termination;
16392
16393                         /* Enable manual control with low off / high on. */
16394                 } else if (eep_config.termination_lvd == 2) {
16395                         asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16396
16397                         /* Enable manual control with low on / high on. */
16398                 } else if (eep_config.termination_lvd == 3) {
16399                         asc_dvc->cfg->termination = termination | TERM_LVD;
16400                 } else {
16401                         /*
16402                          * The EEPROM 'termination_lvd' field contains a bad value.
16403                          * Use automatic termination instead.
16404                          */
16405                         asc_dvc->cfg->termination = termination;
16406                         warn_code |= ASC_WARN_EEPROM_TERMINATION;
16407                 }
16408         }
16409
16410         return warn_code;
16411 }
16412
16413 /*
16414  * Read EEPROM configuration into the specified buffer.
16415  *
16416  * Return a checksum based on the EEPROM configuration read.
16417  */
16418 static ushort __devinit
16419 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16420 {
16421         ushort wval, chksum;
16422         ushort *wbuf;
16423         int eep_addr;
16424         ushort *charfields;
16425
16426         charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16427         wbuf = (ushort *)cfg_buf;
16428         chksum = 0;
16429
16430         for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16431              eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16432                 wval = AdvReadEEPWord(iop_base, eep_addr);
16433                 chksum += wval; /* Checksum is calculated from word values. */
16434                 if (*charfields++) {
16435                         *wbuf = le16_to_cpu(wval);
16436                 } else {
16437                         *wbuf = wval;
16438                 }
16439         }
16440         /* Read checksum word. */
16441         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16442         wbuf++;
16443         charfields++;
16444
16445         /* Read rest of EEPROM not covered by the checksum. */
16446         for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16447              eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16448                 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16449                 if (*charfields++) {
16450                         *wbuf = le16_to_cpu(*wbuf);
16451                 }
16452         }
16453         return chksum;
16454 }
16455
16456 /*
16457  * Read EEPROM configuration into the specified buffer.
16458  *
16459  * Return a checksum based on the EEPROM configuration read.
16460  */
16461 static ushort __devinit
16462 AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
16463 {
16464         ushort wval, chksum;
16465         ushort *wbuf;
16466         int eep_addr;
16467         ushort *charfields;
16468
16469         charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16470         wbuf = (ushort *)cfg_buf;
16471         chksum = 0;
16472
16473         for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16474              eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16475                 wval = AdvReadEEPWord(iop_base, eep_addr);
16476                 chksum += wval; /* Checksum is calculated from word values. */
16477                 if (*charfields++) {
16478                         *wbuf = le16_to_cpu(wval);
16479                 } else {
16480                         *wbuf = wval;
16481                 }
16482         }
16483         /* Read checksum word. */
16484         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16485         wbuf++;
16486         charfields++;
16487
16488         /* Read rest of EEPROM not covered by the checksum. */
16489         for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16490              eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16491                 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16492                 if (*charfields++) {
16493                         *wbuf = le16_to_cpu(*wbuf);
16494                 }
16495         }
16496         return chksum;
16497 }
16498
16499 /*
16500  * Read EEPROM configuration into the specified buffer.
16501  *
16502  * Return a checksum based on the EEPROM configuration read.
16503  */
16504 static ushort __devinit
16505 AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
16506 {
16507         ushort wval, chksum;
16508         ushort *wbuf;
16509         int eep_addr;
16510         ushort *charfields;
16511
16512         charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16513         wbuf = (ushort *)cfg_buf;
16514         chksum = 0;
16515
16516         for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16517              eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16518                 wval = AdvReadEEPWord(iop_base, eep_addr);
16519                 chksum += wval; /* Checksum is calculated from word values. */
16520                 if (*charfields++) {
16521                         *wbuf = le16_to_cpu(wval);
16522                 } else {
16523                         *wbuf = wval;
16524                 }
16525         }
16526         /* Read checksum word. */
16527         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16528         wbuf++;
16529         charfields++;
16530
16531         /* Read rest of EEPROM not covered by the checksum. */
16532         for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16533              eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16534                 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16535                 if (*charfields++) {
16536                         *wbuf = le16_to_cpu(*wbuf);
16537                 }
16538         }
16539         return chksum;
16540 }
16541
16542 /*
16543  * Read the EEPROM from specified location
16544  */
16545 static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
16546 {
16547         AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16548                              ASC_EEP_CMD_READ | eep_word_addr);
16549         AdvWaitEEPCmd(iop_base);
16550         return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
16551 }
16552
16553 /*
16554  * Wait for EEPROM command to complete
16555  */
16556 static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
16557 {
16558         int eep_delay_ms;
16559
16560         for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
16561                 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
16562                     ASC_EEP_CMD_DONE) {
16563                         break;
16564                 }
16565                 DvcSleepMilliSecond(1);
16566         }
16567         if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
16568             0) {
16569                 ASC_ASSERT(0);
16570         }
16571         return;
16572 }
16573
16574 /*
16575  * Write the EEPROM from 'cfg_buf'.
16576  */
16577 void __devinit
16578 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16579 {
16580         ushort *wbuf;
16581         ushort addr, chksum;
16582         ushort *charfields;
16583
16584         wbuf = (ushort *)cfg_buf;
16585         charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16586         chksum = 0;
16587
16588         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16589         AdvWaitEEPCmd(iop_base);
16590
16591         /*
16592          * Write EEPROM from word 0 to word 20.
16593          */
16594         for (addr = ADV_EEP_DVC_CFG_BEGIN;
16595              addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16596                 ushort word;
16597
16598                 if (*charfields++) {
16599                         word = cpu_to_le16(*wbuf);
16600                 } else {
16601                         word = *wbuf;
16602                 }
16603                 chksum += *wbuf;        /* Checksum is calculated from word values. */
16604                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16605                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16606                                      ASC_EEP_CMD_WRITE | addr);
16607                 AdvWaitEEPCmd(iop_base);
16608                 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16609         }
16610
16611         /*
16612          * Write EEPROM checksum at word 21.
16613          */
16614         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16615         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16616         AdvWaitEEPCmd(iop_base);
16617         wbuf++;
16618         charfields++;
16619
16620         /*
16621          * Write EEPROM OEM name at words 22 to 29.
16622          */
16623         for (addr = ADV_EEP_DVC_CTL_BEGIN;
16624              addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16625                 ushort word;
16626
16627                 if (*charfields++) {
16628                         word = cpu_to_le16(*wbuf);
16629                 } else {
16630                         word = *wbuf;
16631                 }
16632                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16633                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16634                                      ASC_EEP_CMD_WRITE | addr);
16635                 AdvWaitEEPCmd(iop_base);
16636         }
16637         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16638         AdvWaitEEPCmd(iop_base);
16639         return;
16640 }
16641
16642 /*
16643  * Write the EEPROM from 'cfg_buf'.
16644  */
16645 void __devinit
16646 AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
16647 {
16648         ushort *wbuf;
16649         ushort *charfields;
16650         ushort addr, chksum;
16651
16652         wbuf = (ushort *)cfg_buf;
16653         charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16654         chksum = 0;
16655
16656         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16657         AdvWaitEEPCmd(iop_base);
16658
16659         /*
16660          * Write EEPROM from word 0 to word 20.
16661          */
16662         for (addr = ADV_EEP_DVC_CFG_BEGIN;
16663              addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16664                 ushort word;
16665
16666                 if (*charfields++) {
16667                         word = cpu_to_le16(*wbuf);
16668                 } else {
16669                         word = *wbuf;
16670                 }
16671                 chksum += *wbuf;        /* Checksum is calculated from word values. */
16672                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16673                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16674                                      ASC_EEP_CMD_WRITE | addr);
16675                 AdvWaitEEPCmd(iop_base);
16676                 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16677         }
16678
16679         /*
16680          * Write EEPROM checksum at word 21.
16681          */
16682         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16683         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16684         AdvWaitEEPCmd(iop_base);
16685         wbuf++;
16686         charfields++;
16687
16688         /*
16689          * Write EEPROM OEM name at words 22 to 29.
16690          */
16691         for (addr = ADV_EEP_DVC_CTL_BEGIN;
16692              addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16693                 ushort word;
16694
16695                 if (*charfields++) {
16696                         word = cpu_to_le16(*wbuf);
16697                 } else {
16698                         word = *wbuf;
16699                 }
16700                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16701                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16702                                      ASC_EEP_CMD_WRITE | addr);
16703                 AdvWaitEEPCmd(iop_base);
16704         }
16705         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16706         AdvWaitEEPCmd(iop_base);
16707         return;
16708 }
16709
16710 /*
16711  * Write the EEPROM from 'cfg_buf'.
16712  */
16713 void __devinit
16714 AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
16715 {
16716         ushort *wbuf;
16717         ushort *charfields;
16718         ushort addr, chksum;
16719
16720         wbuf = (ushort *)cfg_buf;
16721         charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16722         chksum = 0;
16723
16724         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16725         AdvWaitEEPCmd(iop_base);
16726
16727         /*
16728          * Write EEPROM from word 0 to word 20.
16729          */
16730         for (addr = ADV_EEP_DVC_CFG_BEGIN;
16731              addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16732                 ushort word;
16733
16734                 if (*charfields++) {
16735                         word = cpu_to_le16(*wbuf);
16736                 } else {
16737                         word = *wbuf;
16738                 }
16739                 chksum += *wbuf;        /* Checksum is calculated from word values. */
16740                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16741                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16742                                      ASC_EEP_CMD_WRITE | addr);
16743                 AdvWaitEEPCmd(iop_base);
16744                 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16745         }
16746
16747         /*
16748          * Write EEPROM checksum at word 21.
16749          */
16750         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16751         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16752         AdvWaitEEPCmd(iop_base);
16753         wbuf++;
16754         charfields++;
16755
16756         /*
16757          * Write EEPROM OEM name at words 22 to 29.
16758          */
16759         for (addr = ADV_EEP_DVC_CTL_BEGIN;
16760              addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16761                 ushort word;
16762
16763                 if (*charfields++) {
16764                         word = cpu_to_le16(*wbuf);
16765                 } else {
16766                         word = *wbuf;
16767                 }
16768                 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16769                 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16770                                      ASC_EEP_CMD_WRITE | addr);
16771                 AdvWaitEEPCmd(iop_base);
16772         }
16773         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16774         AdvWaitEEPCmd(iop_base);
16775         return;
16776 }
16777
16778 /* a_advlib.c */
16779 /*
16780  * AdvExeScsiQueue() - Send a request to the RISC microcode program.
16781  *
16782  *   Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
16783  *   add the carrier to the ICQ (Initiator Command Queue), and tickle the
16784  *   RISC to notify it a new command is ready to be executed.
16785  *
16786  * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
16787  * set to SCSI_MAX_RETRY.
16788  *
16789  * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
16790  * for DMA addresses or math operations are byte swapped to little-endian
16791  * order.
16792  *
16793  * Return:
16794  *      ADV_SUCCESS(1) - The request was successfully queued.
16795  *      ADV_BUSY(0) -    Resource unavailable; Retry again after pending
16796  *                       request completes.
16797  *      ADV_ERROR(-1) -  Invalid ADV_SCSI_REQ_Q request structure
16798  *                       host IC error.
16799  */
16800 static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
16801 {
16802         ulong last_int_level;
16803         AdvPortAddr iop_base;
16804         ADV_DCNT req_size;
16805         ADV_PADDR req_paddr;
16806         ADV_CARR_T *new_carrp;
16807
16808         ASC_ASSERT(scsiq != NULL);      /* 'scsiq' should never be NULL. */
16809
16810         /*
16811          * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
16812          */
16813         if (scsiq->target_id > ADV_MAX_TID) {
16814                 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
16815                 scsiq->done_status = QD_WITH_ERROR;
16816                 return ADV_ERROR;
16817         }
16818
16819         iop_base = asc_dvc->iop_base;
16820
16821         last_int_level = DvcEnterCritical();
16822
16823         /*
16824          * Allocate a carrier ensuring at least one carrier always
16825          * remains on the freelist and initialize fields.
16826          */
16827         if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
16828                 DvcLeaveCritical(last_int_level);
16829                 return ADV_BUSY;
16830         }
16831         asc_dvc->carr_freelist = (ADV_CARR_T *)
16832             ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
16833         asc_dvc->carr_pending_cnt++;
16834
16835         /*
16836          * Set the carrier to be a stopper by setting 'next_vpa'
16837          * to the stopper value. The current stopper will be changed
16838          * below to point to the new stopper.
16839          */
16840         new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16841
16842         /*
16843          * Clear the ADV_SCSI_REQ_Q done flag.
16844          */
16845         scsiq->a_flag &= ~ADV_SCSIQ_DONE;
16846
16847         req_size = sizeof(ADV_SCSI_REQ_Q);
16848         req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
16849                                   (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
16850
16851         ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
16852         ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
16853
16854         /* Wait for assertion before making little-endian */
16855         req_paddr = cpu_to_le32(req_paddr);
16856
16857         /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
16858         scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
16859         scsiq->scsiq_rptr = req_paddr;
16860
16861         scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
16862         /*
16863          * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
16864          * order during initialization.
16865          */
16866         scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
16867
16868         /*
16869          * Use the current stopper to send the ADV_SCSI_REQ_Q command to
16870          * the microcode. The newly allocated stopper will become the new
16871          * stopper.
16872          */
16873         asc_dvc->icq_sp->areq_vpa = req_paddr;
16874
16875         /*
16876          * Set the 'next_vpa' pointer for the old stopper to be the
16877          * physical address of the new stopper. The RISC can only
16878          * follow physical addresses.
16879          */
16880         asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
16881
16882         /*
16883          * Set the host adapter stopper pointer to point to the new carrier.
16884          */
16885         asc_dvc->icq_sp = new_carrp;
16886
16887         if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
16888             asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
16889                 /*
16890                  * Tickle the RISC to tell it to read its Command Queue Head pointer.
16891                  */
16892                 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
16893                 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
16894                         /*
16895                          * Clear the tickle value. In the ASC-3550 the RISC flag
16896                          * command 'clr_tickle_a' does not work unless the host
16897                          * value is cleared.
16898                          */
16899                         AdvWriteByteRegister(iop_base, IOPB_TICKLE,
16900                                              ADV_TICKLE_NOP);
16901                 }
16902         } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16903                 /*
16904                  * Notify the RISC a carrier is ready by writing the physical
16905                  * address of the new carrier stopper to the COMMA register.
16906                  */
16907                 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
16908                                       le32_to_cpu(new_carrp->carr_pa));
16909         }
16910
16911         DvcLeaveCritical(last_int_level);
16912
16913         return ADV_SUCCESS;
16914 }
16915
16916 /*
16917  * Reset SCSI Bus and purge all outstanding requests.
16918  *
16919  * Return Value:
16920  *      ADV_TRUE(1) -   All requests are purged and SCSI Bus is reset.
16921  *      ADV_FALSE(0) -  Microcode command failed.
16922  *      ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
16923  *                      may be hung which requires driver recovery.
16924  */
16925 static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
16926 {
16927         int status;
16928
16929         /*
16930          * Send the SCSI Bus Reset idle start idle command which asserts
16931          * the SCSI Bus Reset signal.
16932          */
16933         status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
16934         if (status != ADV_TRUE) {
16935                 return status;
16936         }
16937
16938         /*
16939          * Delay for the specified SCSI Bus Reset hold time.
16940          *
16941          * The hold time delay is done on the host because the RISC has no
16942          * microsecond accurate timer.
16943          */
16944         DvcDelayMicroSecond(asc_dvc, (ushort)ASC_SCSI_RESET_HOLD_TIME_US);
16945
16946         /*
16947          * Send the SCSI Bus Reset end idle command which de-asserts
16948          * the SCSI Bus Reset signal and purges any pending requests.
16949          */
16950         status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
16951         if (status != ADV_TRUE) {
16952                 return status;
16953         }
16954
16955         DvcSleepMilliSecond((ADV_DCNT)asc_dvc->scsi_reset_wait * 1000);
16956
16957         return status;
16958 }
16959
16960 /*
16961  * Reset chip and SCSI Bus.
16962  *
16963  * Return Value:
16964  *      ADV_TRUE(1) -   Chip re-initialization and SCSI Bus Reset successful.
16965  *      ADV_FALSE(0) -  Chip re-initialization and SCSI Bus Reset failure.
16966  */
16967 static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
16968 {
16969         int status;
16970         ushort wdtr_able, sdtr_able, tagqng_able;
16971         ushort ppr_able = 0;
16972         uchar tid, max_cmd[ADV_MAX_TID + 1];
16973         AdvPortAddr iop_base;
16974         ushort bios_sig;
16975
16976         iop_base = asc_dvc->iop_base;
16977
16978         /*
16979          * Save current per TID negotiated values.
16980          */
16981         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16982         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16983         if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16984                 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16985         }
16986         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16987         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
16988                 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16989                                 max_cmd[tid]);
16990         }
16991
16992         /*
16993          * Force the AdvInitAsc3550/38C0800Driver() function to
16994          * perform a SCSI Bus Reset by clearing the BIOS signature word.
16995          * The initialization functions assumes a SCSI Bus Reset is not
16996          * needed if the BIOS signature word is present.
16997          */
16998         AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
16999         AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
17000
17001         /*
17002          * Stop chip and reset it.
17003          */
17004         AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
17005         AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
17006         DvcSleepMilliSecond(100);
17007         AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
17008                              ADV_CTRL_REG_CMD_WR_IO_REG);
17009
17010         /*
17011          * Reset Adv Library error code, if any, and try
17012          * re-initializing the chip.
17013          */
17014         asc_dvc->err_code = 0;
17015         if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17016                 status = AdvInitAsc38C1600Driver(asc_dvc);
17017         } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
17018                 status = AdvInitAsc38C0800Driver(asc_dvc);
17019         } else {
17020                 status = AdvInitAsc3550Driver(asc_dvc);
17021         }
17022
17023         /* Translate initialization return value to status value. */
17024         if (status == 0) {
17025                 status = ADV_TRUE;
17026         } else {
17027                 status = ADV_FALSE;
17028         }
17029
17030         /*
17031          * Restore the BIOS signature word.
17032          */
17033         AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17034
17035         /*
17036          * Restore per TID negotiated values.
17037          */
17038         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17039         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17040         if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17041                 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17042         }
17043         AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17044         for (tid = 0; tid <= ADV_MAX_TID; tid++) {
17045                 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17046                                  max_cmd[tid]);
17047         }
17048
17049         return status;
17050 }
17051
17052 /*
17053  * Adv Library Interrupt Service Routine
17054  *
17055  *  This function is called by a driver's interrupt service routine.
17056  *  The function disables and re-enables interrupts.
17057  *
17058  *  When a microcode idle command is completed, the ADV_DVC_VAR
17059  *  'idle_cmd_done' field is set to ADV_TRUE.
17060  *
17061  *  Note: AdvISR() can be called when interrupts are disabled or even
17062  *  when there is no hardware interrupt condition present. It will
17063  *  always check for completed idle commands and microcode requests.
17064  *  This is an important feature that shouldn't be changed because it
17065  *  allows commands to be completed from polling mode loops.
17066  *
17067  * Return:
17068  *   ADV_TRUE(1) - interrupt was pending
17069  *   ADV_FALSE(0) - no interrupt was pending
17070  */
17071 static int AdvISR(ADV_DVC_VAR *asc_dvc)
17072 {
17073         AdvPortAddr iop_base;
17074         uchar int_stat;
17075         ushort target_bit;
17076         ADV_CARR_T *free_carrp;
17077         ADV_VADDR irq_next_vpa;
17078         int flags;
17079         ADV_SCSI_REQ_Q *scsiq;
17080
17081         flags = DvcEnterCritical();
17082
17083         iop_base = asc_dvc->iop_base;
17084
17085         /* Reading the register clears the interrupt. */
17086         int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
17087
17088         if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
17089                          ADV_INTR_STATUS_INTRC)) == 0) {
17090                 DvcLeaveCritical(flags);
17091                 return ADV_FALSE;
17092         }
17093
17094         /*
17095          * Notify the driver of an asynchronous microcode condition by
17096          * calling the ADV_DVC_VAR.async_callback function. The function
17097          * is passed the microcode ASC_MC_INTRB_CODE byte value.
17098          */
17099         if (int_stat & ADV_INTR_STATUS_INTRB) {
17100                 uchar intrb_code;
17101
17102                 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
17103
17104                 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17105                     asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
17106                         if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
17107                             asc_dvc->carr_pending_cnt != 0) {
17108                                 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
17109                                                      ADV_TICKLE_A);
17110                                 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
17111                                         AdvWriteByteRegister(iop_base,
17112                                                              IOPB_TICKLE,
17113                                                              ADV_TICKLE_NOP);
17114                                 }
17115                         }
17116                 }
17117
17118                 if (asc_dvc->async_callback != 0) {
17119                         (*asc_dvc->async_callback) (asc_dvc, intrb_code);
17120                 }
17121         }
17122
17123         /*
17124          * Check if the IRQ stopper carrier contains a completed request.
17125          */
17126         while (((irq_next_vpa =
17127                  le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
17128                 /*
17129                  * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
17130                  * The RISC will have set 'areq_vpa' to a virtual address.
17131                  *
17132                  * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
17133                  * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
17134                  * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
17135                  * in AdvExeScsiQueue().
17136                  */
17137                 scsiq = (ADV_SCSI_REQ_Q *)
17138                     ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
17139
17140                 /*
17141                  * Request finished with good status and the queue was not
17142                  * DMAed to host memory by the firmware. Set all status fields
17143                  * to indicate good status.
17144                  */
17145                 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
17146                         scsiq->done_status = QD_NO_ERROR;
17147                         scsiq->host_status = scsiq->scsi_status = 0;
17148                         scsiq->data_cnt = 0L;
17149                 }
17150
17151                 /*
17152                  * Advance the stopper pointer to the next carrier
17153                  * ignoring the lower four bits. Free the previous
17154                  * stopper carrier.
17155                  */
17156                 free_carrp = asc_dvc->irq_sp;
17157                 asc_dvc->irq_sp = (ADV_CARR_T *)
17158                     ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
17159
17160                 free_carrp->next_vpa =
17161                     cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
17162                 asc_dvc->carr_freelist = free_carrp;
17163                 asc_dvc->carr_pending_cnt--;
17164
17165                 ASC_ASSERT(scsiq != NULL);
17166                 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
17167
17168                 /*
17169                  * Clear request microcode control flag.
17170                  */
17171                 scsiq->cntl = 0;
17172
17173                 /*
17174                  * If the command that completed was a SCSI INQUIRY and
17175                  * LUN 0 was sent the command, then process the INQUIRY
17176                  * command information for the device.
17177                  *
17178                  * Note: If data returned were either VPD or CmdDt data,
17179                  * don't process the INQUIRY command information for
17180                  * the device, otherwise may erroneously set *_able bits.
17181                  */
17182                 if (scsiq->done_status == QD_NO_ERROR &&
17183                     scsiq->cdb[0] == INQUIRY &&
17184                     scsiq->target_lun == 0 &&
17185                     (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
17186                     == ADV_INQ_RTN_STD_INQUIRY_DATA) {
17187                         AdvInquiryHandling(asc_dvc, scsiq);
17188                 }
17189
17190                 /*
17191                  * Notify the driver of the completed request by passing
17192                  * the ADV_SCSI_REQ_Q pointer to its callback function.
17193                  */
17194                 scsiq->a_flag |= ADV_SCSIQ_DONE;
17195                 (*asc_dvc->isr_callback) (asc_dvc, scsiq);
17196                 /*
17197                  * Note: After the driver callback function is called, 'scsiq'
17198                  * can no longer be referenced.
17199                  *
17200                  * Fall through and continue processing other completed
17201                  * requests...
17202                  */
17203
17204                 /*
17205                  * Disable interrupts again in case the driver inadvertently
17206                  * enabled interrupts in its callback function.
17207                  *
17208                  * The DvcEnterCritical() return value is ignored, because
17209                  * the 'flags' saved when AdvISR() was first entered will be
17210                  * used to restore the interrupt flag on exit.
17211                  */
17212                 (void)DvcEnterCritical();
17213         }
17214         DvcLeaveCritical(flags);
17215         return ADV_TRUE;
17216 }
17217
17218 /*
17219  * Send an idle command to the chip and wait for completion.
17220  *
17221  * Command completion is polled for once per microsecond.
17222  *
17223  * The function can be called from anywhere including an interrupt handler.
17224  * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
17225  * functions to prevent reentrancy.
17226  *
17227  * Return Values:
17228  *   ADV_TRUE - command completed successfully
17229  *   ADV_FALSE - command failed
17230  *   ADV_ERROR - command timed out
17231  */
17232 static int
17233 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
17234                ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
17235 {
17236         ulong last_int_level;
17237         int result;
17238         ADV_DCNT i, j;
17239         AdvPortAddr iop_base;
17240
17241         last_int_level = DvcEnterCritical();
17242
17243         iop_base = asc_dvc->iop_base;
17244
17245         /*
17246          * Clear the idle command status which is set by the microcode
17247          * to a non-zero value to indicate when the command is completed.
17248          * The non-zero result is one of the IDLE_CMD_STATUS_* values
17249          * defined in a_advlib.h.
17250          */
17251         AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
17252
17253         /*
17254          * Write the idle command value after the idle command parameter
17255          * has been written to avoid a race condition. If the order is not
17256          * followed, the microcode may process the idle command before the
17257          * parameters have been written to LRAM.
17258          */
17259         AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
17260                                 cpu_to_le32(idle_cmd_parameter));
17261         AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
17262
17263         /*
17264          * Tickle the RISC to tell it to process the idle command.
17265          */
17266         AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
17267         if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
17268                 /*
17269                  * Clear the tickle value. In the ASC-3550 the RISC flag
17270                  * command 'clr_tickle_b' does not work unless the host
17271                  * value is cleared.
17272                  */
17273                 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17274         }
17275
17276         /* Wait for up to 100 millisecond for the idle command to timeout. */
17277         for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
17278                 /* Poll once each microsecond for command completion. */
17279                 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
17280                         AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
17281                                         result);
17282                         if (result != 0) {
17283                                 DvcLeaveCritical(last_int_level);
17284                                 return result;
17285                         }
17286                         DvcDelayMicroSecond(asc_dvc, (ushort)1);
17287                 }
17288         }
17289
17290         ASC_ASSERT(0);          /* The idle command should never timeout. */
17291         DvcLeaveCritical(last_int_level);
17292         return ADV_ERROR;
17293 }
17294
17295 /*
17296  * Inquiry Information Byte 7 Handling
17297  *
17298  * Handle SCSI Inquiry Command information for a device by setting
17299  * microcode operating variables that affect WDTR, SDTR, and Tag
17300  * Queuing.
17301  */
17302 static void AdvInquiryHandling(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
17303 {
17304         AdvPortAddr iop_base;
17305         uchar tid;
17306         ADV_SCSI_INQUIRY *inq;
17307         ushort tidmask;
17308         ushort cfg_word;
17309
17310         /*
17311          * AdvInquiryHandling() requires up to INQUIRY information Byte 7
17312          * to be available.
17313          *
17314          * If less than 8 bytes of INQUIRY information were requested or less
17315          * than 8 bytes were transferred, then return. cdb[4] is the request
17316          * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
17317          * microcode to the transfer residual count.
17318          */
17319
17320         if (scsiq->cdb[4] < 8 ||
17321             (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8) {
17322                 return;
17323         }
17324
17325         iop_base = asc_dvc->iop_base;
17326         tid = scsiq->target_id;
17327
17328         inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr;
17329
17330         /*
17331          * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
17332          */
17333         if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2) {
17334                 return;
17335         } else {
17336                 /*
17337                  * INQUIRY Byte 7 Handling
17338                  *
17339                  * Use a device's INQUIRY byte 7 to determine whether it
17340                  * supports WDTR, SDTR, and Tag Queuing. If the feature
17341                  * is enabled in the EEPROM and the device supports the
17342                  * feature, then enable it in the microcode.
17343                  */
17344
17345                 tidmask = ADV_TID_TO_TIDMASK(tid);
17346
17347                 /*
17348                  * Wide Transfers
17349                  *
17350                  * If the EEPROM enabled WDTR for the device and the device
17351                  * supports wide bus (16 bit) transfers, then turn on the
17352                  * device's 'wdtr_able' bit and write the new value to the
17353                  * microcode.
17354                  */
17355                 if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq)) {
17356                         AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
17357                         if ((cfg_word & tidmask) == 0) {
17358                                 cfg_word |= tidmask;
17359                                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
17360                                                  cfg_word);
17361
17362                                 /*
17363                                  * Clear the microcode "SDTR negotiation" and "WDTR
17364                                  * negotiation" done indicators for the target to cause
17365                                  * it to negotiate with the new setting set above.
17366                                  * WDTR when accepted causes the target to enter
17367                                  * asynchronous mode, so SDTR must be negotiated.
17368                                  */
17369                                 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE,
17370                                                 cfg_word);
17371                                 cfg_word &= ~tidmask;
17372                                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE,
17373                                                  cfg_word);
17374                                 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE,
17375                                                 cfg_word);
17376                                 cfg_word &= ~tidmask;
17377                                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE,
17378                                                  cfg_word);
17379                         }
17380                 }
17381
17382                 /*
17383                  * Synchronous Transfers
17384                  *
17385                  * If the EEPROM enabled SDTR for the device and the device
17386                  * supports synchronous transfers, then turn on the device's
17387                  * 'sdtr_able' bit. Write the new value to the microcode.
17388                  */
17389                 if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq)) {
17390                         AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
17391                         if ((cfg_word & tidmask) == 0) {
17392                                 cfg_word |= tidmask;
17393                                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
17394                                                  cfg_word);
17395
17396                                 /*
17397                                  * Clear the microcode "SDTR negotiation" done indicator
17398                                  * for the target to cause it to negotiate with the new
17399                                  * setting set above.
17400                                  */
17401                                 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE,
17402                                                 cfg_word);
17403                                 cfg_word &= ~tidmask;
17404                                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE,
17405                                                  cfg_word);
17406                         }
17407                 }
17408                 /*
17409                  * If the Inquiry data included enough space for the SPI-3
17410                  * Clocking field, then check if DT mode is supported.
17411                  */
17412                 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 &&
17413                     (scsiq->cdb[4] >= 57 ||
17414                      (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57)) {
17415                         /*
17416                          * PPR (Parallel Protocol Request) Capable
17417                          *
17418                          * If the device supports DT mode, then it must be PPR capable.
17419                          * The PPR message will be used in place of the SDTR and WDTR
17420                          * messages to negotiate synchronous speed and offset, transfer
17421                          * width, and protocol options.
17422                          */
17423                         if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY) {
17424                                 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE,
17425                                                 asc_dvc->ppr_able);
17426                                 asc_dvc->ppr_able |= tidmask;
17427                                 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE,
17428                                                  asc_dvc->ppr_able);
17429                         }
17430                 }
17431
17432                 /*
17433                  * If the EEPROM enabled Tag Queuing for the device and the
17434                  * device supports Tag Queueing, then turn on the device's
17435                  * 'tagqng_enable' bit in the microcode and set the microcode
17436                  * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
17437                  * value.
17438                  *
17439                  * Tag Queuing is disabled for the BIOS which runs in polled
17440                  * mode and would see no benefit from Tag Queuing. Also by
17441                  * disabling Tag Queuing in the BIOS devices with Tag Queuing
17442                  * bugs will at least work with the BIOS.
17443                  */
17444                 if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq)) {
17445                         AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
17446                         cfg_word |= tidmask;
17447                         AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
17448                                          cfg_word);
17449
17450                         AdvWriteByteLram(iop_base,
17451                                          ASC_MC_NUMBER_OF_MAX_CMD + tid,
17452                                          asc_dvc->max_dvc_qng);
17453                 }
17454         }
17455 }
17456
17457 static int __devinit
17458 advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
17459 {
17460         int req_cnt = 0;
17461         adv_req_t *reqp = NULL;
17462         int sg_cnt = 0;
17463         adv_sgblk_t *sgp;
17464         int warn_code, err_code;
17465
17466         /*
17467          * Allocate buffer carrier structures. The total size
17468          * is about 4 KB, so allocate all at once.
17469          */
17470         boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
17471         ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp);
17472
17473         if (!boardp->carrp)
17474                 goto kmalloc_failed;
17475
17476         /*
17477          * Allocate up to 'max_host_qng' request structures for the Wide
17478          * board. The total size is about 16 KB, so allocate all at once.
17479          * If the allocation fails decrement and try again.
17480          */
17481         for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
17482                 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
17483
17484                 ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, "
17485                          "bytes %lu\n", reqp, req_cnt,
17486                          (ulong)sizeof(adv_req_t) * req_cnt);
17487
17488                 if (reqp)
17489                         break;
17490         }
17491
17492         if (!reqp)
17493                 goto kmalloc_failed;
17494
17495         boardp->orig_reqp = reqp;
17496
17497         /*
17498          * Allocate up to ADV_TOT_SG_BLOCK request structures for
17499          * the Wide board. Each structure is about 136 bytes.
17500          */
17501         boardp->adv_sgblkp = NULL;
17502         for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
17503                 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
17504
17505                 if (!sgp)
17506                         break;
17507
17508                 sgp->next_sgblkp = boardp->adv_sgblkp;
17509                 boardp->adv_sgblkp = sgp;
17510
17511         }
17512
17513         ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n",
17514                  sg_cnt, sizeof(adv_sgblk_t),
17515                  (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
17516
17517         if (!boardp->adv_sgblkp)
17518                 goto kmalloc_failed;
17519
17520         adv_dvc_varp->carrier_buf = boardp->carrp;
17521
17522         /*
17523          * Point 'adv_reqp' to the request structures and
17524          * link them together.
17525          */
17526         req_cnt--;
17527         reqp[req_cnt].next_reqp = NULL;
17528         for (; req_cnt > 0; req_cnt--) {
17529                 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
17530         }
17531         boardp->adv_reqp = &reqp[0];
17532
17533         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17534                 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n");
17535                 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
17536         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17537                 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()"
17538                            "\n");
17539                 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
17540         } else {
17541                 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()"
17542                            "\n");
17543                 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
17544         }
17545         err_code = adv_dvc_varp->err_code;
17546
17547         if (warn_code || err_code) {
17548                 ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
17549                            " error 0x%x\n", boardp->id, warn_code, err_code);
17550         }
17551
17552         goto exit;
17553
17554  kmalloc_failed:
17555         ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
17556                    "failed\n", boardp->id);
17557         err_code = ADV_ERROR;
17558  exit:
17559         return err_code;
17560 }
17561
17562 static void advansys_wide_free_mem(asc_board_t *boardp)
17563 {
17564         kfree(boardp->carrp);
17565         boardp->carrp = NULL;
17566         kfree(boardp->orig_reqp);
17567         boardp->orig_reqp = boardp->adv_reqp = NULL;
17568         while (boardp->adv_sgblkp) {
17569                 adv_sgblk_t *sgp = boardp->adv_sgblkp;
17570                 boardp->adv_sgblkp = sgp->next_sgblkp;
17571                 kfree(sgp);
17572         }
17573 }
17574
17575 static struct Scsi_Host *__devinit
17576 advansys_board_found(int iop, struct device *dev, int bus_type)
17577 {
17578         struct Scsi_Host *shost;
17579         struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL;
17580         asc_board_t *boardp;
17581         ASC_DVC_VAR *asc_dvc_varp = NULL;
17582         ADV_DVC_VAR *adv_dvc_varp = NULL;
17583         int share_irq;
17584         int iolen = 0;
17585         ADV_PADDR pci_memory_address;
17586         int warn_code, err_code;
17587         int ret;
17588
17589         /*
17590          * Adapter found.
17591          *
17592          * Register the adapter, get its configuration, and
17593          * initialize it.
17594          */
17595         ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n");
17596         shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t));
17597
17598         if (!shost)
17599                 return NULL;
17600
17601         /* Initialize private per board data */
17602         boardp = ASC_BOARDP(shost);
17603         memset(boardp, 0, sizeof(asc_board_t));
17604         boardp->id = asc_board_count++;
17605
17606         /* Initialize spinlock. */
17607         spin_lock_init(&boardp->lock);
17608
17609         /*
17610          * Handle both narrow and wide boards.
17611          *
17612          * If a Wide board was detected, set the board structure
17613          * wide board flag. Set-up the board structure based on
17614          * the board type.
17615          */
17616 #ifdef CONFIG_PCI
17617         if (bus_type == ASC_IS_PCI &&
17618             (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
17619              pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
17620              pdev->device == PCI_DEVICE_ID_38C1600_REV1)) {
17621                 boardp->flags |= ASC_IS_WIDE_BOARD;
17622         }
17623 #endif /* CONFIG_PCI */
17624
17625         if (ASC_NARROW_BOARD(boardp)) {
17626                 ASC_DBG(1, "advansys_board_found: narrow board\n");
17627                 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
17628                 asc_dvc_varp->bus_type = bus_type;
17629                 asc_dvc_varp->drv_ptr = boardp;
17630                 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
17631                 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
17632                 asc_dvc_varp->iop_base = iop;
17633                 asc_dvc_varp->isr_callback = asc_isr_callback;
17634         } else {
17635                 ASC_DBG(1, "advansys_board_found: wide board\n");
17636                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
17637                 adv_dvc_varp->drv_ptr = boardp;
17638                 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
17639                 adv_dvc_varp->isr_callback = adv_isr_callback;
17640                 adv_dvc_varp->async_callback = adv_async_callback;
17641 #ifdef CONFIG_PCI
17642                 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
17643                         ASC_DBG(1, "advansys_board_found: ASC-3550\n");
17644                         adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
17645                 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
17646                         ASC_DBG(1, "advansys_board_found: ASC-38C0800\n");
17647                         adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
17648                 } else {
17649                         ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
17650                         adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
17651                 }
17652 #endif /* CONFIG_PCI */
17653
17654                 /*
17655                  * Map the board's registers into virtual memory for
17656                  * PCI slave access. Only memory accesses are used to
17657                  * access the board's registers.
17658                  *
17659                  * Note: The PCI register base address is not always
17660                  * page aligned, but the address passed to ioremap()
17661                  * must be page aligned. It is guaranteed that the
17662                  * PCI register base address will not cross a page
17663                  * boundary.
17664                  */
17665                 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17666                         iolen = ADV_3550_IOLEN;
17667                 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17668                         iolen = ADV_38C0800_IOLEN;
17669                 } else {
17670                         iolen = ADV_38C1600_IOLEN;
17671                 }
17672 #ifdef CONFIG_PCI
17673                 pci_memory_address = pci_resource_start(pdev, 1);
17674                 ASC_DBG1(1,
17675                          "advansys_board_found: pci_memory_address: 0x%lx\n",
17676                          (ulong)pci_memory_address);
17677                 if ((boardp->ioremap_addr =
17678                      ioremap(pci_memory_address & PAGE_MASK, PAGE_SIZE)) == 0) {
17679                         ASC_PRINT3
17680                             ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
17681                              boardp->id, pci_memory_address, iolen);
17682                         goto err_shost;
17683                 }
17684                 ASC_DBG1(1,
17685                          "advansys_board_found: ioremap_addr: 0x%lx\n",
17686                          (ulong)boardp->ioremap_addr);
17687                 adv_dvc_varp->iop_base = (AdvPortAddr)
17688                     (boardp->ioremap_addr +
17689                      (pci_memory_address - (pci_memory_address & PAGE_MASK)));
17690                 ASC_DBG1(1,
17691                          "advansys_board_found: iop_base: 0x%lx\n",
17692                          adv_dvc_varp->iop_base);
17693 #endif /* CONFIG_PCI */
17694
17695                 /*
17696                  * Even though it isn't used to access wide boards, other
17697                  * than for the debug line below, save I/O Port address so
17698                  * that it can be reported.
17699                  */
17700                 boardp->ioport = iop;
17701
17702                 ASC_DBG2(1,
17703                          "advansys_board_found: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
17704                          (ushort)inp(iop + 1), (ushort)inpw(iop));
17705         }
17706
17707 #ifdef CONFIG_PROC_FS
17708         /*
17709          * Allocate buffer for printing information from
17710          * /proc/scsi/advansys/[0...].
17711          */
17712         boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
17713         if (!boardp->prtbuf) {
17714                 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
17715                            "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
17716                 goto err_unmap;
17717         }
17718 #endif /* CONFIG_PROC_FS */
17719
17720         if (ASC_NARROW_BOARD(boardp)) {
17721                 asc_dvc_varp->cfg->dev = dev;
17722                 /*
17723                  * Set the board bus type and PCI IRQ before
17724                  * calling AscInitGetConfig().
17725                  */
17726                 switch (asc_dvc_varp->bus_type) {
17727 #ifdef CONFIG_ISA
17728                 case ASC_IS_ISA:
17729                         shost->unchecked_isa_dma = TRUE;
17730                         share_irq = 0;
17731                         break;
17732                 case ASC_IS_VL:
17733                         shost->unchecked_isa_dma = FALSE;
17734                         share_irq = 0;
17735                         break;
17736                 case ASC_IS_EISA:
17737                         shost->unchecked_isa_dma = FALSE;
17738                         share_irq = IRQF_SHARED;
17739                         break;
17740 #endif /* CONFIG_ISA */
17741 #ifdef CONFIG_PCI
17742                 case ASC_IS_PCI:
17743                         shost->irq = asc_dvc_varp->irq_no = pdev->irq;
17744                         asc_dvc_varp->cfg->pci_slot_info =
17745                             ASC_PCI_MKID(pdev->bus->number,
17746                                          PCI_SLOT(pdev->devfn),
17747                                          PCI_FUNC(pdev->devfn));
17748                         shost->unchecked_isa_dma = FALSE;
17749                         share_irq = IRQF_SHARED;
17750                         break;
17751 #endif /* CONFIG_PCI */
17752                 default:
17753                         ASC_PRINT2
17754                             ("advansys_board_found: board %d: unknown adapter type: %d\n",
17755                              boardp->id, asc_dvc_varp->bus_type);
17756                         shost->unchecked_isa_dma = TRUE;
17757                         share_irq = 0;
17758                         break;
17759                 }
17760         } else {
17761                 adv_dvc_varp->cfg->dev = dev;
17762                 /*
17763                  * For Wide boards set PCI information before calling
17764                  * AdvInitGetConfig().
17765                  */
17766 #ifdef CONFIG_PCI
17767                 shost->irq = adv_dvc_varp->irq_no = pdev->irq;
17768                 adv_dvc_varp->cfg->pci_slot_info =
17769                     ASC_PCI_MKID(pdev->bus->number,
17770                                  PCI_SLOT(pdev->devfn),
17771                                  PCI_FUNC(pdev->devfn));
17772                 shost->unchecked_isa_dma = FALSE;
17773                 share_irq = IRQF_SHARED;
17774 #endif /* CONFIG_PCI */
17775         }
17776
17777         /*
17778          * Read the board configuration.
17779          */
17780         if (ASC_NARROW_BOARD(boardp)) {
17781                 /*
17782                  * NOTE: AscInitGetConfig() may change the board's
17783                  * bus_type value. The bus_type value should no
17784                  * longer be used. If the bus_type field must be
17785                  * referenced only use the bit-wise AND operator "&".
17786                  */
17787                 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
17788                 switch (ret = AscInitGetConfig(asc_dvc_varp)) {
17789                 case 0: /* No error */
17790                         break;
17791                 case ASC_WARN_IO_PORT_ROTATE:
17792                         ASC_PRINT1
17793                             ("AscInitGetConfig: board %d: I/O port address modified\n",
17794                              boardp->id);
17795                         break;
17796                 case ASC_WARN_AUTO_CONFIG:
17797                         ASC_PRINT1
17798                             ("AscInitGetConfig: board %d: I/O port increment switch enabled\n",
17799                              boardp->id);
17800                         break;
17801                 case ASC_WARN_EEPROM_CHKSUM:
17802                         ASC_PRINT1
17803                             ("AscInitGetConfig: board %d: EEPROM checksum error\n",
17804                              boardp->id);
17805                         break;
17806                 case ASC_WARN_IRQ_MODIFIED:
17807                         ASC_PRINT1
17808                             ("AscInitGetConfig: board %d: IRQ modified\n",
17809                              boardp->id);
17810                         break;
17811                 case ASC_WARN_CMD_QNG_CONFLICT:
17812                         ASC_PRINT1
17813                             ("AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
17814                              boardp->id);
17815                         break;
17816                 default:
17817                         ASC_PRINT2
17818                             ("AscInitGetConfig: board %d: unknown warning: 0x%x\n",
17819                              boardp->id, ret);
17820                         break;
17821                 }
17822                 if ((err_code = asc_dvc_varp->err_code) != 0) {
17823                         ASC_PRINT3
17824                             ("AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
17825                              boardp->id,
17826                              asc_dvc_varp->init_state, asc_dvc_varp->err_code);
17827                 }
17828         } else {
17829                 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
17830                 if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
17831                         ASC_PRINT2
17832                             ("AdvInitGetConfig: board %d: warning: 0x%x\n",
17833                              boardp->id, ret);
17834                 }
17835                 if ((err_code = adv_dvc_varp->err_code) != 0) {
17836                         ASC_PRINT2
17837                             ("AdvInitGetConfig: board %d error: err_code 0x%x\n",
17838                              boardp->id, adv_dvc_varp->err_code);
17839                 }
17840         }
17841
17842         if (err_code != 0)
17843                 goto err_free_proc;
17844
17845         /*
17846          * Save the EEPROM configuration so that it can be displayed
17847          * from /proc/scsi/advansys/[0...].
17848          */
17849         if (ASC_NARROW_BOARD(boardp)) {
17850
17851                 ASCEEP_CONFIG *ep;
17852
17853                 /*
17854                  * Set the adapter's target id bit in the 'init_tidmask' field.
17855                  */
17856                 boardp->init_tidmask |=
17857                     ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
17858
17859                 /*
17860                  * Save EEPROM settings for the board.
17861                  */
17862                 ep = &boardp->eep_config.asc_eep;
17863
17864                 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
17865                 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
17866                 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
17867                 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
17868                 ep->start_motor = asc_dvc_varp->start_motor;
17869                 ep->cntl = asc_dvc_varp->dvc_cntl;
17870                 ep->no_scam = asc_dvc_varp->no_scam;
17871                 ep->max_total_qng = asc_dvc_varp->max_total_qng;
17872                 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
17873                 /* 'max_tag_qng' is set to the same value for every device. */
17874                 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
17875                 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
17876                 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
17877                 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
17878                 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
17879                 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
17880                 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
17881
17882                 /*
17883                  * Modify board configuration.
17884                  */
17885                 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
17886                 switch (ret = AscInitSetConfig(asc_dvc_varp)) {
17887                 case 0: /* No error. */
17888                         break;
17889                 case ASC_WARN_IO_PORT_ROTATE:
17890                         ASC_PRINT1
17891                             ("AscInitSetConfig: board %d: I/O port address modified\n",
17892                              boardp->id);
17893                         break;
17894                 case ASC_WARN_AUTO_CONFIG:
17895                         ASC_PRINT1
17896                             ("AscInitSetConfig: board %d: I/O port increment switch enabled\n",
17897                              boardp->id);
17898                         break;
17899                 case ASC_WARN_EEPROM_CHKSUM:
17900                         ASC_PRINT1
17901                             ("AscInitSetConfig: board %d: EEPROM checksum error\n",
17902                              boardp->id);
17903                         break;
17904                 case ASC_WARN_IRQ_MODIFIED:
17905                         ASC_PRINT1
17906                             ("AscInitSetConfig: board %d: IRQ modified\n",
17907                              boardp->id);
17908                         break;
17909                 case ASC_WARN_CMD_QNG_CONFLICT:
17910                         ASC_PRINT1
17911                             ("AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
17912                              boardp->id);
17913                         break;
17914                 default:
17915                         ASC_PRINT2
17916                             ("AscInitSetConfig: board %d: unknown warning: 0x%x\n",
17917                              boardp->id, ret);
17918                         break;
17919                 }
17920                 if (asc_dvc_varp->err_code != 0) {
17921                         ASC_PRINT3
17922                             ("AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
17923                              boardp->id,
17924                              asc_dvc_varp->init_state, asc_dvc_varp->err_code);
17925                         goto err_free_proc;
17926                 }
17927
17928                 /*
17929                  * Finish initializing the 'Scsi_Host' structure.
17930                  */
17931                 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
17932                 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
17933                         shost->irq = asc_dvc_varp->irq_no;
17934                 }
17935         } else {
17936                 ADVEEP_3550_CONFIG *ep_3550;
17937                 ADVEEP_38C0800_CONFIG *ep_38C0800;
17938                 ADVEEP_38C1600_CONFIG *ep_38C1600;
17939
17940                 /*
17941                  * Save Wide EEP Configuration Information.
17942                  */
17943                 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17944                         ep_3550 = &boardp->eep_config.adv_3550_eep;
17945
17946                         ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
17947                         ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
17948                         ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17949                         ep_3550->termination = adv_dvc_varp->cfg->termination;
17950                         ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
17951                         ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
17952                         ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
17953                         ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
17954                         ep_3550->ultra_able = adv_dvc_varp->ultra_able;
17955                         ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
17956                         ep_3550->start_motor = adv_dvc_varp->start_motor;
17957                         ep_3550->scsi_reset_delay =
17958                             adv_dvc_varp->scsi_reset_wait;
17959                         ep_3550->serial_number_word1 =
17960                             adv_dvc_varp->cfg->serial1;
17961                         ep_3550->serial_number_word2 =
17962                             adv_dvc_varp->cfg->serial2;
17963                         ep_3550->serial_number_word3 =
17964                             adv_dvc_varp->cfg->serial3;
17965                 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17966                         ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
17967
17968                         ep_38C0800->adapter_scsi_id =
17969                             adv_dvc_varp->chip_scsi_id;
17970                         ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
17971                         ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17972                         ep_38C0800->termination_lvd =
17973                             adv_dvc_varp->cfg->termination;
17974                         ep_38C0800->disc_enable =
17975                             adv_dvc_varp->cfg->disc_enable;
17976                         ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
17977                         ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
17978                         ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
17979                         ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
17980                         ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
17981                         ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
17982                         ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
17983                         ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
17984                         ep_38C0800->start_motor = adv_dvc_varp->start_motor;
17985                         ep_38C0800->scsi_reset_delay =
17986                             adv_dvc_varp->scsi_reset_wait;
17987                         ep_38C0800->serial_number_word1 =
17988                             adv_dvc_varp->cfg->serial1;
17989                         ep_38C0800->serial_number_word2 =
17990                             adv_dvc_varp->cfg->serial2;
17991                         ep_38C0800->serial_number_word3 =
17992                             adv_dvc_varp->cfg->serial3;
17993                 } else {
17994                         ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
17995
17996                         ep_38C1600->adapter_scsi_id =
17997                             adv_dvc_varp->chip_scsi_id;
17998                         ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
17999                         ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
18000                         ep_38C1600->termination_lvd =
18001                             adv_dvc_varp->cfg->termination;
18002                         ep_38C1600->disc_enable =
18003                             adv_dvc_varp->cfg->disc_enable;
18004                         ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
18005                         ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
18006                         ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
18007                         ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
18008                         ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
18009                         ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
18010                         ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
18011                         ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
18012                         ep_38C1600->start_motor = adv_dvc_varp->start_motor;
18013                         ep_38C1600->scsi_reset_delay =
18014                             adv_dvc_varp->scsi_reset_wait;
18015                         ep_38C1600->serial_number_word1 =
18016                             adv_dvc_varp->cfg->serial1;
18017                         ep_38C1600->serial_number_word2 =
18018                             adv_dvc_varp->cfg->serial2;
18019                         ep_38C1600->serial_number_word3 =
18020                             adv_dvc_varp->cfg->serial3;
18021                 }
18022
18023                 /*
18024                  * Set the adapter's target id bit in the 'init_tidmask' field.
18025                  */
18026                 boardp->init_tidmask |=
18027                     ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
18028
18029                 /*
18030                  * Finish initializing the 'Scsi_Host' structure.
18031                  */
18032                 shost->irq = adv_dvc_varp->irq_no;
18033         }
18034
18035         /*
18036          * Channels are numbered beginning with 0. For AdvanSys one host
18037          * structure supports one channel. Multi-channel boards have a
18038          * separate host structure for each channel.
18039          */
18040         shost->max_channel = 0;
18041         if (ASC_NARROW_BOARD(boardp)) {
18042                 shost->max_id = ASC_MAX_TID + 1;
18043                 shost->max_lun = ASC_MAX_LUN + 1;
18044
18045                 shost->io_port = asc_dvc_varp->iop_base;
18046                 boardp->asc_n_io_port = ASC_IOADR_GAP;
18047                 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
18048
18049                 /* Set maximum number of queues the adapter can handle. */
18050                 shost->can_queue = asc_dvc_varp->max_total_qng;
18051         } else {
18052                 shost->max_id = ADV_MAX_TID + 1;
18053                 shost->max_lun = ADV_MAX_LUN + 1;
18054
18055                 /*
18056                  * Save the I/O Port address and length even though
18057                  * I/O ports are not used to access Wide boards.
18058                  * Instead the Wide boards are accessed with
18059                  * PCI Memory Mapped I/O.
18060                  */
18061                 shost->io_port = iop;
18062                 boardp->asc_n_io_port = iolen;
18063
18064                 shost->this_id = adv_dvc_varp->chip_scsi_id;
18065
18066                 /* Set maximum number of queues the adapter can handle. */
18067                 shost->can_queue = adv_dvc_varp->max_host_qng;
18068         }
18069
18070         /*
18071          * 'n_io_port' currently is one byte.
18072          *
18073          * Set a value to 'n_io_port', but never referenced it because
18074          * it may be truncated.
18075          */
18076         shost->n_io_port = boardp->asc_n_io_port <= 255 ?
18077             boardp->asc_n_io_port : 255;
18078
18079         /*
18080          * Following v1.3.89, 'cmd_per_lun' is no longer needed
18081          * and should be set to zero.
18082          *
18083          * But because of a bug introduced in v1.3.89 if the driver is
18084          * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
18085          * SCSI function 'allocate_device' will panic. To allow the driver
18086          * to work as a module in these kernels set 'cmd_per_lun' to 1.
18087          *
18088          * Note: This is wrong.  cmd_per_lun should be set to the depth
18089          * you want on untagged devices always.
18090          #ifdef MODULE
18091          */
18092         shost->cmd_per_lun = 1;
18093 /* #else
18094             shost->cmd_per_lun = 0;
18095 #endif */
18096
18097         /*
18098          * Set the maximum number of scatter-gather elements the
18099          * adapter can handle.
18100          */
18101         if (ASC_NARROW_BOARD(boardp)) {
18102                 /*
18103                  * Allow two commands with 'sg_tablesize' scatter-gather
18104                  * elements to be executed simultaneously. This value is
18105                  * the theoretical hardware limit. It may be decreased
18106                  * below.
18107                  */
18108                 shost->sg_tablesize =
18109                     (((asc_dvc_varp->max_total_qng - 2) / 2) *
18110                      ASC_SG_LIST_PER_Q) + 1;
18111         } else {
18112                 shost->sg_tablesize = ADV_MAX_SG_LIST;
18113         }
18114
18115         /*
18116          * The value of 'sg_tablesize' can not exceed the SCSI
18117          * mid-level driver definition of SG_ALL. SG_ALL also
18118          * must not be exceeded, because it is used to define the
18119          * size of the scatter-gather table in 'struct asc_sg_head'.
18120          */
18121         if (shost->sg_tablesize > SG_ALL) {
18122                 shost->sg_tablesize = SG_ALL;
18123         }
18124
18125         ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize);
18126
18127         /* BIOS start address. */
18128         if (ASC_NARROW_BOARD(boardp)) {
18129                 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
18130                                                     asc_dvc_varp->bus_type);
18131         } else {
18132                 /*
18133                  * Fill-in BIOS board variables. The Wide BIOS saves
18134                  * information in LRAM that is used by the driver.
18135                  */
18136                 AdvReadWordLram(adv_dvc_varp->iop_base,
18137                                 BIOS_SIGNATURE, boardp->bios_signature);
18138                 AdvReadWordLram(adv_dvc_varp->iop_base,
18139                                 BIOS_VERSION, boardp->bios_version);
18140                 AdvReadWordLram(adv_dvc_varp->iop_base,
18141                                 BIOS_CODESEG, boardp->bios_codeseg);
18142                 AdvReadWordLram(adv_dvc_varp->iop_base,
18143                                 BIOS_CODELEN, boardp->bios_codelen);
18144
18145                 ASC_DBG2(1,
18146                          "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n",
18147                          boardp->bios_signature, boardp->bios_version);
18148
18149                 ASC_DBG2(1,
18150                          "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n",
18151                          boardp->bios_codeseg, boardp->bios_codelen);
18152
18153                 /*
18154                  * If the BIOS saved a valid signature, then fill in
18155                  * the BIOS code segment base address.
18156                  */
18157                 if (boardp->bios_signature == 0x55AA) {
18158                         /*
18159                          * Convert x86 realmode code segment to a linear
18160                          * address by shifting left 4.
18161                          */
18162                         shost->base = ((ulong)boardp->bios_codeseg << 4);
18163                 } else {
18164                         shost->base = 0;
18165                 }
18166         }
18167
18168         /*
18169          * Register Board Resources - I/O Port, DMA, IRQ
18170          */
18171
18172         /*
18173          * Register I/O port range.
18174          *
18175          * For Wide boards the I/O ports are not used to access
18176          * the board, but request the region anyway.
18177          *
18178          * 'shost->n_io_port' is not referenced, because it may be truncated.
18179          */
18180         ASC_DBG2(2,
18181                  "advansys_board_found: request_region port 0x%lx, len 0x%x\n",
18182                  (ulong)shost->io_port, boardp->asc_n_io_port);
18183         if (request_region(shost->io_port, boardp->asc_n_io_port,
18184                            "advansys") == NULL) {
18185                 ASC_PRINT3
18186                     ("advansys_board_found: board %d: request_region() failed, port 0x%lx, len 0x%x\n",
18187                      boardp->id, (ulong)shost->io_port, boardp->asc_n_io_port);
18188                 goto err_free_proc;
18189         }
18190
18191         /* Register DMA Channel for Narrow boards. */
18192         shost->dma_channel = NO_ISA_DMA;        /* Default to no ISA DMA. */
18193 #ifdef CONFIG_ISA
18194         if (ASC_NARROW_BOARD(boardp)) {
18195                 /* Register DMA channel for ISA bus. */
18196                 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
18197                         shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
18198                         ret = request_dma(shost->dma_channel, "advansys");
18199                         if (ret) {
18200                                 ASC_PRINT3
18201                                     ("advansys_board_found: board %d: request_dma() %d failed %d\n",
18202                                      boardp->id, shost->dma_channel, ret);
18203                                 goto err_free_region;
18204                         }
18205                         AscEnableIsaDma(shost->dma_channel);
18206                 }
18207         }
18208 #endif /* CONFIG_ISA */
18209
18210         /* Register IRQ Number. */
18211         ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq);
18212
18213         ret = request_irq(shost->irq, advansys_interrupt, share_irq,
18214                           "advansys", shost);
18215
18216         if (ret) {
18217                 if (ret == -EBUSY) {
18218                         ASC_PRINT2
18219                             ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
18220                              boardp->id, shost->irq);
18221                 } else if (ret == -EINVAL) {
18222                         ASC_PRINT2
18223                             ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
18224                              boardp->id, shost->irq);
18225                 } else {
18226                         ASC_PRINT3
18227                             ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
18228                              boardp->id, shost->irq, ret);
18229                 }
18230                 goto err_free_dma;
18231         }
18232
18233         /*
18234          * Initialize board RISC chip and enable interrupts.
18235          */
18236         if (ASC_NARROW_BOARD(boardp)) {
18237                 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
18238                 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
18239                 err_code = asc_dvc_varp->err_code;
18240
18241                 if (warn_code || err_code) {
18242                         ASC_PRINT4
18243                             ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
18244                              boardp->id,
18245                              asc_dvc_varp->init_state, warn_code, err_code);
18246                 }
18247         } else {
18248                 err_code = advansys_wide_init_chip(boardp, adv_dvc_varp);
18249         }
18250
18251         if (err_code != 0)
18252                 goto err_free_wide_mem;
18253
18254         ASC_DBG_PRT_SCSI_HOST(2, shost);
18255
18256         ret = scsi_add_host(shost, dev);
18257         if (ret)
18258                 goto err_free_wide_mem;
18259
18260         scsi_scan_host(shost);
18261         return shost;
18262
18263  err_free_wide_mem:
18264         advansys_wide_free_mem(boardp);
18265         free_irq(shost->irq, shost);
18266  err_free_dma:
18267         if (shost->dma_channel != NO_ISA_DMA)
18268                 free_dma(shost->dma_channel);
18269  err_free_region:
18270         release_region(shost->io_port, boardp->asc_n_io_port);
18271  err_free_proc:
18272         kfree(boardp->prtbuf);
18273  err_unmap:
18274         if (boardp->ioremap_addr)
18275                 iounmap(boardp->ioremap_addr);
18276  err_shost:
18277         scsi_host_put(shost);
18278         return NULL;
18279 }
18280
18281 /*
18282  * advansys_release()
18283  *
18284  * Release resources allocated for a single AdvanSys adapter.
18285  */
18286 static int advansys_release(struct Scsi_Host *shost)
18287 {
18288         asc_board_t *boardp;
18289
18290         ASC_DBG(1, "advansys_release: begin\n");
18291         scsi_remove_host(shost);
18292         boardp = ASC_BOARDP(shost);
18293         free_irq(shost->irq, shost);
18294         if (shost->dma_channel != NO_ISA_DMA) {
18295                 ASC_DBG(1, "advansys_release: free_dma()\n");
18296                 free_dma(shost->dma_channel);
18297         }
18298         release_region(shost->io_port, boardp->asc_n_io_port);
18299         if (ASC_WIDE_BOARD(boardp)) {
18300                 iounmap(boardp->ioremap_addr);
18301                 advansys_wide_free_mem(boardp);
18302         }
18303         kfree(boardp->prtbuf);
18304         scsi_host_put(shost);
18305         ASC_DBG(1, "advansys_release: end\n");
18306         return 0;
18307 }
18308
18309 static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
18310         0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
18311         0x0210, 0x0230, 0x0250, 0x0330
18312 };
18313
18314 static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
18315 {
18316         PortAddr iop_base = _asc_def_iop_base[id];
18317         struct Scsi_Host *shost;
18318
18319         if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
18320                 ASC_DBG1(1, "advansys_isa_match: check_region() failed "
18321                          "I/O port 0x%x\n", iop_base);
18322                 return -ENODEV;
18323         }
18324         ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base);
18325         release_region(iop_base, ASC_IOADR_GAP);
18326         if (!AscFindSignature(iop_base))
18327                 goto nodev;
18328         if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
18329                 goto nodev;
18330
18331         shost = advansys_board_found(iop_base, dev, ASC_IS_ISA);
18332
18333         if (!shost)
18334                 goto nodev;
18335
18336         dev_set_drvdata(dev, shost);
18337         return 0;
18338
18339  nodev:
18340         return -ENODEV;
18341 }
18342
18343 static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
18344 {
18345         advansys_release(dev_get_drvdata(dev));
18346         return 0;
18347 }
18348
18349 static struct isa_driver advansys_isa_driver = {
18350         .probe          = advansys_isa_probe,
18351         .remove         = __devexit_p(advansys_isa_remove),
18352         .driver = {
18353                 .owner  = THIS_MODULE,
18354                 .name   = "advansys",
18355         },
18356 };
18357
18358 static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
18359 {
18360         PortAddr iop_base = _asc_def_iop_base[id];
18361         struct Scsi_Host *shost;
18362
18363         if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
18364                 ASC_DBG1(1, "advansys_vlb_match: check_region() failed "
18365                          "I/O port 0x%x\n", iop_base);
18366                 return -ENODEV;
18367         }
18368         ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base);
18369         release_region(iop_base, ASC_IOADR_GAP);
18370         if (!AscFindSignature(iop_base))
18371                 goto nodev;
18372         /*
18373          * I don't think this condition can actually happen, but the old
18374          * driver did it, and the chances of finding a VLB setup in 2007
18375          * to do testing with is slight to none.
18376          */
18377         if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
18378                 goto nodev;
18379
18380         shost = advansys_board_found(iop_base, dev, ASC_IS_VL);
18381
18382         if (!shost)
18383                 goto nodev;
18384
18385         dev_set_drvdata(dev, shost);
18386         return 0;
18387
18388  nodev:
18389         return -ENODEV;
18390 }
18391
18392 static struct isa_driver advansys_vlb_driver = {
18393         .probe          = advansys_vlb_probe,
18394         .remove         = __devexit_p(advansys_isa_remove),
18395         .driver = {
18396                 .owner  = THIS_MODULE,
18397                 .name   = "advansys",
18398         },
18399 };
18400
18401 static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
18402         { "ABP7401" },
18403         { "ABP7501" },
18404         { "" }
18405 };
18406
18407 MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
18408
18409 /*
18410  * EISA is a little more tricky than PCI; each EISA device may have two
18411  * channels, and this driver is written to make each channel its own Scsi_Host
18412  */
18413 struct eisa_scsi_data {
18414         struct Scsi_Host *host[2];
18415 };
18416
18417 static int __devinit advansys_eisa_probe(struct device *dev)
18418 {
18419         int i, ioport;
18420         int err;
18421         struct eisa_device *edev = to_eisa_device(dev);
18422         struct eisa_scsi_data *data;
18423
18424         err = -ENOMEM;
18425         data = kzalloc(sizeof(*data), GFP_KERNEL);
18426         if (!data)
18427                 goto fail;
18428         ioport = edev->base_addr + 0xc30;
18429
18430         err = -ENODEV;
18431         for (i = 0; i < 2; i++, ioport += 0x20) {
18432                 if (!AscFindSignature(ioport))
18433                         continue;
18434                 /*
18435                  * I don't know why we need to do this for EISA chips, but
18436                  * not for any others.  It looks to be equivalent to
18437                  * AscGetChipCfgMsw, but I may have overlooked something,
18438                  * so I'm not converting it until I get an EISA board to
18439                  * test with.
18440                  */
18441                 inw(ioport + 4);
18442                 data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA);
18443                 if (data->host[i])
18444                         err = 0;
18445         }
18446
18447         if (err) {
18448                 kfree(data);
18449         } else {
18450                 dev_set_drvdata(dev, data);
18451         }
18452
18453  fail:
18454         return err;
18455 }
18456
18457 static __devexit int advansys_eisa_remove(struct device *dev)
18458 {
18459         int i;
18460         struct eisa_scsi_data *data = dev_get_drvdata(dev);
18461
18462         for (i = 0; i < 2; i++) {
18463                 struct Scsi_Host *shost = data->host[i];
18464                 if (!shost)
18465                         continue;
18466                 advansys_release(shost);
18467         }
18468
18469         kfree(data);
18470         return 0;
18471 }
18472
18473 static struct eisa_driver advansys_eisa_driver = {
18474         .id_table =             advansys_eisa_table,
18475         .driver = {
18476                 .name =         "advansys",
18477                 .probe =        advansys_eisa_probe,
18478                 .remove =       __devexit_p(advansys_eisa_remove),
18479         }
18480 };
18481
18482 /* PCI Devices supported by this driver */
18483 static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
18484         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
18485          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18486         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
18487          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18488         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
18489          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18490         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
18491          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18492         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
18493          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18494         {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
18495          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18496         {}
18497 };
18498
18499 MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
18500
18501 static int __devinit
18502 advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
18503 {
18504         int err, ioport;
18505         struct Scsi_Host *shost;
18506
18507         err = pci_enable_device(pdev);
18508         if (err)
18509                 goto fail;
18510
18511         if (pci_resource_len(pdev, 0) == 0)
18512                 goto nodev;
18513
18514         ioport = pci_resource_start(pdev, 0);
18515         shost = advansys_board_found(ioport, &pdev->dev, ASC_IS_PCI);
18516
18517         if (!shost)
18518                 goto nodev;
18519
18520         pci_set_drvdata(pdev, shost);
18521         return 0;
18522
18523  nodev:
18524         err = -ENODEV;
18525         pci_disable_device(pdev);
18526  fail:
18527         return err;
18528 }
18529
18530 static void __devexit advansys_pci_remove(struct pci_dev *pdev)
18531 {
18532         advansys_release(pci_get_drvdata(pdev));
18533         pci_disable_device(pdev);
18534 }
18535
18536 static struct pci_driver advansys_pci_driver = {
18537         .name =         "advansys",
18538         .id_table =     advansys_pci_tbl,
18539         .probe =        advansys_pci_probe,
18540         .remove =       __devexit_p(advansys_pci_remove),
18541 };
18542
18543 static int __init advansys_init(void)
18544 {
18545         int error;
18546
18547         error = isa_register_driver(&advansys_isa_driver,
18548                                     ASC_IOADR_TABLE_MAX_IX);
18549         if (error)
18550                 goto fail;
18551
18552         error = isa_register_driver(&advansys_vlb_driver,
18553                                     ASC_IOADR_TABLE_MAX_IX);
18554         if (error)
18555                 goto unregister_isa;
18556
18557         error = eisa_driver_register(&advansys_eisa_driver);
18558         if (error)
18559                 goto unregister_vlb;
18560
18561         error = pci_register_driver(&advansys_pci_driver);
18562         if (error)
18563                 goto unregister_eisa;
18564
18565         return 0;
18566
18567  unregister_eisa:
18568         eisa_driver_unregister(&advansys_eisa_driver);
18569  unregister_vlb:
18570         isa_unregister_driver(&advansys_vlb_driver);
18571  unregister_isa:
18572         isa_unregister_driver(&advansys_isa_driver);
18573  fail:
18574         return error;
18575 }
18576
18577 static void __exit advansys_exit(void)
18578 {
18579         pci_unregister_driver(&advansys_pci_driver);
18580         eisa_driver_unregister(&advansys_eisa_driver);
18581         isa_unregister_driver(&advansys_vlb_driver);
18582         isa_unregister_driver(&advansys_isa_driver);
18583 }
18584
18585 module_init(advansys_init);
18586 module_exit(advansys_exit);
18587
18588 MODULE_LICENSE("GPL");