xref: /openbmc/linux/drivers/scsi/advansys.c (revision c21b37f6)
1 #define ASC_VERSION "3.3K"	/* AdvanSys Driver Version */
2 
3 /*
4  * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
5  *
6  * Copyright (c) 1995-2000 Advanced System Products, Inc.
7  * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
8  * All Rights Reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that redistributions of source
12  * code retain the above copyright notice and this comment without
13  * modification.
14  *
15  * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
16  * changed its name to ConnectCom Solutions, Inc.
17  *
18  */
19 
20 /*
21 
22   Documentation for the AdvanSys Driver
23 
24   A. Linux Kernels Supported by this Driver
25   B. Adapters Supported by this Driver
26   C. Linux source files modified by AdvanSys Driver
27   D. Source Comments
28   E. Driver Compile Time Options and Debugging
29   F. Driver LILO Option
30   G. Tests to run before releasing new driver
31   H. Release History
32   I. Known Problems/Fix List
33   J. Credits (Chronological Order)
34 
35   A. Linux Kernels Supported by this Driver
36 
37      This driver has been tested in the following Linux kernels: v2.2.18
38      v2.4.0. The driver is supported on v2.2 and v2.4 kernels and on x86,
39      alpha, and PowerPC platforms.
40 
41   B. Adapters Supported by this Driver
42 
43      AdvanSys (Advanced System Products, Inc.) manufactures the following
44      RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow
45      (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI
46      buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit
47      transfer) SCSI Host Adapters for the PCI bus.
48 
49      The CDB counts below indicate the number of SCSI CDB (Command
50      Descriptor Block) requests that can be stored in the RISC chip
51      cache and board LRAM. A CDB is a single SCSI command. The driver
52      detect routine will display the number of CDBs available for each
53      adapter detected. The number of CDBs used by the driver can be
54      lowered in the BIOS by changing the 'Host Queue Size' adapter setting.
55 
56      Laptop Products:
57         ABP-480 - Bus-Master CardBus (16 CDB) (2.4 kernel and greater)
58 
59      Connectivity Products:
60         ABP510/5150 - Bus-Master ISA (240 CDB)
61         ABP5140 - Bus-Master ISA PnP (16 CDB)
62         ABP5142 - Bus-Master ISA PnP with floppy (16 CDB)
63         ABP902/3902 - Bus-Master PCI (16 CDB)
64         ABP3905 - Bus-Master PCI (16 CDB)
65         ABP915 - Bus-Master PCI (16 CDB)
66         ABP920 - Bus-Master PCI (16 CDB)
67         ABP3922 - Bus-Master PCI (16 CDB)
68         ABP3925 - Bus-Master PCI (16 CDB)
69         ABP930 - Bus-Master PCI (16 CDB)
70         ABP930U - Bus-Master PCI Ultra (16 CDB)
71         ABP930UA - Bus-Master PCI Ultra (16 CDB)
72         ABP960 - Bus-Master PCI MAC/PC (16 CDB)
73         ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
74 
75      Single Channel Products:
76         ABP542 - Bus-Master ISA with floppy (240 CDB)
77         ABP742 - Bus-Master EISA (240 CDB)
78         ABP842 - Bus-Master VL (240 CDB)
79         ABP940 - Bus-Master PCI (240 CDB)
80         ABP940U - Bus-Master PCI Ultra (240 CDB)
81         ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB)
82         ABP970 - Bus-Master PCI MAC/PC (240 CDB)
83         ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
84         ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB)
85         ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB)
86         ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB)
87         ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB)
88 
89      Multi-Channel Products:
90         ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
91         ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
92         ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
93         ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel)
94         ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
95         ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
96         ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.)
97         ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB)
98         ABP3950U3W - Bus-Master PCI Dual LVD2/Ultra3-Wide (253 CDB)
99 
100   C. Linux source files modified by AdvanSys Driver
101 
102      This section for historical purposes documents the changes
103      originally made to the Linux kernel source to add the advansys
104      driver. As Linux has changed some of these files have also
105      been modified.
106 
107      1. linux/arch/i386/config.in:
108 
109           bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
110 
111      2. linux/drivers/scsi/hosts.c:
112 
113           #ifdef CONFIG_SCSI_ADVANSYS
114           #include "advansys.h"
115           #endif
116 
117         and after "static struct scsi_host_template builtin_scsi_hosts[] =":
118 
119           #ifdef CONFIG_SCSI_ADVANSYS
120           ADVANSYS,
121           #endif
122 
123      3. linux/drivers/scsi/Makefile:
124 
125           ifdef CONFIG_SCSI_ADVANSYS
126           SCSI_SRCS := $(SCSI_SRCS) advansys.c
127           SCSI_OBJS := $(SCSI_OBJS) advansys.o
128           else
129           SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
130           endif
131 
132      4. linux/init/main.c:
133 
134           extern void advansys_setup(char *str, int *ints);
135 
136         and add the following lines to the bootsetups[] array.
137 
138           #ifdef CONFIG_SCSI_ADVANSYS
139              { "advansys=", advansys_setup },
140           #endif
141 
142   D. Source Comments
143 
144      1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
145 
146      2. This driver should be maintained in multiple files. But to make
147         it easier to include with Linux and to follow Linux conventions,
148         the whole driver is maintained in the source files advansys.h and
149         advansys.c. In this file logical sections of the driver begin with
150         a comment that contains '---'. The following are the logical sections
151         of the driver below.
152 
153            --- Linux Version
154            --- Linux Include File
155            --- Driver Options
156            --- Debugging Header
157            --- Asc Library Constants and Macros
158            --- Adv Library Constants and Macros
159            --- Driver Constants and Macros
160            --- Driver Structures
161            --- Driver Data
162            --- Driver Function Prototypes
163            --- Linux 'struct scsi_host_template' and advansys_setup() Functions
164            --- Loadable Driver Support
165            --- Miscellaneous Driver Functions
166            --- Functions Required by the Asc Library
167            --- Functions Required by the Adv Library
168            --- Tracing and Debugging Functions
169            --- Asc Library Functions
170            --- Adv Library Functions
171 
172      3. The string 'XXX' is used to flag code that needs to be re-written
173         or that contains a problem that needs to be addressed.
174 
175      4. I have stripped comments from and reformatted the source for the
176         Asc Library and Adv Library to reduce the size of this file. This
177         source can be found under the following headings. The Asc Library
178         is used to support Narrow Boards. The Adv Library is used to
179         support Wide Boards.
180 
181            --- Asc Library Constants and Macros
182            --- Adv Library Constants and Macros
183            --- Asc Library Functions
184            --- Adv Library Functions
185 
186   E. Driver Compile Time Options and Debugging
187 
188      In this source file the following constants can be defined. They are
189      defined in the source below. Both of these options are enabled by
190      default.
191 
192      1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled)
193 
194         Enabling this option adds assertion logic statements to the
195         driver. If an assertion fails a message will be displayed to
196         the console, but the system will continue to operate. Any
197         assertions encountered should be reported to the person
198         responsible for the driver. Assertion statements may proactively
199         detect problems with the driver and facilitate fixing these
200         problems. Enabling assertions will add a small overhead to the
201         execution of the driver.
202 
203      2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled)
204 
205         Enabling this option adds tracing functions to the driver and
206         the ability to set a driver tracing level at boot time. This
207         option will also export symbols not required outside the driver to
208         the kernel name space. This option is very useful for debugging
209         the driver, but it will add to the size of the driver execution
210         image and add overhead to the execution of the driver.
211 
212         The amount of debugging output can be controlled with the global
213         variable 'asc_dbglvl'. The higher the number the more output. By
214         default the debug level is 0.
215 
216         If the driver is loaded at boot time and the LILO Driver Option
217         is included in the system, the debug level can be changed by
218         specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
219         first three hex digits of the pseudo I/O Port must be set to
220         'deb' and the fourth hex digit specifies the debug level: 0 - F.
221         The following command line will look for an adapter at 0x330
222         and set the debug level to 2.
223 
224            linux advansys=0x330,0,0,0,0xdeb2
225 
226         If the driver is built as a loadable module this variable can be
227         defined when the driver is loaded. The following insmod command
228         will set the debug level to one.
229 
230            insmod advansys.o asc_dbglvl=1
231 
232         Debugging Message Levels:
233            0: Errors Only
234            1: High-Level Tracing
235            2-N: Verbose Tracing
236 
237         To enable debug output to console, please make sure that:
238 
239         a. System and kernel logging is enabled (syslogd, klogd running).
240         b. Kernel messages are routed to console output. Check
241            /etc/syslog.conf for an entry similar to this:
242 
243                 kern.*                  /dev/console
244 
245         c. klogd is started with the appropriate -c parameter
246            (e.g. klogd -c 8)
247 
248         This will cause printk() messages to be be displayed on the
249         current console. Refer to the klogd(8) and syslogd(8) man pages
250         for details.
251 
252         Alternatively you can enable printk() to console with this
253         program. However, this is not the 'official' way to do this.
254         Debug output is logged in /var/log/messages.
255 
256           main()
257           {
258                   syscall(103, 7, 0, 0);
259           }
260 
261         Increasing LOG_BUF_LEN in kernel/printk.c to something like
262         40960 allows more debug messages to be buffered in the kernel
263         and written to the console or log file.
264 
265      3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0)
266 
267         Enabling this option adds statistics collection and display
268         through /proc to the driver. The information is useful for
269         monitoring driver and device performance. It will add to the
270         size of the driver execution image and add minor overhead to
271         the execution of the driver.
272 
273         Statistics are maintained on a per adapter basis. Driver entry
274         point call counts and transfer size counts are maintained.
275         Statistics are only available for kernels greater than or equal
276         to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured.
277 
278         AdvanSys SCSI adapter files have the following path name format:
279 
280            /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
281 
282         This information can be displayed with cat. For example:
283 
284            cat /proc/scsi/advansys/0
285 
286         When ADVANSYS_STATS is not defined the AdvanSys /proc files only
287         contain adapter and device configuration information.
288 
289   F. Driver LILO Option
290 
291      If init/main.c is modified as described in the 'Directions for Adding
292      the AdvanSys Driver to Linux' section (B.4.) above, the driver will
293      recognize the 'advansys' LILO command line and /etc/lilo.conf option.
294      This option can be used to either disable I/O port scanning or to limit
295      scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
296      PCI boards will still be searched for and detected. This option only
297      affects searching for ISA and VL boards.
298 
299      Examples:
300        1. Eliminate I/O port scanning:
301             boot: linux advansys=
302               or
303             boot: linux advansys=0x0
304        2. Limit I/O port scanning to one I/O port:
305             boot: linux advansys=0x110
306        3. Limit I/O port scanning to four I/O ports:
307             boot: linux advansys=0x110,0x210,0x230,0x330
308 
309      For a loadable module the same effect can be achieved by setting
310      the 'asc_iopflag' variable and 'asc_ioport' array when loading
311      the driver, e.g.
312 
313            insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
314 
315      If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1)
316      I/O Port may be added to specify the driver debug level. Refer to
317      the 'Driver Compile Time Options and Debugging' section above for
318      more information.
319 
320   G. Tests to run before releasing new driver
321 
322      1. In the supported kernels verify there are no warning or compile
323         errors when the kernel is built as both a driver and as a module
324         and with the following options:
325 
326         ADVANSYS_DEBUG - enabled and disabled
327         CONFIG_SMP - enabled and disabled
328         CONFIG_PROC_FS - enabled and disabled
329 
330      2. Run tests on an x86, alpha, and PowerPC with at least one narrow
331         card and one wide card attached to a hard disk and CD-ROM drive:
332         fdisk, mkfs, fsck, bonnie, copy/compare test from the
333         CD-ROM to the hard drive.
334 
335   H. Release History
336 
337      BETA-1.0 (12/23/95):
338          First Release
339 
340      BETA-1.1 (12/28/95):
341          1. Prevent advansys_detect() from being called twice.
342          2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
343 
344      1.2 (1/12/96):
345          1. Prevent re-entrancy in the interrupt handler which
346             resulted in the driver hanging Linux.
347          2. Fix problem that prevented ABP-940 cards from being
348             recognized on some PCI motherboards.
349          3. Add support for the ABP-5140 PnP ISA card.
350          4. Fix check condition return status.
351          5. Add conditionally compiled code for Linux v1.3.X.
352 
353      1.3 (2/23/96):
354          1. Fix problem in advansys_biosparam() that resulted in the
355             wrong drive geometry being returned for drives > 1GB with
356             extended translation enabled.
357          2. Add additional tracing during device initialization.
358          3. Change code that only applies to ISA PnP adapter.
359          4. Eliminate 'make dep' warning.
360          5. Try to fix problem with handling resets by increasing their
361             timeout value.
362 
363      1.4 (5/8/96):
364          1. Change definitions to eliminate conflicts with other subsystems.
365          2. Add versioning code for the shared interrupt changes.
366          3. Eliminate problem in asc_rmqueue() with iterating after removing
367             a request.
368          4. Remove reset request loop problem from the "Known Problems or
369             Issues" section. This problem was isolated and fixed in the
370             mid-level SCSI driver.
371 
372      1.5 (8/8/96):
373          1. Add support for ABP-940U (PCI Ultra) adapter.
374          2. Add support for IRQ sharing by setting the IRQF_SHARED flag for
375             request_irq and supplying a dev_id pointer to both request_irq()
376             and free_irq().
377          3. In AscSearchIOPortAddr11() restore a call to check_region() which
378             should be used before I/O port probing.
379          4. Fix bug in asc_prt_hex() which resulted in the displaying
380             the wrong data.
381          5. Incorporate miscellaneous Asc Library bug fixes and new microcode.
382          6. Change driver versioning to be specific to each Linux sub-level.
383          7. Change statistics gathering to be per adapter instead of global
384             to the driver.
385          8. Add more information and statistics to the adapter /proc file:
386             /proc/scsi/advansys[0...].
387          9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list.
388             This problem has been addressed with the SCSI mid-level changes
389             made in v1.3.89. The advansys_select_queue_depths() function
390             was added for the v1.3.89 changes.
391 
392      1.6 (9/10/96):
393          1. Incorporate miscellaneous Asc Library bug fixes and new microcode.
394 
395      1.7 (9/25/96):
396          1. Enable clustering and optimize the setting of the maximum number
397             of scatter gather elements for any particular board. Clustering
398             increases CPU utilization, but results in a relatively larger
399             increase in I/O throughput.
400          2. Improve the performance of the request queuing functions by
401             adding a last pointer to the queue structure.
402          3. Correct problems with reset and abort request handling that
403             could have hung or crashed Linux.
404          4. Add more information to the adapter /proc file:
405             /proc/scsi/advansys[0...].
406          5. Remove the request timeout issue form the driver issues list.
407          6. Miscellaneous documentation additions and changes.
408 
409      1.8 (10/4/96):
410          1. Make changes to handle the new v2.1.0 kernel memory mapping
411             in which a kernel virtual address may not be equivalent to its
412             bus or DMA memory address.
413          2. Change abort and reset request handling to make it yet even
414             more robust.
415          3. Try to mitigate request starvation by sending ordered requests
416             to heavily loaded, tag queuing enabled devices.
417          4. Maintain statistics on request response time.
418          5. Add request response time statistics and other information to
419             the adapter /proc file: /proc/scsi/advansys[0...].
420 
421      1.9 (10/21/96):
422          1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to
423             make use of mid-level SCSI driver device queue depth flow
424             control mechanism. This will eliminate aborts caused by a
425             device being unable to keep up with requests and eliminate
426             repeat busy or QUEUE FULL status returned by a device.
427          2. Incorporate miscellaneous Asc Library bug fixes.
428          3. To allow the driver to work in kernels with broken module
429             support set 'cmd_per_lun' if the driver is compiled as a
430             module. This change affects kernels v1.3.89 to present.
431          4. Remove PCI BIOS address from the driver banner. The PCI BIOS
432             is relocated by the motherboard BIOS and its new address can
433             not be determined by the driver.
434          5. Add mid-level SCSI queue depth information to the adapter
435             /proc file: /proc/scsi/advansys[0...].
436 
437      2.0 (11/14/96):
438          1. Change allocation of global structures used for device
439             initialization to guarantee they are in DMA-able memory.
440             Previously when the driver was loaded as a module these
441             structures might not have been in DMA-able memory, causing
442             device initialization to fail.
443 
444      2.1 (12/30/96):
445          1. In advansys_reset(), if the request is a synchronous reset
446             request, even if the request serial number has changed, then
447             complete the request.
448          2. Add Asc Library bug fixes including new microcode.
449          3. Clear inquiry buffer before using it.
450          4. Correct ifdef typo.
451 
452      2.2 (1/15/97):
453          1. Add Asc Library bug fixes including new microcode.
454          2. Add synchronous data transfer rate information to the
455             adapter /proc file: /proc/scsi/advansys[0...].
456          3. Change ADVANSYS_DEBUG to be disabled by default. This
457             will reduce the size of the driver image, eliminate execution
458             overhead, and remove unneeded symbols from the kernel symbol
459             space that were previously added by the driver.
460          4. Add new compile-time option ADVANSYS_ASSERT for assertion
461             code that used to be defined within ADVANSYS_DEBUG. This
462             option is enabled by default.
463 
464      2.8 (5/26/97):
465          1. Change version number to 2.8 to synchronize the Linux driver
466             version numbering with other AdvanSys drivers.
467          2. Reformat source files without tabs to present the same view
468             of the file to everyone regardless of the editor tab setting
469             being used.
470          3. Add Asc Library bug fixes.
471 
472      3.1A (1/8/98):
473          1. Change version number to 3.1 to indicate that support for
474             Ultra-Wide adapters (ABP-940UW) is included in this release.
475          2. Add Asc Library (Narrow Board) bug fixes.
476          3. Report an underrun condition with the host status byte set
477             to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which
478             causes the underrun condition to be ignored. When Linux defines
479             its own DID_UNDERRUN the constant defined in this file can be
480             removed.
481          4. Add patch to AscWaitTixISRDone().
482          5. Add support for up to 16 different AdvanSys host adapter SCSI
483             channels in one system. This allows four cards with four channels
484             to be used in one system.
485 
486      3.1B (1/9/98):
487          1. Handle that PCI register base addresses are not always page
488             aligned even though ioremap() requires that the address argument
489             be page aligned.
490 
491      3.1C (1/10/98):
492          1. Update latest BIOS version checked for from the /proc file.
493          2. Don't set microcode SDTR variable at initialization. Instead
494             wait until device capabilities have been detected from an Inquiry
495             command.
496 
497      3.1D (1/21/98):
498          1. Improve performance when the driver is compiled as module by
499             allowing up to 64 scatter-gather elements instead of 8.
500 
501      3.1E (5/1/98):
502          1. Set time delay in AscWaitTixISRDone() to 1000 ms.
503          2. Include SMP locking changes.
504          3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS
505             access functions.
506          4. Update board serial number printing.
507          5. Try allocating an IRQ both with and without the IRQF_DISABLED
508             flag set to allow IRQ sharing with drivers that do not set
509             the IRQF_DISABLED flag. Also display a more descriptive error
510             message if request_irq() fails.
511          6. Update to latest Asc and Adv Libraries.
512 
513      3.2A (7/22/99):
514          1. Update Adv Library to 4.16 which includes support for
515             the ASC38C0800 (Ultra2/LVD) IC.
516 
517      3.2B (8/23/99):
518          1. Correct PCI compile time option for v2.1.93 and greater
519             kernels, advansys_info() string, and debug compile time
520             option.
521          2. Correct DvcSleepMilliSecond() for v2.1.0 and greater
522             kernels. This caused an LVD detection/BIST problem problem
523             among other things.
524          3. Sort PCI cards by PCI Bus, Slot, Function ascending order
525             to be consistent with the BIOS.
526          4. Update to Asc Library S121 and Adv Library 5.2.
527 
528      3.2C (8/24/99):
529          1. Correct PCI card detection bug introduced in 3.2B that
530             prevented PCI cards from being detected in kernels older
531             than v2.1.93.
532 
533      3.2D (8/26/99):
534          1. Correct /proc device synchronous speed information display.
535             Also when re-negotiation is pending for a target device
536             note this condition with an * and footnote.
537          2. Correct initialization problem with Ultra-Wide cards that
538             have a pre-3.2 BIOS. A microcode variable changed locations
539             in 3.2 and greater BIOSes which caused WDTR to be attempted
540             erroneously with drives that don't support WDTR.
541 
542      3.2E (8/30/99):
543          1. Fix compile error caused by v2.3.13 PCI structure change.
544          2. Remove field from ASCEEP_CONFIG that resulted in an EEPROM
545             checksum error for ISA cards.
546          3. Remove ASC_QUEUE_FLOW_CONTROL conditional code. The mid-level
547             SCSI changes that it depended on were never included in Linux.
548 
549      3.2F (9/3/99):
550          1. Handle new initial function code added in v2.3.16 for all
551             driver versions.
552 
553      3.2G (9/8/99):
554          1. Fix PCI board detection in v2.3.13 and greater kernels.
555          2. Fix comiple errors in v2.3.X with debugging enabled.
556 
557      3.2H (9/13/99):
558          1. Add 64-bit address, long support for Alpha and UltraSPARC.
559             The driver has been verified to work on an Alpha system.
560          2. Add partial byte order handling support for Power PC and
561             other big-endian platforms. This support has not yet been
562             completed or verified.
563          3. For wide boards replace block zeroing of request and
564             scatter-gather structures with individual field initialization
565             to improve performance.
566          4. Correct and clarify ROM BIOS version detection.
567 
568      3.2I (10/8/99):
569          1. Update to Adv Library 5.4.
570          2. Add v2.3.19 underrun reporting to asc_isr_callback() and
571             adv_isr_callback().  Remove DID_UNDERRUN constant and other
572             no longer needed code that previously documented the lack
573             of underrun handling.
574 
575      3.2J (10/14/99):
576          1. Eliminate compile errors for v2.0 and earlier kernels.
577 
578      3.2K (11/15/99):
579          1. Correct debug compile error in asc_prt_adv_scsi_req_q().
580          2. Update Adv Library to 5.5.
581          3. Add ifdef handling for /proc changes added in v2.3.28.
582          4. Increase Wide board scatter-gather list maximum length to
583             255 when the driver is compiled into the kernel.
584 
585      3.2L (11/18/99):
586          1. Fix bug in adv_get_sglist() that caused an assertion failure
587             at line 7475. The reqp->sgblkp pointer must be initialized
588             to NULL in adv_get_sglist().
589 
590      3.2M (11/29/99):
591          1. Really fix bug in adv_get_sglist().
592          2. Incorporate v2.3.29 changes into driver.
593 
594      3.2N (4/1/00):
595          1. Add CONFIG_ISA ifdef code.
596          2. Include advansys_interrupts_enabled name change patch.
597          3. For >= v2.3.28 use new SCSI error handling with new function
598             advansys_eh_bus_reset(). Don't include an abort function
599             because of base library limitations.
600          4. For >= v2.3.28 use per board lock instead of io_request_lock.
601          5. For >= v2.3.28 eliminate advansys_command() and
602             advansys_command_done().
603          6. Add some changes for PowerPC (Big Endian) support, but it isn't
604             working yet.
605          7. Fix "nonexistent resource free" problem that occurred on a module
606             unload for boards with an I/O space >= 255. The 'n_io_port' field
607             is only one byte and can not be used to hold an ioport length more
608             than 255.
609 
610      3.3A (4/4/00):
611          1. Update to Adv Library 5.8.
612          2. For wide cards add support for CDBs up to 16 bytes.
613          3. Eliminate warnings when CONFIG_PROC_FS is not defined.
614 
615      3.3B (5/1/00):
616          1. Support for PowerPC (Big Endian) wide cards. Narrow cards
617             still need work.
618          2. Change bitfields to shift and mask access for endian
619             portability.
620 
621      3.3C (10/13/00):
622          1. Update for latest 2.4 kernel.
623          2. Test ABP-480 CardBus support in 2.4 kernel - works!
624          3. Update to Asc Library S123.
625          4. Update to Adv Library 5.12.
626 
627      3.3D (11/22/00):
628          1. Update for latest 2.4 kernel.
629          2. Create patches for 2.2 and 2.4 kernels.
630 
631      3.3E (1/9/01):
632          1. Now that 2.4 is released remove ifdef code for kernel versions
633             less than 2.2. The driver is now only supported in kernels 2.2,
634             2.4, and greater.
635          2. Add code to release and acquire the io_request_lock in
636             the driver entrypoint functions: advansys_detect and
637             advansys_queuecommand. In kernel 2.4 the SCSI mid-level driver
638             still holds the io_request_lock on entry to SCSI low-level drivers.
639             This was supposed to be removed before 2.4 was released but never
640             happened. When the mid-level SCSI driver is changed all references
641             to the io_request_lock should be removed from the driver.
642          3. Simplify error handling by removing advansys_abort(),
643             AscAbortSRB(), AscResetDevice(). SCSI bus reset requests are
644             now handled by resetting the SCSI bus and fully re-initializing
645             the chip. This simple method of error recovery has proven to work
646             most reliably after attempts at different methods. Also now only
647             support the "new" error handling method and remove the obsolete
648             error handling interface.
649          4. Fix debug build errors.
650 
651      3.3F (1/24/01):
652          1. Merge with ConnectCom version from Andy Kellner which
653             updates Adv Library to 5.14.
654          2. Make PowerPC (Big Endian) work for narrow cards and
655             fix problems writing EEPROM for wide cards.
656          3. Remove interrupts_enabled assertion function.
657 
658      3.3G (2/16/01):
659          1. Return an error from narrow boards if passed a 16 byte
660             CDB. The wide board can already handle 16 byte CDBs.
661 
662      3.3GJ (4/15/02):
663 	 1. hacks for lk 2.5 series (D. Gilbert)
664 
665      3.3GJD (10/14/02):
666          1. change select_queue_depths to slave_configure
667 	 2. make cmd_per_lun be sane again
668 
669      3.3K [2004/06/24]:
670          1. continuing cleanup for lk 2.6 series
671          2. Fix problem in lk 2.6.7-bk2 that broke PCI wide cards
672          3. Fix problem that oopsed ISA cards
673 
674   I. Known Problems/Fix List (XXX)
675 
676      1. Need to add memory mapping workaround. Test the memory mapping.
677         If it doesn't work revert to I/O port access. Can a test be done
678         safely?
679      2. Handle an interrupt not working. Keep an interrupt counter in
680         the interrupt handler. In the timeout function if the interrupt
681         has not occurred then print a message and run in polled mode.
682      3. Allow bus type scanning order to be changed.
683      4. Need to add support for target mode commands, cf. CAM XPT.
684 
685   J. Credits (Chronological Order)
686 
687      Bob Frey <bfrey@turbolinux.com.cn> wrote the AdvanSys SCSI driver
688      and maintained it up to 3.3F. He continues to answer questions
689      and help maintain the driver.
690 
691      Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and
692      basis for the Linux v1.3.X changes which were included in the
693      1.2 release.
694 
695      Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug
696      in advansys_biosparam() which was fixed in the 1.3 release.
697 
698      Erik Ratcliffe <erik@caldera.com> has done testing of the
699      AdvanSys driver in the Caldera releases.
700 
701      Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to
702      AscWaitTixISRDone() which he found necessary to make the
703      driver work with a SCSI-1 disk.
704 
705      Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide
706      support in the 3.1A driver.
707 
708      Doug Gilbert <dgilbert@interlog.com> has made changes and
709      suggestions to improve the driver and done a lot of testing.
710 
711      Ken Mort <ken@mort.net> reported a DEBUG compile bug fixed
712      in 3.2K.
713 
714      Tom Rini <trini@kernel.crashing.org> provided the CONFIG_ISA
715      patch and helped with PowerPC wide and narrow board support.
716 
717      Philip Blundell <philb@gnu.org> provided an
718      advansys_interrupts_enabled patch.
719 
720      Dave Jones <dave@denial.force9.co.uk> reported the compiler
721      warnings generated when CONFIG_PROC_FS was not defined in
722      the 3.2M driver.
723 
724      Jerry Quinn <jlquinn@us.ibm.com> fixed PowerPC support (endian
725      problems) for wide cards.
726 
727      Bryan Henderson <bryanh@giraffe-data.com> helped debug narrow
728      card error handling.
729 
730      Manuel Veloso <veloso@pobox.com> worked hard on PowerPC narrow
731      board support and fixed a bug in AscGetEEPConfig().
732 
733      Arnaldo Carvalho de Melo <acme@conectiva.com.br> made
734      save_flags/restore_flags changes.
735 
736      Andy Kellner <AKellner@connectcom.net> continues the Advansys SCSI
737      driver development for ConnectCom (Version > 3.3F).
738 
739   K. ConnectCom (AdvanSys) Contact Information
740 
741      Mail:                   ConnectCom Solutions, Inc.
742                              1150 Ringwood Court
743                              San Jose, CA 95131
744      Operator/Sales:         1-408-383-9400
745      FAX:                    1-408-383-9612
746      Tech Support:           1-408-467-2930
747      Tech Support E-Mail:    linux@connectcom.net
748      FTP Site:               ftp.connectcom.net (login: anonymous)
749      Web Site:               http://www.connectcom.net
750 
751 */
752 
753 /*
754  * --- Linux Include Files
755  */
756 
757 #include <linux/module.h>
758 
759 #if defined(CONFIG_X86) && !defined(CONFIG_ISA)
760 #define CONFIG_ISA
761 #endif /* CONFIG_X86 && !CONFIG_ISA */
762 
763 #include <linux/string.h>
764 #include <linux/kernel.h>
765 #include <linux/types.h>
766 #include <linux/ioport.h>
767 #include <linux/interrupt.h>
768 #include <linux/delay.h>
769 #include <linux/slab.h>
770 #include <linux/mm.h>
771 #include <linux/proc_fs.h>
772 #include <linux/init.h>
773 #include <linux/blkdev.h>
774 #include <linux/stat.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 /* FIXME: (by jejb@steeleye.com) This warning is present for two
783  * reasons:
784  *
785  * 1) This driver badly needs converting to the correct driver model
786  *    probing API
787  *
788  * 2) Although all of the necessary command mapping places have the
789  * appropriate dma_map.. APIs, the driver still processes its internal
790  * queue using bus_to_virt() and virt_to_bus() which are illegal under
791  * the API.  The entire queue processing structure will need to be
792  * altered to fix this.
793  */
794 #warning this driver is still not properly converted to the DMA API
795 
796 #include <scsi/scsi_cmnd.h>
797 #include <scsi/scsi_device.h>
798 #include <scsi/scsi_tcq.h>
799 #include <scsi/scsi.h>
800 #include <scsi/scsi_host.h>
801 #ifdef CONFIG_PCI
802 #include <linux/pci.h>
803 #endif /* CONFIG_PCI */
804 
805 /*
806  * --- Driver Options
807  */
808 
809 /* Enable driver assertions. */
810 #define ADVANSYS_ASSERT
811 
812 /* Enable driver /proc statistics. */
813 #define ADVANSYS_STATS
814 
815 /* Enable driver tracing. */
816 /* #define ADVANSYS_DEBUG */
817 
818 /*
819  * --- Asc Library Constants and Macros
820  */
821 
822 #define ASC_LIB_VERSION_MAJOR  1
823 #define ASC_LIB_VERSION_MINOR  24
824 #define ASC_LIB_SERIAL_NUMBER  123
825 
826 /*
827  * Portable Data Types
828  *
829  * Any instance where a 32-bit long or pointer type is assumed
830  * for precision or HW defined structures, the following define
831  * types must be used. In Linux the char, short, and int types
832  * are all consistent at 8, 16, and 32 bits respectively. Pointers
833  * and long types are 64 bits on Alpha and UltraSPARC.
834  */
835 #define ASC_PADDR __u32		/* Physical/Bus address data type. */
836 #define ASC_VADDR __u32		/* Virtual address data type. */
837 #define ASC_DCNT  __u32		/* Unsigned Data count type. */
838 #define ASC_SDCNT __s32		/* Signed Data count type. */
839 
840 /*
841  * These macros are used to convert a virtual address to a
842  * 32-bit value. This currently can be used on Linux Alpha
843  * which uses 64-bit virtual address but a 32-bit bus address.
844  * This is likely to break in the future, but doing this now
845  * will give us time to change the HW and FW to handle 64-bit
846  * addresses.
847  */
848 #define ASC_VADDR_TO_U32   virt_to_bus
849 #define ASC_U32_TO_VADDR   bus_to_virt
850 
851 typedef unsigned char uchar;
852 
853 #ifndef TRUE
854 #define TRUE     (1)
855 #endif
856 #ifndef FALSE
857 #define FALSE    (0)
858 #endif
859 
860 #define EOF      (-1)
861 #define ERR      (-1)
862 #define UW_ERR   (uint)(0xFFFF)
863 #define isodd_word(val)   ((((uint)val) & (uint)0x0001) != 0)
864 #define AscPCIConfigVendorIDRegister      0x0000
865 #define AscPCIConfigDeviceIDRegister      0x0002
866 #define AscPCIConfigCommandRegister       0x0004
867 #define AscPCIConfigStatusRegister        0x0006
868 #define AscPCIConfigRevisionIDRegister    0x0008
869 #define AscPCIConfigCacheSize             0x000C
870 #define AscPCIConfigLatencyTimer          0x000D
871 #define AscPCIIOBaseRegister              0x0010
872 #define AscPCICmdRegBits_IOMemBusMaster   0x0007
873 #define ASC_PCI_ID2BUS(id)    ((id) & 0xFF)
874 #define ASC_PCI_ID2DEV(id)    (((id) >> 11) & 0x1F)
875 #define ASC_PCI_ID2FUNC(id)   (((id) >> 8) & 0x7)
876 #define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
877 #define ASC_PCI_REVISION_3150             0x02
878 #define ASC_PCI_REVISION_3050             0x03
879 
880 #define  ASC_DVCLIB_CALL_DONE     (1)
881 #define  ASC_DVCLIB_CALL_FAILED   (0)
882 #define  ASC_DVCLIB_CALL_ERROR    (-1)
883 
884 #define PCI_VENDOR_ID_ASP		0x10cd
885 #define PCI_DEVICE_ID_ASP_1200A		0x1100
886 #define PCI_DEVICE_ID_ASP_ABP940	0x1200
887 #define PCI_DEVICE_ID_ASP_ABP940U	0x1300
888 #define PCI_DEVICE_ID_ASP_ABP940UW	0x2300
889 #define PCI_DEVICE_ID_38C0800_REV1	0x2500
890 #define PCI_DEVICE_ID_38C1600_REV1	0x2700
891 
892 /*
893  * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
894  * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
895  * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
896  * SRB structure.
897  */
898 #define CC_VERY_LONG_SG_LIST 0
899 #define ASC_SRB2SCSIQ(srb_ptr)  (srb_ptr)
900 
901 #define PortAddr                 unsigned short	/* port address size  */
902 #define inp(port)                inb(port)
903 #define outp(port, byte)         outb((byte), (port))
904 
905 #define inpw(port)               inw(port)
906 #define outpw(port, word)        outw((word), (port))
907 
908 #define ASC_MAX_SG_QUEUE    7
909 #define ASC_MAX_SG_LIST     255
910 
911 #define ASC_CS_TYPE  unsigned short
912 
913 #define ASC_IS_ISA          (0x0001)
914 #define ASC_IS_ISAPNP       (0x0081)
915 #define ASC_IS_EISA         (0x0002)
916 #define ASC_IS_PCI          (0x0004)
917 #define ASC_IS_PCI_ULTRA    (0x0104)
918 #define ASC_IS_PCMCIA       (0x0008)
919 #define ASC_IS_MCA          (0x0020)
920 #define ASC_IS_VL           (0x0040)
921 #define ASC_ISA_PNP_PORT_ADDR  (0x279)
922 #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
923 #define ASC_IS_WIDESCSI_16  (0x0100)
924 #define ASC_IS_WIDESCSI_32  (0x0200)
925 #define ASC_IS_BIG_ENDIAN   (0x8000)
926 #define ASC_CHIP_MIN_VER_VL      (0x01)
927 #define ASC_CHIP_MAX_VER_VL      (0x07)
928 #define ASC_CHIP_MIN_VER_PCI     (0x09)
929 #define ASC_CHIP_MAX_VER_PCI     (0x0F)
930 #define ASC_CHIP_VER_PCI_BIT     (0x08)
931 #define ASC_CHIP_MIN_VER_ISA     (0x11)
932 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
933 #define ASC_CHIP_MAX_VER_ISA     (0x27)
934 #define ASC_CHIP_VER_ISA_BIT     (0x30)
935 #define ASC_CHIP_VER_ISAPNP_BIT  (0x20)
936 #define ASC_CHIP_VER_ASYN_BUG    (0x21)
937 #define ASC_CHIP_VER_PCI             0x08
938 #define ASC_CHIP_VER_PCI_ULTRA_3150  (ASC_CHIP_VER_PCI | 0x02)
939 #define ASC_CHIP_VER_PCI_ULTRA_3050  (ASC_CHIP_VER_PCI | 0x03)
940 #define ASC_CHIP_MIN_VER_EISA (0x41)
941 #define ASC_CHIP_MAX_VER_EISA (0x47)
942 #define ASC_CHIP_VER_EISA_BIT (0x40)
943 #define ASC_CHIP_LATEST_VER_EISA   ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
944 #define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER   0x21
945 #define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER   0x0A
946 #define ASC_MAX_VL_DMA_ADDR     (0x07FFFFFFL)
947 #define ASC_MAX_VL_DMA_COUNT    (0x07FFFFFFL)
948 #define ASC_MAX_PCI_DMA_ADDR    (0xFFFFFFFFL)
949 #define ASC_MAX_PCI_DMA_COUNT   (0xFFFFFFFFL)
950 #define ASC_MAX_ISA_DMA_ADDR    (0x00FFFFFFL)
951 #define ASC_MAX_ISA_DMA_COUNT   (0x00FFFFFFL)
952 #define ASC_MAX_EISA_DMA_ADDR   (0x07FFFFFFL)
953 #define ASC_MAX_EISA_DMA_COUNT  (0x07FFFFFFL)
954 
955 #define ASC_SCSI_ID_BITS  3
956 #define ASC_SCSI_TIX_TYPE     uchar
957 #define ASC_ALL_DEVICE_BIT_SET  0xFF
958 #define ASC_SCSI_BIT_ID_TYPE  uchar
959 #define ASC_MAX_TID       7
960 #define ASC_MAX_LUN       7
961 #define ASC_SCSI_WIDTH_BIT_SET  0xFF
962 #define ASC_MAX_SENSE_LEN   32
963 #define ASC_MIN_SENSE_LEN   14
964 #define ASC_MAX_CDB_LEN     12
965 #define ASC_SCSI_RESET_HOLD_TIME_US  60
966 
967 #define ADV_INQ_CLOCKING_ST_ONLY    0x0
968 #define ADV_INQ_CLOCKING_DT_ONLY    0x1
969 #define ADV_INQ_CLOCKING_ST_AND_DT  0x3
970 
971 /*
972  * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
973  * and CmdDt (Command Support Data) field bit definitions.
974  */
975 #define ADV_INQ_RTN_VPD_AND_CMDDT           0x3
976 #define ADV_INQ_RTN_CMDDT_FOR_OP_CODE       0x2
977 #define ADV_INQ_RTN_VPD_FOR_PG_CODE         0x1
978 #define ADV_INQ_RTN_STD_INQUIRY_DATA        0x0
979 
980 #define ASC_SCSIDIR_NOCHK    0x00
981 #define ASC_SCSIDIR_T2H      0x08
982 #define ASC_SCSIDIR_H2T      0x10
983 #define ASC_SCSIDIR_NODATA   0x18
984 #define SCSI_ASC_NOMEDIA          0x3A
985 #define ASC_SRB_HOST(x)  ((uchar)((uchar)(x) >> 4))
986 #define ASC_SRB_TID(x)   ((uchar)((uchar)(x) & (uchar)0x0F))
987 #define ASC_SRB_LUN(x)   ((uchar)((uint)(x) >> 13))
988 #define PUT_CDB1(x)   ((uchar)((uint)(x) >> 8))
989 #define MS_CMD_DONE    0x00
990 #define MS_EXTEND      0x01
991 #define MS_SDTR_LEN    0x03
992 #define MS_SDTR_CODE   0x01
993 #define MS_WDTR_LEN    0x02
994 #define MS_WDTR_CODE   0x03
995 #define MS_MDP_LEN    0x05
996 #define MS_MDP_CODE   0x00
997 
998 /*
999  * Inquiry data structure and bitfield macros
1000  *
1001  * Only quantities of more than 1 bit are shifted, since the others are
1002  * just tested for true or false. C bitfields aren't portable between big
1003  * and little-endian platforms so they are not used.
1004  */
1005 
1006 #define ASC_INQ_DVC_TYPE(inq)       ((inq)->periph & 0x1f)
1007 #define ASC_INQ_QUALIFIER(inq)      (((inq)->periph & 0xe0) >> 5)
1008 #define ASC_INQ_DVC_TYPE_MOD(inq)   ((inq)->devtype & 0x7f)
1009 #define ASC_INQ_REMOVABLE(inq)      ((inq)->devtype & 0x80)
1010 #define ASC_INQ_ANSI_VER(inq)       ((inq)->ver & 0x07)
1011 #define ASC_INQ_ECMA_VER(inq)       (((inq)->ver & 0x38) >> 3)
1012 #define ASC_INQ_ISO_VER(inq)        (((inq)->ver & 0xc0) >> 6)
1013 #define ASC_INQ_RESPONSE_FMT(inq)   ((inq)->byte3 & 0x0f)
1014 #define ASC_INQ_TERM_IO(inq)        ((inq)->byte3 & 0x40)
1015 #define ASC_INQ_ASYNC_NOTIF(inq)    ((inq)->byte3 & 0x80)
1016 #define ASC_INQ_SOFT_RESET(inq)     ((inq)->flags & 0x01)
1017 #define ASC_INQ_CMD_QUEUE(inq)      ((inq)->flags & 0x02)
1018 #define ASC_INQ_LINK_CMD(inq)       ((inq)->flags & 0x08)
1019 #define ASC_INQ_SYNC(inq)           ((inq)->flags & 0x10)
1020 #define ASC_INQ_WIDE16(inq)         ((inq)->flags & 0x20)
1021 #define ASC_INQ_WIDE32(inq)         ((inq)->flags & 0x40)
1022 #define ASC_INQ_REL_ADDR(inq)       ((inq)->flags & 0x80)
1023 #define ASC_INQ_INFO_UNIT(inq)      ((inq)->info & 0x01)
1024 #define ASC_INQ_QUICK_ARB(inq)      ((inq)->info & 0x02)
1025 #define ASC_INQ_CLOCKING(inq)       (((inq)->info & 0x0c) >> 2)
1026 
1027 typedef struct {
1028 	uchar periph;
1029 	uchar devtype;
1030 	uchar ver;
1031 	uchar byte3;
1032 	uchar add_len;
1033 	uchar res1;
1034 	uchar res2;
1035 	uchar flags;
1036 	uchar vendor_id[8];
1037 	uchar product_id[16];
1038 	uchar product_rev_level[4];
1039 } ASC_SCSI_INQUIRY;
1040 
1041 #define ASC_SG_LIST_PER_Q   7
1042 #define QS_FREE        0x00
1043 #define QS_READY       0x01
1044 #define QS_DISC1       0x02
1045 #define QS_DISC2       0x04
1046 #define QS_BUSY        0x08
1047 #define QS_ABORTED     0x40
1048 #define QS_DONE        0x80
1049 #define QC_NO_CALLBACK   0x01
1050 #define QC_SG_SWAP_QUEUE 0x02
1051 #define QC_SG_HEAD       0x04
1052 #define QC_DATA_IN       0x08
1053 #define QC_DATA_OUT      0x10
1054 #define QC_URGENT        0x20
1055 #define QC_MSG_OUT       0x40
1056 #define QC_REQ_SENSE     0x80
1057 #define QCSG_SG_XFER_LIST  0x02
1058 #define QCSG_SG_XFER_MORE  0x04
1059 #define QCSG_SG_XFER_END   0x08
1060 #define QD_IN_PROGRESS       0x00
1061 #define QD_NO_ERROR          0x01
1062 #define QD_ABORTED_BY_HOST   0x02
1063 #define QD_WITH_ERROR        0x04
1064 #define QD_INVALID_REQUEST   0x80
1065 #define QD_INVALID_HOST_NUM  0x81
1066 #define QD_INVALID_DEVICE    0x82
1067 #define QD_ERR_INTERNAL      0xFF
1068 #define QHSTA_NO_ERROR               0x00
1069 #define QHSTA_M_SEL_TIMEOUT          0x11
1070 #define QHSTA_M_DATA_OVER_RUN        0x12
1071 #define QHSTA_M_DATA_UNDER_RUN       0x12
1072 #define QHSTA_M_UNEXPECTED_BUS_FREE  0x13
1073 #define QHSTA_M_BAD_BUS_PHASE_SEQ    0x14
1074 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1075 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET  0x22
1076 #define QHSTA_D_HOST_ABORT_FAILED       0x23
1077 #define QHSTA_D_EXE_SCSI_Q_FAILED       0x24
1078 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1079 #define QHSTA_D_ASPI_NO_BUF_POOL        0x26
1080 #define QHSTA_M_WTM_TIMEOUT         0x41
1081 #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
1082 #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
1083 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1084 #define QHSTA_M_TARGET_STATUS_BUSY  0x45
1085 #define QHSTA_M_BAD_TAG_CODE        0x46
1086 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY  0x47
1087 #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1088 #define QHSTA_D_LRAM_CMP_ERROR        0x81
1089 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1090 #define ASC_FLAG_SCSIQ_REQ        0x01
1091 #define ASC_FLAG_BIOS_SCSIQ_REQ   0x02
1092 #define ASC_FLAG_BIOS_ASYNC_IO    0x04
1093 #define ASC_FLAG_SRB_LINEAR_ADDR  0x08
1094 #define ASC_FLAG_WIN16            0x10
1095 #define ASC_FLAG_WIN32            0x20
1096 #define ASC_FLAG_ISA_OVER_16MB    0x40
1097 #define ASC_FLAG_DOS_VM_CALLBACK  0x80
1098 #define ASC_TAG_FLAG_EXTRA_BYTES               0x10
1099 #define ASC_TAG_FLAG_DISABLE_DISCONNECT        0x04
1100 #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX  0x08
1101 #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1102 #define ASC_SCSIQ_CPY_BEG              4
1103 #define ASC_SCSIQ_SGHD_CPY_BEG         2
1104 #define ASC_SCSIQ_B_FWD                0
1105 #define ASC_SCSIQ_B_BWD                1
1106 #define ASC_SCSIQ_B_STATUS             2
1107 #define ASC_SCSIQ_B_QNO                3
1108 #define ASC_SCSIQ_B_CNTL               4
1109 #define ASC_SCSIQ_B_SG_QUEUE_CNT       5
1110 #define ASC_SCSIQ_D_DATA_ADDR          8
1111 #define ASC_SCSIQ_D_DATA_CNT          12
1112 #define ASC_SCSIQ_B_SENSE_LEN         20
1113 #define ASC_SCSIQ_DONE_INFO_BEG       22
1114 #define ASC_SCSIQ_D_SRBPTR            22
1115 #define ASC_SCSIQ_B_TARGET_IX         26
1116 #define ASC_SCSIQ_B_CDB_LEN           28
1117 #define ASC_SCSIQ_B_TAG_CODE          29
1118 #define ASC_SCSIQ_W_VM_ID             30
1119 #define ASC_SCSIQ_DONE_STATUS         32
1120 #define ASC_SCSIQ_HOST_STATUS         33
1121 #define ASC_SCSIQ_SCSI_STATUS         34
1122 #define ASC_SCSIQ_CDB_BEG             36
1123 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1124 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT  60
1125 #define ASC_SCSIQ_B_FIRST_SG_WK_QP    48
1126 #define ASC_SCSIQ_B_SG_WK_QP          49
1127 #define ASC_SCSIQ_B_SG_WK_IX          50
1128 #define ASC_SCSIQ_W_ALT_DC1           52
1129 #define ASC_SCSIQ_B_LIST_CNT          6
1130 #define ASC_SCSIQ_B_CUR_LIST_CNT      7
1131 #define ASC_SGQ_B_SG_CNTL             4
1132 #define ASC_SGQ_B_SG_HEAD_QP          5
1133 #define ASC_SGQ_B_SG_LIST_CNT         6
1134 #define ASC_SGQ_B_SG_CUR_LIST_CNT     7
1135 #define ASC_SGQ_LIST_BEG              8
1136 #define ASC_DEF_SCSI1_QNG    4
1137 #define ASC_MAX_SCSI1_QNG    4
1138 #define ASC_DEF_SCSI2_QNG    16
1139 #define ASC_MAX_SCSI2_QNG    32
1140 #define ASC_TAG_CODE_MASK    0x23
1141 #define ASC_STOP_REQ_RISC_STOP      0x01
1142 #define ASC_STOP_ACK_RISC_STOP      0x03
1143 #define ASC_STOP_CLEAN_UP_BUSY_Q    0x10
1144 #define ASC_STOP_CLEAN_UP_DISC_Q    0x20
1145 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1146 #define ASC_TIDLUN_TO_IX(tid, lun)  (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1147 #define ASC_TID_TO_TARGET_ID(tid)   (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1148 #define ASC_TIX_TO_TARGET_ID(tix)   (0x01 << ((tix) & ASC_MAX_TID))
1149 #define ASC_TIX_TO_TID(tix)         ((tix) & ASC_MAX_TID)
1150 #define ASC_TID_TO_TIX(tid)         ((tid) & ASC_MAX_TID)
1151 #define ASC_TIX_TO_LUN(tix)         (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1152 #define ASC_QNO_TO_QADDR(q_no)      ((ASC_QADR_BEG)+((int)(q_no) << 6))
1153 
1154 typedef struct asc_scsiq_1 {
1155 	uchar status;
1156 	uchar q_no;
1157 	uchar cntl;
1158 	uchar sg_queue_cnt;
1159 	uchar target_id;
1160 	uchar target_lun;
1161 	ASC_PADDR data_addr;
1162 	ASC_DCNT data_cnt;
1163 	ASC_PADDR sense_addr;
1164 	uchar sense_len;
1165 	uchar extra_bytes;
1166 } ASC_SCSIQ_1;
1167 
1168 typedef struct asc_scsiq_2 {
1169 	ASC_VADDR srb_ptr;
1170 	uchar target_ix;
1171 	uchar flag;
1172 	uchar cdb_len;
1173 	uchar tag_code;
1174 	ushort vm_id;
1175 } ASC_SCSIQ_2;
1176 
1177 typedef struct asc_scsiq_3 {
1178 	uchar done_stat;
1179 	uchar host_stat;
1180 	uchar scsi_stat;
1181 	uchar scsi_msg;
1182 } ASC_SCSIQ_3;
1183 
1184 typedef struct asc_scsiq_4 {
1185 	uchar cdb[ASC_MAX_CDB_LEN];
1186 	uchar y_first_sg_list_qp;
1187 	uchar y_working_sg_qp;
1188 	uchar y_working_sg_ix;
1189 	uchar y_res;
1190 	ushort x_req_count;
1191 	ushort x_reconnect_rtn;
1192 	ASC_PADDR x_saved_data_addr;
1193 	ASC_DCNT x_saved_data_cnt;
1194 } ASC_SCSIQ_4;
1195 
1196 typedef struct asc_q_done_info {
1197 	ASC_SCSIQ_2 d2;
1198 	ASC_SCSIQ_3 d3;
1199 	uchar q_status;
1200 	uchar q_no;
1201 	uchar cntl;
1202 	uchar sense_len;
1203 	uchar extra_bytes;
1204 	uchar res;
1205 	ASC_DCNT remain_bytes;
1206 } ASC_QDONE_INFO;
1207 
1208 typedef struct asc_sg_list {
1209 	ASC_PADDR addr;
1210 	ASC_DCNT bytes;
1211 } ASC_SG_LIST;
1212 
1213 typedef struct asc_sg_head {
1214 	ushort entry_cnt;
1215 	ushort queue_cnt;
1216 	ushort entry_to_copy;
1217 	ushort res;
1218 	ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1219 } ASC_SG_HEAD;
1220 
1221 #define ASC_MIN_SG_LIST   2
1222 
1223 typedef struct asc_min_sg_head {
1224 	ushort entry_cnt;
1225 	ushort queue_cnt;
1226 	ushort entry_to_copy;
1227 	ushort res;
1228 	ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
1229 } ASC_MIN_SG_HEAD;
1230 
1231 #define QCX_SORT        (0x0001)
1232 #define QCX_COALEASE    (0x0002)
1233 
1234 typedef struct asc_scsi_q {
1235 	ASC_SCSIQ_1 q1;
1236 	ASC_SCSIQ_2 q2;
1237 	uchar *cdbptr;
1238 	ASC_SG_HEAD *sg_head;
1239 	ushort remain_sg_entry_cnt;
1240 	ushort next_sg_index;
1241 } ASC_SCSI_Q;
1242 
1243 typedef struct asc_scsi_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_REQ_Q;
1253 
1254 typedef struct asc_scsi_bios_req_q {
1255 	ASC_SCSIQ_1 r1;
1256 	ASC_SCSIQ_2 r2;
1257 	uchar *cdbptr;
1258 	ASC_SG_HEAD *sg_head;
1259 	uchar *sense_ptr;
1260 	ASC_SCSIQ_3 r3;
1261 	uchar cdb[ASC_MAX_CDB_LEN];
1262 	uchar sense[ASC_MIN_SENSE_LEN];
1263 } ASC_SCSI_BIOS_REQ_Q;
1264 
1265 typedef struct asc_risc_q {
1266 	uchar fwd;
1267 	uchar bwd;
1268 	ASC_SCSIQ_1 i1;
1269 	ASC_SCSIQ_2 i2;
1270 	ASC_SCSIQ_3 i3;
1271 	ASC_SCSIQ_4 i4;
1272 } ASC_RISC_Q;
1273 
1274 typedef struct asc_sg_list_q {
1275 	uchar seq_no;
1276 	uchar q_no;
1277 	uchar cntl;
1278 	uchar sg_head_qp;
1279 	uchar sg_list_cnt;
1280 	uchar sg_cur_list_cnt;
1281 } ASC_SG_LIST_Q;
1282 
1283 typedef struct asc_risc_sg_list_q {
1284 	uchar fwd;
1285 	uchar bwd;
1286 	ASC_SG_LIST_Q sg;
1287 	ASC_SG_LIST sg_list[7];
1288 } ASC_RISC_SG_LIST_Q;
1289 
1290 #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP  0x1000000UL
1291 #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP  1024
1292 #define ASCQ_ERR_NO_ERROR             0
1293 #define ASCQ_ERR_IO_NOT_FOUND         1
1294 #define ASCQ_ERR_LOCAL_MEM            2
1295 #define ASCQ_ERR_CHKSUM               3
1296 #define ASCQ_ERR_START_CHIP           4
1297 #define ASCQ_ERR_INT_TARGET_ID        5
1298 #define ASCQ_ERR_INT_LOCAL_MEM        6
1299 #define ASCQ_ERR_HALT_RISC            7
1300 #define ASCQ_ERR_GET_ASPI_ENTRY       8
1301 #define ASCQ_ERR_CLOSE_ASPI           9
1302 #define ASCQ_ERR_HOST_INQUIRY         0x0A
1303 #define ASCQ_ERR_SAVED_SRB_BAD        0x0B
1304 #define ASCQ_ERR_QCNTL_SG_LIST        0x0C
1305 #define ASCQ_ERR_Q_STATUS             0x0D
1306 #define ASCQ_ERR_WR_SCSIQ             0x0E
1307 #define ASCQ_ERR_PC_ADDR              0x0F
1308 #define ASCQ_ERR_SYN_OFFSET           0x10
1309 #define ASCQ_ERR_SYN_XFER_TIME        0x11
1310 #define ASCQ_ERR_LOCK_DMA             0x12
1311 #define ASCQ_ERR_UNLOCK_DMA           0x13
1312 #define ASCQ_ERR_VDS_CHK_INSTALL      0x14
1313 #define ASCQ_ERR_MICRO_CODE_HALT      0x15
1314 #define ASCQ_ERR_SET_LRAM_ADDR        0x16
1315 #define ASCQ_ERR_CUR_QNG              0x17
1316 #define ASCQ_ERR_SG_Q_LINKS           0x18
1317 #define ASCQ_ERR_SCSIQ_PTR            0x19
1318 #define ASCQ_ERR_ISR_RE_ENTRY         0x1A
1319 #define ASCQ_ERR_CRITICAL_RE_ENTRY    0x1B
1320 #define ASCQ_ERR_ISR_ON_CRITICAL      0x1C
1321 #define ASCQ_ERR_SG_LIST_ODD_ADDRESS  0x1D
1322 #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1323 #define ASCQ_ERR_SCSIQ_NULL_PTR       0x1F
1324 #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR   0x20
1325 #define ASCQ_ERR_GET_NUM_OF_FREE_Q    0x21
1326 #define ASCQ_ERR_SEND_SCSI_Q          0x22
1327 #define ASCQ_ERR_HOST_REQ_RISC_HALT   0x23
1328 #define ASCQ_ERR_RESET_SDTR           0x24
1329 
1330 /*
1331  * Warning code values are set in ASC_DVC_VAR  'warn_code'.
1332  */
1333 #define ASC_WARN_NO_ERROR             0x0000
1334 #define ASC_WARN_IO_PORT_ROTATE       0x0001
1335 #define ASC_WARN_EEPROM_CHKSUM        0x0002
1336 #define ASC_WARN_IRQ_MODIFIED         0x0004
1337 #define ASC_WARN_AUTO_CONFIG          0x0008
1338 #define ASC_WARN_CMD_QNG_CONFLICT     0x0010
1339 #define ASC_WARN_EEPROM_RECOVER       0x0020
1340 #define ASC_WARN_CFG_MSW_RECOVER      0x0040
1341 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1342 
1343 /*
1344  * Error code values are set in ASC_DVC_VAR  'err_code'.
1345  */
1346 #define ASC_IERR_WRITE_EEPROM         0x0001
1347 #define ASC_IERR_MCODE_CHKSUM         0x0002
1348 #define ASC_IERR_SET_PC_ADDR          0x0004
1349 #define ASC_IERR_START_STOP_CHIP      0x0008
1350 #define ASC_IERR_IRQ_NO               0x0010
1351 #define ASC_IERR_SET_IRQ_NO           0x0020
1352 #define ASC_IERR_CHIP_VERSION         0x0040
1353 #define ASC_IERR_SET_SCSI_ID          0x0080
1354 #define ASC_IERR_GET_PHY_ADDR         0x0100
1355 #define ASC_IERR_BAD_SIGNATURE        0x0200
1356 #define ASC_IERR_NO_BUS_TYPE          0x0400
1357 #define ASC_IERR_SCAM                 0x0800
1358 #define ASC_IERR_SET_SDTR             0x1000
1359 #define ASC_IERR_RW_LRAM              0x8000
1360 
1361 #define ASC_DEF_IRQ_NO  10
1362 #define ASC_MAX_IRQ_NO  15
1363 #define ASC_MIN_IRQ_NO  10
1364 #define ASC_MIN_REMAIN_Q        (0x02)
1365 #define ASC_DEF_MAX_TOTAL_QNG   (0xF0)
1366 #define ASC_MIN_TAG_Q_PER_DVC   (0x04)
1367 #define ASC_DEF_TAG_Q_PER_DVC   (0x04)
1368 #define ASC_MIN_FREE_Q        ASC_MIN_REMAIN_Q
1369 #define ASC_MIN_TOTAL_QNG     ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1370 #define ASC_MAX_TOTAL_QNG 240
1371 #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1372 #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG   8
1373 #define ASC_MAX_PCI_INRAM_TOTAL_QNG  20
1374 #define ASC_MAX_INRAM_TAG_QNG   16
1375 #define ASC_IOADR_TABLE_MAX_IX  11
1376 #define ASC_IOADR_GAP   0x10
1377 #define ASC_SEARCH_IOP_GAP 0x10
1378 #define ASC_MIN_IOP_ADDR   (PortAddr)0x0100
1379 #define ASC_MAX_IOP_ADDR   (PortAddr)0x3F0
1380 #define ASC_IOADR_1     (PortAddr)0x0110
1381 #define ASC_IOADR_2     (PortAddr)0x0130
1382 #define ASC_IOADR_3     (PortAddr)0x0150
1383 #define ASC_IOADR_4     (PortAddr)0x0190
1384 #define ASC_IOADR_5     (PortAddr)0x0210
1385 #define ASC_IOADR_6     (PortAddr)0x0230
1386 #define ASC_IOADR_7     (PortAddr)0x0250
1387 #define ASC_IOADR_8     (PortAddr)0x0330
1388 #define ASC_IOADR_DEF   ASC_IOADR_8
1389 #define ASC_LIB_SCSIQ_WK_SP        256
1390 #define ASC_MAX_SYN_XFER_NO        16
1391 #define ASC_SYN_MAX_OFFSET         0x0F
1392 #define ASC_DEF_SDTR_OFFSET        0x0F
1393 #define ASC_DEF_SDTR_INDEX         0x00
1394 #define ASC_SDTR_ULTRA_PCI_10MB_INDEX  0x02
1395 #define SYN_XFER_NS_0  25
1396 #define SYN_XFER_NS_1  30
1397 #define SYN_XFER_NS_2  35
1398 #define SYN_XFER_NS_3  40
1399 #define SYN_XFER_NS_4  50
1400 #define SYN_XFER_NS_5  60
1401 #define SYN_XFER_NS_6  70
1402 #define SYN_XFER_NS_7  85
1403 #define SYN_ULTRA_XFER_NS_0    12
1404 #define SYN_ULTRA_XFER_NS_1    19
1405 #define SYN_ULTRA_XFER_NS_2    25
1406 #define SYN_ULTRA_XFER_NS_3    32
1407 #define SYN_ULTRA_XFER_NS_4    38
1408 #define SYN_ULTRA_XFER_NS_5    44
1409 #define SYN_ULTRA_XFER_NS_6    50
1410 #define SYN_ULTRA_XFER_NS_7    57
1411 #define SYN_ULTRA_XFER_NS_8    63
1412 #define SYN_ULTRA_XFER_NS_9    69
1413 #define SYN_ULTRA_XFER_NS_10   75
1414 #define SYN_ULTRA_XFER_NS_11   82
1415 #define SYN_ULTRA_XFER_NS_12   88
1416 #define SYN_ULTRA_XFER_NS_13   94
1417 #define SYN_ULTRA_XFER_NS_14  100
1418 #define SYN_ULTRA_XFER_NS_15  107
1419 
1420 typedef struct ext_msg {
1421 	uchar msg_type;
1422 	uchar msg_len;
1423 	uchar msg_req;
1424 	union {
1425 		struct {
1426 			uchar sdtr_xfer_period;
1427 			uchar sdtr_req_ack_offset;
1428 		} sdtr;
1429 		struct {
1430 			uchar wdtr_width;
1431 		} wdtr;
1432 		struct {
1433 			uchar mdp_b3;
1434 			uchar mdp_b2;
1435 			uchar mdp_b1;
1436 			uchar mdp_b0;
1437 		} mdp;
1438 	} u_ext_msg;
1439 	uchar res;
1440 } EXT_MSG;
1441 
1442 #define xfer_period     u_ext_msg.sdtr.sdtr_xfer_period
1443 #define req_ack_offset  u_ext_msg.sdtr.sdtr_req_ack_offset
1444 #define wdtr_width      u_ext_msg.wdtr.wdtr_width
1445 #define mdp_b3          u_ext_msg.mdp_b3
1446 #define mdp_b2          u_ext_msg.mdp_b2
1447 #define mdp_b1          u_ext_msg.mdp_b1
1448 #define mdp_b0          u_ext_msg.mdp_b0
1449 
1450 typedef struct asc_dvc_cfg {
1451 	ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1452 	ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1453 	ASC_SCSI_BIT_ID_TYPE disc_enable;
1454 	ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1455 	uchar chip_scsi_id;
1456 	uchar isa_dma_speed;
1457 	uchar isa_dma_channel;
1458 	uchar chip_version;
1459 	ushort lib_serial_no;
1460 	ushort lib_version;
1461 	ushort mcode_date;
1462 	ushort mcode_version;
1463 	uchar max_tag_qng[ASC_MAX_TID + 1];
1464 	uchar *overrun_buf;
1465 	uchar sdtr_period_offset[ASC_MAX_TID + 1];
1466 	ushort pci_slot_info;
1467 	uchar adapter_info[6];
1468 	struct device *dev;
1469 } ASC_DVC_CFG;
1470 
1471 #define ASC_DEF_DVC_CNTL       0xFFFF
1472 #define ASC_DEF_CHIP_SCSI_ID   7
1473 #define ASC_DEF_ISA_DMA_SPEED  4
1474 #define ASC_INIT_STATE_NULL          0x0000
1475 #define ASC_INIT_STATE_BEG_GET_CFG   0x0001
1476 #define ASC_INIT_STATE_END_GET_CFG   0x0002
1477 #define ASC_INIT_STATE_BEG_SET_CFG   0x0004
1478 #define ASC_INIT_STATE_END_SET_CFG   0x0008
1479 #define ASC_INIT_STATE_BEG_LOAD_MC   0x0010
1480 #define ASC_INIT_STATE_END_LOAD_MC   0x0020
1481 #define ASC_INIT_STATE_BEG_INQUIRY   0x0040
1482 #define ASC_INIT_STATE_END_INQUIRY   0x0080
1483 #define ASC_INIT_RESET_SCSI_DONE     0x0100
1484 #define ASC_INIT_STATE_WITHOUT_EEP   0x8000
1485 #define ASC_BUG_FIX_IF_NOT_DWB       0x0001
1486 #define ASC_BUG_FIX_ASYN_USE_SYN     0x0002
1487 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1488 #define ASC_MIN_TAGGED_CMD  7
1489 #define ASC_MAX_SCSI_RESET_WAIT      30
1490 
1491 struct asc_dvc_var;		/* Forward Declaration. */
1492 
1493 typedef void (*ASC_ISR_CALLBACK) (struct asc_dvc_var *, ASC_QDONE_INFO *);
1494 typedef int (*ASC_EXE_CALLBACK) (struct asc_dvc_var *, ASC_SCSI_Q *);
1495 
1496 typedef struct asc_dvc_var {
1497 	PortAddr iop_base;
1498 	ushort err_code;
1499 	ushort dvc_cntl;
1500 	ushort bug_fix_cntl;
1501 	ushort bus_type;
1502 	ASC_ISR_CALLBACK isr_callback;
1503 	ASC_EXE_CALLBACK exe_callback;
1504 	ASC_SCSI_BIT_ID_TYPE init_sdtr;
1505 	ASC_SCSI_BIT_ID_TYPE sdtr_done;
1506 	ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1507 	ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1508 	ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1509 	ASC_SCSI_BIT_ID_TYPE start_motor;
1510 	uchar scsi_reset_wait;
1511 	uchar chip_no;
1512 	char is_in_int;
1513 	uchar max_total_qng;
1514 	uchar cur_total_qng;
1515 	uchar in_critical_cnt;
1516 	uchar irq_no;
1517 	uchar last_q_shortage;
1518 	ushort init_state;
1519 	uchar cur_dvc_qng[ASC_MAX_TID + 1];
1520 	uchar max_dvc_qng[ASC_MAX_TID + 1];
1521 	ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
1522 	ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
1523 	uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1524 	ASC_DVC_CFG *cfg;
1525 	ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1526 	char redo_scam;
1527 	ushort res2;
1528 	uchar dos_int13_table[ASC_MAX_TID + 1];
1529 	ASC_DCNT max_dma_count;
1530 	ASC_SCSI_BIT_ID_TYPE no_scam;
1531 	ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1532 	uchar max_sdtr_index;
1533 	uchar host_init_sdtr_index;
1534 	struct asc_board *drv_ptr;
1535 	ASC_DCNT uc_break;
1536 } ASC_DVC_VAR;
1537 
1538 typedef struct asc_dvc_inq_info {
1539 	uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1540 } ASC_DVC_INQ_INFO;
1541 
1542 typedef struct asc_cap_info {
1543 	ASC_DCNT lba;
1544 	ASC_DCNT blk_size;
1545 } ASC_CAP_INFO;
1546 
1547 typedef struct asc_cap_info_array {
1548 	ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1549 } ASC_CAP_INFO_ARRAY;
1550 
1551 #define ASC_MCNTL_NO_SEL_TIMEOUT  (ushort)0x0001
1552 #define ASC_MCNTL_NULL_TARGET     (ushort)0x0002
1553 #define ASC_CNTL_INITIATOR         (ushort)0x0001
1554 #define ASC_CNTL_BIOS_GT_1GB       (ushort)0x0002
1555 #define ASC_CNTL_BIOS_GT_2_DISK    (ushort)0x0004
1556 #define ASC_CNTL_BIOS_REMOVABLE    (ushort)0x0008
1557 #define ASC_CNTL_NO_SCAM           (ushort)0x0010
1558 #define ASC_CNTL_INT_MULTI_Q       (ushort)0x0080
1559 #define ASC_CNTL_NO_LUN_SUPPORT    (ushort)0x0040
1560 #define ASC_CNTL_NO_VERIFY_COPY    (ushort)0x0100
1561 #define ASC_CNTL_RESET_SCSI        (ushort)0x0200
1562 #define ASC_CNTL_INIT_INQUIRY      (ushort)0x0400
1563 #define ASC_CNTL_INIT_VERBOSE      (ushort)0x0800
1564 #define ASC_CNTL_SCSI_PARITY       (ushort)0x1000
1565 #define ASC_CNTL_BURST_MODE        (ushort)0x2000
1566 #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1567 #define ASC_EEP_DVC_CFG_BEG_VL    2
1568 #define ASC_EEP_MAX_DVC_ADDR_VL   15
1569 #define ASC_EEP_DVC_CFG_BEG      32
1570 #define ASC_EEP_MAX_DVC_ADDR     45
1571 #define ASC_EEP_DEFINED_WORDS    10
1572 #define ASC_EEP_MAX_ADDR         63
1573 #define ASC_EEP_RES_WORDS         0
1574 #define ASC_EEP_MAX_RETRY        20
1575 #define ASC_MAX_INIT_BUSY_RETRY   8
1576 #define ASC_EEP_ISA_PNP_WSIZE    16
1577 
1578 /*
1579  * These macros keep the chip SCSI id and ISA DMA speed
1580  * bitfields in board order. C bitfields aren't portable
1581  * between big and little-endian platforms so they are
1582  * not used.
1583  */
1584 
1585 #define ASC_EEP_GET_CHIP_ID(cfg)    ((cfg)->id_speed & 0x0f)
1586 #define ASC_EEP_GET_DMA_SPD(cfg)    (((cfg)->id_speed & 0xf0) >> 4)
1587 #define ASC_EEP_SET_CHIP_ID(cfg, sid) \
1588    ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
1589 #define ASC_EEP_SET_DMA_SPD(cfg, spd) \
1590    ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
1591 
1592 typedef struct asceep_config {
1593 	ushort cfg_lsw;
1594 	ushort cfg_msw;
1595 	uchar init_sdtr;
1596 	uchar disc_enable;
1597 	uchar use_cmd_qng;
1598 	uchar start_motor;
1599 	uchar max_total_qng;
1600 	uchar max_tag_qng;
1601 	uchar bios_scan;
1602 	uchar power_up_wait;
1603 	uchar no_scam;
1604 	uchar id_speed;		/* low order 4 bits is chip scsi id */
1605 	/* high order 4 bits is isa dma speed */
1606 	uchar dos_int13_table[ASC_MAX_TID + 1];
1607 	uchar adapter_info[6];
1608 	ushort cntl;
1609 	ushort chksum;
1610 } ASCEEP_CONFIG;
1611 
1612 #define ASC_PCI_CFG_LSW_SCSI_PARITY  0x0800
1613 #define ASC_PCI_CFG_LSW_BURST_MODE   0x0080
1614 #define ASC_PCI_CFG_LSW_INTR_ABLE    0x0020
1615 
1616 #define ASC_EEP_CMD_READ          0x80
1617 #define ASC_EEP_CMD_WRITE         0x40
1618 #define ASC_EEP_CMD_WRITE_ABLE    0x30
1619 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
1620 #define ASC_OVERRUN_BSIZE  0x00000048UL
1621 #define ASC_CTRL_BREAK_ONCE        0x0001
1622 #define ASC_CTRL_BREAK_STAY_IDLE   0x0002
1623 #define ASCV_MSGOUT_BEG         0x0000
1624 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1625 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1626 #define ASCV_BREAK_SAVED_CODE   (ushort)0x0006
1627 #define ASCV_MSGIN_BEG          (ASCV_MSGOUT_BEG+8)
1628 #define ASCV_MSGIN_SDTR_PERIOD  (ASCV_MSGIN_BEG+3)
1629 #define ASCV_MSGIN_SDTR_OFFSET  (ASCV_MSGIN_BEG+4)
1630 #define ASCV_SDTR_DATA_BEG      (ASCV_MSGIN_BEG+8)
1631 #define ASCV_SDTR_DONE_BEG      (ASCV_SDTR_DATA_BEG+8)
1632 #define ASCV_MAX_DVC_QNG_BEG    (ushort)0x0020
1633 #define ASCV_BREAK_ADDR           (ushort)0x0028
1634 #define ASCV_BREAK_NOTIFY_COUNT   (ushort)0x002A
1635 #define ASCV_BREAK_CONTROL        (ushort)0x002C
1636 #define ASCV_BREAK_HIT_COUNT      (ushort)0x002E
1637 
1638 #define ASCV_ASCDVC_ERR_CODE_W  (ushort)0x0030
1639 #define ASCV_MCODE_CHKSUM_W   (ushort)0x0032
1640 #define ASCV_MCODE_SIZE_W     (ushort)0x0034
1641 #define ASCV_STOP_CODE_B      (ushort)0x0036
1642 #define ASCV_DVC_ERR_CODE_B   (ushort)0x0037
1643 #define ASCV_OVERRUN_PADDR_D  (ushort)0x0038
1644 #define ASCV_OVERRUN_BSIZE_D  (ushort)0x003C
1645 #define ASCV_HALTCODE_W       (ushort)0x0040
1646 #define ASCV_CHKSUM_W         (ushort)0x0042
1647 #define ASCV_MC_DATE_W        (ushort)0x0044
1648 #define ASCV_MC_VER_W         (ushort)0x0046
1649 #define ASCV_NEXTRDY_B        (ushort)0x0048
1650 #define ASCV_DONENEXT_B       (ushort)0x0049
1651 #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1652 #define ASCV_SCSIBUSY_B       (ushort)0x004B
1653 #define ASCV_Q_DONE_IN_PROGRESS_B  (ushort)0x004C
1654 #define ASCV_CURCDB_B         (ushort)0x004D
1655 #define ASCV_RCLUN_B          (ushort)0x004E
1656 #define ASCV_BUSY_QHEAD_B     (ushort)0x004F
1657 #define ASCV_DISC1_QHEAD_B    (ushort)0x0050
1658 #define ASCV_DISC_ENABLE_B    (ushort)0x0052
1659 #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1660 #define ASCV_HOSTSCSI_ID_B    (ushort)0x0055
1661 #define ASCV_MCODE_CNTL_B     (ushort)0x0056
1662 #define ASCV_NULL_TARGET_B    (ushort)0x0057
1663 #define ASCV_FREE_Q_HEAD_W    (ushort)0x0058
1664 #define ASCV_DONE_Q_TAIL_W    (ushort)0x005A
1665 #define ASCV_FREE_Q_HEAD_B    (ushort)(ASCV_FREE_Q_HEAD_W+1)
1666 #define ASCV_DONE_Q_TAIL_B    (ushort)(ASCV_DONE_Q_TAIL_W+1)
1667 #define ASCV_HOST_FLAG_B      (ushort)0x005D
1668 #define ASCV_TOTAL_READY_Q_B  (ushort)0x0064
1669 #define ASCV_VER_SERIAL_B     (ushort)0x0065
1670 #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1671 #define ASCV_WTM_FLAG_B       (ushort)0x0068
1672 #define ASCV_RISC_FLAG_B      (ushort)0x006A
1673 #define ASCV_REQ_SG_LIST_QP   (ushort)0x006B
1674 #define ASC_HOST_FLAG_IN_ISR        0x01
1675 #define ASC_HOST_FLAG_ACK_INT       0x02
1676 #define ASC_RISC_FLAG_GEN_INT      0x01
1677 #define ASC_RISC_FLAG_REQ_SG_LIST  0x02
1678 #define IOP_CTRL         (0x0F)
1679 #define IOP_STATUS       (0x0E)
1680 #define IOP_INT_ACK      IOP_STATUS
1681 #define IOP_REG_IFC      (0x0D)
1682 #define IOP_SYN_OFFSET    (0x0B)
1683 #define IOP_EXTRA_CONTROL (0x0D)
1684 #define IOP_REG_PC        (0x0C)
1685 #define IOP_RAM_ADDR      (0x0A)
1686 #define IOP_RAM_DATA      (0x08)
1687 #define IOP_EEP_DATA      (0x06)
1688 #define IOP_EEP_CMD       (0x07)
1689 #define IOP_VERSION       (0x03)
1690 #define IOP_CONFIG_HIGH   (0x04)
1691 #define IOP_CONFIG_LOW    (0x02)
1692 #define IOP_SIG_BYTE      (0x01)
1693 #define IOP_SIG_WORD      (0x00)
1694 #define IOP_REG_DC1      (0x0E)
1695 #define IOP_REG_DC0      (0x0C)
1696 #define IOP_REG_SB       (0x0B)
1697 #define IOP_REG_DA1      (0x0A)
1698 #define IOP_REG_DA0      (0x08)
1699 #define IOP_REG_SC       (0x09)
1700 #define IOP_DMA_SPEED    (0x07)
1701 #define IOP_REG_FLAG     (0x07)
1702 #define IOP_FIFO_H       (0x06)
1703 #define IOP_FIFO_L       (0x04)
1704 #define IOP_REG_ID       (0x05)
1705 #define IOP_REG_QP       (0x03)
1706 #define IOP_REG_IH       (0x02)
1707 #define IOP_REG_IX       (0x01)
1708 #define IOP_REG_AX       (0x00)
1709 #define IFC_REG_LOCK      (0x00)
1710 #define IFC_REG_UNLOCK    (0x09)
1711 #define IFC_WR_EN_FILTER  (0x10)
1712 #define IFC_RD_NO_EEPROM  (0x10)
1713 #define IFC_SLEW_RATE     (0x20)
1714 #define IFC_ACT_NEG       (0x40)
1715 #define IFC_INP_FILTER    (0x80)
1716 #define IFC_INIT_DEFAULT  (IFC_ACT_NEG | IFC_REG_UNLOCK)
1717 #define SC_SEL   (uchar)(0x80)
1718 #define SC_BSY   (uchar)(0x40)
1719 #define SC_ACK   (uchar)(0x20)
1720 #define SC_REQ   (uchar)(0x10)
1721 #define SC_ATN   (uchar)(0x08)
1722 #define SC_IO    (uchar)(0x04)
1723 #define SC_CD    (uchar)(0x02)
1724 #define SC_MSG   (uchar)(0x01)
1725 #define SEC_SCSI_CTL         (uchar)(0x80)
1726 #define SEC_ACTIVE_NEGATE    (uchar)(0x40)
1727 #define SEC_SLEW_RATE        (uchar)(0x20)
1728 #define SEC_ENABLE_FILTER    (uchar)(0x10)
1729 #define ASC_HALT_EXTMSG_IN     (ushort)0x8000
1730 #define ASC_HALT_CHK_CONDITION (ushort)0x8100
1731 #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1732 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX  (ushort)0x8300
1733 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX   (ushort)0x8400
1734 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1735 #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1736 #define ASC_MAX_QNO        0xF8
1737 #define ASC_DATA_SEC_BEG   (ushort)0x0080
1738 #define ASC_DATA_SEC_END   (ushort)0x0080
1739 #define ASC_CODE_SEC_BEG   (ushort)0x0080
1740 #define ASC_CODE_SEC_END   (ushort)0x0080
1741 #define ASC_QADR_BEG       (0x4000)
1742 #define ASC_QADR_USED      (ushort)(ASC_MAX_QNO * 64)
1743 #define ASC_QADR_END       (ushort)0x7FFF
1744 #define ASC_QLAST_ADR      (ushort)0x7FC0
1745 #define ASC_QBLK_SIZE      0x40
1746 #define ASC_BIOS_DATA_QBEG 0xF8
1747 #define ASC_MIN_ACTIVE_QNO 0x01
1748 #define ASC_QLINK_END      0xFF
1749 #define ASC_EEPROM_WORDS   0x10
1750 #define ASC_MAX_MGS_LEN    0x10
1751 #define ASC_BIOS_ADDR_DEF  0xDC00
1752 #define ASC_BIOS_SIZE      0x3800
1753 #define ASC_BIOS_RAM_OFF   0x3800
1754 #define ASC_BIOS_RAM_SIZE  0x800
1755 #define ASC_BIOS_MIN_ADDR  0xC000
1756 #define ASC_BIOS_MAX_ADDR  0xEC00
1757 #define ASC_BIOS_BANK_SIZE 0x0400
1758 #define ASC_MCODE_START_ADDR  0x0080
1759 #define ASC_CFG0_HOST_INT_ON    0x0020
1760 #define ASC_CFG0_BIOS_ON        0x0040
1761 #define ASC_CFG0_VERA_BURST_ON  0x0080
1762 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
1763 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
1764 #define ASC_CFG1_LRAM_8BITS_ON  0x0800
1765 #define ASC_CFG_MSW_CLR_MASK    0x3080
1766 #define CSW_TEST1             (ASC_CS_TYPE)0x8000
1767 #define CSW_AUTO_CONFIG       (ASC_CS_TYPE)0x4000
1768 #define CSW_RESERVED1         (ASC_CS_TYPE)0x2000
1769 #define CSW_IRQ_WRITTEN       (ASC_CS_TYPE)0x1000
1770 #define CSW_33MHZ_SELECTED    (ASC_CS_TYPE)0x0800
1771 #define CSW_TEST2             (ASC_CS_TYPE)0x0400
1772 #define CSW_TEST3             (ASC_CS_TYPE)0x0200
1773 #define CSW_RESERVED2         (ASC_CS_TYPE)0x0100
1774 #define CSW_DMA_DONE          (ASC_CS_TYPE)0x0080
1775 #define CSW_FIFO_RDY          (ASC_CS_TYPE)0x0040
1776 #define CSW_EEP_READ_DONE     (ASC_CS_TYPE)0x0020
1777 #define CSW_HALTED            (ASC_CS_TYPE)0x0010
1778 #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1779 #define CSW_PARITY_ERR        (ASC_CS_TYPE)0x0004
1780 #define CSW_SCSI_RESET_LATCH  (ASC_CS_TYPE)0x0002
1781 #define CSW_INT_PENDING       (ASC_CS_TYPE)0x0001
1782 #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1783 #define CIW_INT_ACK      (ASC_CS_TYPE)0x0100
1784 #define CIW_TEST1        (ASC_CS_TYPE)0x0200
1785 #define CIW_TEST2        (ASC_CS_TYPE)0x0400
1786 #define CIW_SEL_33MHZ    (ASC_CS_TYPE)0x0800
1787 #define CIW_IRQ_ACT      (ASC_CS_TYPE)0x1000
1788 #define CC_CHIP_RESET   (uchar)0x80
1789 #define CC_SCSI_RESET   (uchar)0x40
1790 #define CC_HALT         (uchar)0x20
1791 #define CC_SINGLE_STEP  (uchar)0x10
1792 #define CC_DMA_ABLE     (uchar)0x08
1793 #define CC_TEST         (uchar)0x04
1794 #define CC_BANK_ONE     (uchar)0x02
1795 #define CC_DIAG         (uchar)0x01
1796 #define ASC_1000_ID0W      0x04C1
1797 #define ASC_1000_ID0W_FIX  0x00C1
1798 #define ASC_1000_ID1B      0x25
1799 #define ASC_EISA_BIG_IOP_GAP   (0x1C30-0x0C50)
1800 #define ASC_EISA_SMALL_IOP_GAP (0x0020)
1801 #define ASC_EISA_MIN_IOP_ADDR  (0x0C30)
1802 #define ASC_EISA_MAX_IOP_ADDR  (0xFC50)
1803 #define ASC_EISA_REV_IOP_MASK  (0x0C83)
1804 #define ASC_EISA_PID_IOP_MASK  (0x0C80)
1805 #define ASC_EISA_CFG_IOP_MASK  (0x0C86)
1806 #define ASC_GET_EISA_SLOT(iop)  (PortAddr)((iop) & 0xF000)
1807 #define ASC_EISA_ID_740    0x01745004UL
1808 #define ASC_EISA_ID_750    0x01755004UL
1809 #define INS_HALTINT        (ushort)0x6281
1810 #define INS_HALT           (ushort)0x6280
1811 #define INS_SINT           (ushort)0x6200
1812 #define INS_RFLAG_WTM      (ushort)0x7380
1813 #define ASC_MC_SAVE_CODE_WSIZE  0x500
1814 #define ASC_MC_SAVE_DATA_WSIZE  0x40
1815 
1816 typedef struct asc_mc_saved {
1817 	ushort data[ASC_MC_SAVE_DATA_WSIZE];
1818 	ushort code[ASC_MC_SAVE_CODE_WSIZE];
1819 } ASC_MC_SAVED;
1820 
1821 #define AscGetQDoneInProgress(port)         AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1822 #define AscPutQDoneInProgress(port, val)    AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1823 #define AscGetVarFreeQHead(port)            AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1824 #define AscGetVarDoneQTail(port)            AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1825 #define AscPutVarFreeQHead(port, val)       AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1826 #define AscPutVarDoneQTail(port, val)       AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1827 #define AscGetRiscVarFreeQHead(port)        AscReadLramByte((port), ASCV_NEXTRDY_B)
1828 #define AscGetRiscVarDoneQTail(port)        AscReadLramByte((port), ASCV_DONENEXT_B)
1829 #define AscPutRiscVarFreeQHead(port, val)   AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1830 #define AscPutRiscVarDoneQTail(port, val)   AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1831 #define AscPutMCodeSDTRDoneAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1832 #define AscGetMCodeSDTRDoneAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1833 #define AscPutMCodeInitSDTRAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1834 #define AscGetMCodeInitSDTRAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1835 #define AscSynIndexToPeriod(index)        (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1836 #define AscGetChipSignatureByte(port)     (uchar)inp((port)+IOP_SIG_BYTE)
1837 #define AscGetChipSignatureWord(port)     (ushort)inpw((port)+IOP_SIG_WORD)
1838 #define AscGetChipVerNo(port)             (uchar)inp((port)+IOP_VERSION)
1839 #define AscGetChipCfgLsw(port)            (ushort)inpw((port)+IOP_CONFIG_LOW)
1840 #define AscGetChipCfgMsw(port)            (ushort)inpw((port)+IOP_CONFIG_HIGH)
1841 #define AscSetChipCfgLsw(port, data)      outpw((port)+IOP_CONFIG_LOW, data)
1842 #define AscSetChipCfgMsw(port, data)      outpw((port)+IOP_CONFIG_HIGH, data)
1843 #define AscGetChipEEPCmd(port)            (uchar)inp((port)+IOP_EEP_CMD)
1844 #define AscSetChipEEPCmd(port, data)      outp((port)+IOP_EEP_CMD, data)
1845 #define AscGetChipEEPData(port)           (ushort)inpw((port)+IOP_EEP_DATA)
1846 #define AscSetChipEEPData(port, data)     outpw((port)+IOP_EEP_DATA, data)
1847 #define AscGetChipLramAddr(port)          (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1848 #define AscSetChipLramAddr(port, addr)    outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1849 #define AscGetChipLramData(port)          (ushort)inpw((port)+IOP_RAM_DATA)
1850 #define AscSetChipLramData(port, data)    outpw((port)+IOP_RAM_DATA, data)
1851 #define AscGetChipIFC(port)               (uchar)inp((port)+IOP_REG_IFC)
1852 #define AscSetChipIFC(port, data)          outp((port)+IOP_REG_IFC, data)
1853 #define AscGetChipStatus(port)            (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1854 #define AscSetChipStatus(port, cs_val)    outpw((port)+IOP_STATUS, cs_val)
1855 #define AscGetChipControl(port)           (uchar)inp((port)+IOP_CTRL)
1856 #define AscSetChipControl(port, cc_val)   outp((port)+IOP_CTRL, cc_val)
1857 #define AscGetChipSyn(port)               (uchar)inp((port)+IOP_SYN_OFFSET)
1858 #define AscSetChipSyn(port, data)         outp((port)+IOP_SYN_OFFSET, data)
1859 #define AscSetPCAddr(port, data)          outpw((port)+IOP_REG_PC, data)
1860 #define AscGetPCAddr(port)                (ushort)inpw((port)+IOP_REG_PC)
1861 #define AscIsIntPending(port)             (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1862 #define AscGetChipScsiID(port)            ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1863 #define AscGetExtraControl(port)          (uchar)inp((port)+IOP_EXTRA_CONTROL)
1864 #define AscSetExtraControl(port, data)    outp((port)+IOP_EXTRA_CONTROL, data)
1865 #define AscReadChipAX(port)               (ushort)inpw((port)+IOP_REG_AX)
1866 #define AscWriteChipAX(port, data)        outpw((port)+IOP_REG_AX, data)
1867 #define AscReadChipIX(port)               (uchar)inp((port)+IOP_REG_IX)
1868 #define AscWriteChipIX(port, data)        outp((port)+IOP_REG_IX, data)
1869 #define AscReadChipIH(port)               (ushort)inpw((port)+IOP_REG_IH)
1870 #define AscWriteChipIH(port, data)        outpw((port)+IOP_REG_IH, data)
1871 #define AscReadChipQP(port)               (uchar)inp((port)+IOP_REG_QP)
1872 #define AscWriteChipQP(port, data)        outp((port)+IOP_REG_QP, data)
1873 #define AscReadChipFIFO_L(port)           (ushort)inpw((port)+IOP_REG_FIFO_L)
1874 #define AscWriteChipFIFO_L(port, data)    outpw((port)+IOP_REG_FIFO_L, data)
1875 #define AscReadChipFIFO_H(port)           (ushort)inpw((port)+IOP_REG_FIFO_H)
1876 #define AscWriteChipFIFO_H(port, data)    outpw((port)+IOP_REG_FIFO_H, data)
1877 #define AscReadChipDmaSpeed(port)         (uchar)inp((port)+IOP_DMA_SPEED)
1878 #define AscWriteChipDmaSpeed(port, data)  outp((port)+IOP_DMA_SPEED, data)
1879 #define AscReadChipDA0(port)              (ushort)inpw((port)+IOP_REG_DA0)
1880 #define AscWriteChipDA0(port)             outpw((port)+IOP_REG_DA0, data)
1881 #define AscReadChipDA1(port)              (ushort)inpw((port)+IOP_REG_DA1)
1882 #define AscWriteChipDA1(port)             outpw((port)+IOP_REG_DA1, data)
1883 #define AscReadChipDC0(port)              (ushort)inpw((port)+IOP_REG_DC0)
1884 #define AscWriteChipDC0(port)             outpw((port)+IOP_REG_DC0, data)
1885 #define AscReadChipDC1(port)              (ushort)inpw((port)+IOP_REG_DC1)
1886 #define AscWriteChipDC1(port)             outpw((port)+IOP_REG_DC1, data)
1887 #define AscReadChipDvcID(port)            (uchar)inp((port)+IOP_REG_ID)
1888 #define AscWriteChipDvcID(port, data)     outp((port)+IOP_REG_ID, data)
1889 
1890 static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1891 static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1892 static void AscWaitEEPRead(void);
1893 static void AscWaitEEPWrite(void);
1894 static ushort AscReadEEPWord(PortAddr, uchar);
1895 static ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1896 static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1897 static int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1898 static int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1899 static int AscStartChip(PortAddr);
1900 static int AscStopChip(PortAddr);
1901 static void AscSetChipIH(PortAddr, ushort);
1902 static int AscIsChipHalted(PortAddr);
1903 static void AscAckInterrupt(PortAddr);
1904 static void AscDisableInterrupt(PortAddr);
1905 static void AscEnableInterrupt(PortAddr);
1906 static void AscSetBank(PortAddr, uchar);
1907 static int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1908 #ifdef CONFIG_ISA
1909 static ushort AscGetIsaDmaChannel(PortAddr);
1910 static ushort AscSetIsaDmaChannel(PortAddr, ushort);
1911 static uchar AscSetIsaDmaSpeed(PortAddr, uchar);
1912 static uchar AscGetIsaDmaSpeed(PortAddr);
1913 #endif /* CONFIG_ISA */
1914 static uchar AscReadLramByte(PortAddr, ushort);
1915 static ushort AscReadLramWord(PortAddr, ushort);
1916 #if CC_VERY_LONG_SG_LIST
1917 static ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1918 #endif /* CC_VERY_LONG_SG_LIST */
1919 static void AscWriteLramWord(PortAddr, ushort, ushort);
1920 static void AscWriteLramByte(PortAddr, ushort, uchar);
1921 static ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
1922 static void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1923 static void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1924 static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1925 static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
1926 static ushort AscInitAscDvcVar(ASC_DVC_VAR *);
1927 static ushort AscInitFromEEP(ASC_DVC_VAR *);
1928 static ushort AscInitFromAscDvcVar(ASC_DVC_VAR *);
1929 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1930 static int AscTestExternalLram(ASC_DVC_VAR *);
1931 static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1932 static uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1933 static void AscSetChipSDTR(PortAddr, uchar, uchar);
1934 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1935 static uchar AscAllocFreeQueue(PortAddr, uchar);
1936 static uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1937 static int AscHostReqRiscHalt(PortAddr);
1938 static int AscStopQueueExe(PortAddr);
1939 static int AscSendScsiQueue(ASC_DVC_VAR *,
1940 			    ASC_SCSI_Q *scsiq, uchar n_q_required);
1941 static int AscPutReadyQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1942 static int AscPutReadySgListQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1943 static int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1944 static int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1945 static ushort AscInitLram(ASC_DVC_VAR *);
1946 static ushort AscInitQLinkVar(ASC_DVC_VAR *);
1947 static int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1948 static int AscIsrChipHalted(ASC_DVC_VAR *);
1949 static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1950 				   ASC_QDONE_INFO *, ASC_DCNT);
1951 static int AscIsrQDone(ASC_DVC_VAR *);
1952 static int AscCompareString(uchar *, uchar *, int);
1953 #ifdef CONFIG_ISA
1954 static ushort AscGetEisaChipCfg(PortAddr);
1955 static ASC_DCNT AscGetEisaProductID(PortAddr);
1956 static PortAddr AscSearchIOPortAddrEISA(PortAddr);
1957 static PortAddr AscSearchIOPortAddr11(PortAddr);
1958 static PortAddr AscSearchIOPortAddr(PortAddr, ushort);
1959 static void AscSetISAPNPWaitForKey(void);
1960 #endif /* CONFIG_ISA */
1961 static uchar AscGetChipScsiCtrl(PortAddr);
1962 static uchar AscSetChipScsiID(PortAddr, uchar);
1963 static uchar AscGetChipVersion(PortAddr, ushort);
1964 static ushort AscGetChipBusType(PortAddr);
1965 static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
1966 static int AscFindSignature(PortAddr);
1967 static void AscToggleIRQAct(PortAddr);
1968 static uchar AscGetChipIRQ(PortAddr, ushort);
1969 static uchar AscSetChipIRQ(PortAddr, uchar, ushort);
1970 static ushort AscGetChipBiosAddress(PortAddr, ushort);
1971 static inline ulong DvcEnterCritical(void);
1972 static inline void DvcLeaveCritical(ulong);
1973 #ifdef CONFIG_PCI
1974 static uchar DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort);
1975 static void DvcWritePCIConfigByte(ASC_DVC_VAR *, ushort, uchar);
1976 #endif /* CONFIG_PCI */
1977 static ushort AscGetChipBiosAddress(PortAddr, ushort);
1978 static void DvcSleepMilliSecond(ASC_DCNT);
1979 static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
1980 static void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1981 static void DvcGetQinfo(PortAddr, ushort, uchar *, int);
1982 static ushort AscInitGetConfig(ASC_DVC_VAR *);
1983 static ushort AscInitSetConfig(ASC_DVC_VAR *);
1984 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
1985 static void AscAsyncFix(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *);
1986 static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
1987 static void AscInquiryHandling(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *);
1988 static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
1989 static int AscISR(ASC_DVC_VAR *);
1990 static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar);
1991 static int AscSgListToQueue(int);
1992 #ifdef CONFIG_ISA
1993 static void AscEnableIsaDma(uchar);
1994 #endif /* CONFIG_ISA */
1995 static ASC_DCNT AscGetMaxDmaCount(ushort);
1996 static const char *advansys_info(struct Scsi_Host *shost);
1997 
1998 /*
1999  * --- Adv Library Constants and Macros
2000  */
2001 
2002 #define ADV_LIB_VERSION_MAJOR  5
2003 #define ADV_LIB_VERSION_MINOR  14
2004 
2005 /*
2006  * Define Adv Library required special types.
2007  */
2008 
2009 /*
2010  * Portable Data Types
2011  *
2012  * Any instance where a 32-bit long or pointer type is assumed
2013  * for precision or HW defined structures, the following define
2014  * types must be used. In Linux the char, short, and int types
2015  * are all consistent at 8, 16, and 32 bits respectively. Pointers
2016  * and long types are 64 bits on Alpha and UltraSPARC.
2017  */
2018 #define ADV_PADDR __u32		/* Physical address data type. */
2019 #define ADV_VADDR __u32		/* Virtual address data type. */
2020 #define ADV_DCNT  __u32		/* Unsigned Data count type. */
2021 #define ADV_SDCNT __s32		/* Signed Data count type. */
2022 
2023 /*
2024  * These macros are used to convert a virtual address to a
2025  * 32-bit value. This currently can be used on Linux Alpha
2026  * which uses 64-bit virtual address but a 32-bit bus address.
2027  * This is likely to break in the future, but doing this now
2028  * will give us time to change the HW and FW to handle 64-bit
2029  * addresses.
2030  */
2031 #define ADV_VADDR_TO_U32   virt_to_bus
2032 #define ADV_U32_TO_VADDR   bus_to_virt
2033 
2034 #define AdvPortAddr  void __iomem *	/* Virtual memory address size */
2035 
2036 /*
2037  * Define Adv Library required memory access macros.
2038  */
2039 #define ADV_MEM_READB(addr) readb(addr)
2040 #define ADV_MEM_READW(addr) readw(addr)
2041 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
2042 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
2043 #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
2044 
2045 #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
2046 
2047 /*
2048  * For wide  boards a CDB length maximum of 16 bytes
2049  * is supported.
2050  */
2051 #define ADV_MAX_CDB_LEN     16
2052 
2053 /*
2054  * Define total number of simultaneous maximum element scatter-gather
2055  * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
2056  * maximum number of outstanding commands per wide host adapter. Each
2057  * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
2058  * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
2059  * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
2060  * structures or 255 scatter-gather elements.
2061  *
2062  */
2063 #define ADV_TOT_SG_BLOCK        ASC_DEF_MAX_HOST_QNG
2064 
2065 /*
2066  * Define Adv Library required maximum number of scatter-gather
2067  * elements per request.
2068  */
2069 #define ADV_MAX_SG_LIST         255
2070 
2071 /* Number of SG blocks needed. */
2072 #define ADV_NUM_SG_BLOCK \
2073     ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
2074 
2075 /* Total contiguous memory needed for SG blocks. */
2076 #define ADV_SG_TOTAL_MEM_SIZE \
2077     (sizeof(ADV_SG_BLOCK) *  ADV_NUM_SG_BLOCK)
2078 
2079 #define ADV_PAGE_SIZE PAGE_SIZE
2080 
2081 #define ADV_NUM_PAGE_CROSSING \
2082     ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2083 
2084 #define ADV_EEP_DVC_CFG_BEGIN           (0x00)
2085 #define ADV_EEP_DVC_CFG_END             (0x15)
2086 #define ADV_EEP_DVC_CTL_BEGIN           (0x16)	/* location of OEM name */
2087 #define ADV_EEP_MAX_WORD_ADDR           (0x1E)
2088 
2089 #define ADV_EEP_DELAY_MS                100
2090 
2091 #define ADV_EEPROM_BIG_ENDIAN          0x8000	/* EEPROM Bit 15 */
2092 #define ADV_EEPROM_BIOS_ENABLE         0x4000	/* EEPROM Bit 14 */
2093 /*
2094  * For the ASC3550 Bit 13 is Termination Polarity control bit.
2095  * For later ICs Bit 13 controls whether the CIS (Card Information
2096  * Service Section) is loaded from EEPROM.
2097  */
2098 #define ADV_EEPROM_TERM_POL            0x2000	/* EEPROM Bit 13 */
2099 #define ADV_EEPROM_CIS_LD              0x2000	/* EEPROM Bit 13 */
2100 /*
2101  * ASC38C1600 Bit 11
2102  *
2103  * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
2104  * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
2105  * Function 0 will specify INT B.
2106  *
2107  * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
2108  * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
2109  * Function 1 will specify INT A.
2110  */
2111 #define ADV_EEPROM_INTAB               0x0800	/* EEPROM Bit 11 */
2112 
2113 typedef struct adveep_3550_config {
2114 	/* Word Offset, Description */
2115 
2116 	ushort cfg_lsw;		/* 00 power up initialization */
2117 	/*  bit 13 set - Term Polarity Control */
2118 	/*  bit 14 set - BIOS Enable */
2119 	/*  bit 15 set - Big Endian Mode */
2120 	ushort cfg_msw;		/* 01 unused      */
2121 	ushort disc_enable;	/* 02 disconnect enable */
2122 	ushort wdtr_able;	/* 03 Wide DTR able */
2123 	ushort sdtr_able;	/* 04 Synchronous DTR able */
2124 	ushort start_motor;	/* 05 send start up motor */
2125 	ushort tagqng_able;	/* 06 tag queuing able */
2126 	ushort bios_scan;	/* 07 BIOS device control */
2127 	ushort scam_tolerant;	/* 08 no scam */
2128 
2129 	uchar adapter_scsi_id;	/* 09 Host Adapter ID */
2130 	uchar bios_boot_delay;	/*    power up wait */
2131 
2132 	uchar scsi_reset_delay;	/* 10 reset delay */
2133 	uchar bios_id_lun;	/*    first boot device scsi id & lun */
2134 	/*    high nibble is lun */
2135 	/*    low nibble is scsi id */
2136 
2137 	uchar termination;	/* 11 0 - automatic */
2138 	/*    1 - low off / high off */
2139 	/*    2 - low off / high on */
2140 	/*    3 - low on  / high on */
2141 	/*    There is no low on  / high off */
2142 
2143 	uchar reserved1;	/*    reserved byte (not used) */
2144 
2145 	ushort bios_ctrl;	/* 12 BIOS control bits */
2146 	/*  bit 0  BIOS don't act as initiator. */
2147 	/*  bit 1  BIOS > 1 GB support */
2148 	/*  bit 2  BIOS > 2 Disk Support */
2149 	/*  bit 3  BIOS don't support removables */
2150 	/*  bit 4  BIOS support bootable CD */
2151 	/*  bit 5  BIOS scan enabled */
2152 	/*  bit 6  BIOS support multiple LUNs */
2153 	/*  bit 7  BIOS display of message */
2154 	/*  bit 8  SCAM disabled */
2155 	/*  bit 9  Reset SCSI bus during init. */
2156 	/*  bit 10 */
2157 	/*  bit 11 No verbose initialization. */
2158 	/*  bit 12 SCSI parity enabled */
2159 	/*  bit 13 */
2160 	/*  bit 14 */
2161 	/*  bit 15 */
2162 	ushort ultra_able;	/* 13 ULTRA speed able */
2163 	ushort reserved2;	/* 14 reserved */
2164 	uchar max_host_qng;	/* 15 maximum host queuing */
2165 	uchar max_dvc_qng;	/*    maximum per device queuing */
2166 	ushort dvc_cntl;	/* 16 control bit for driver */
2167 	ushort bug_fix;		/* 17 control bit for bug fix */
2168 	ushort serial_number_word1;	/* 18 Board serial number word 1 */
2169 	ushort serial_number_word2;	/* 19 Board serial number word 2 */
2170 	ushort serial_number_word3;	/* 20 Board serial number word 3 */
2171 	ushort check_sum;	/* 21 EEP check sum */
2172 	uchar oem_name[16];	/* 22 OEM name */
2173 	ushort dvc_err_code;	/* 30 last device driver error code */
2174 	ushort adv_err_code;	/* 31 last uc and Adv Lib error code */
2175 	ushort adv_err_addr;	/* 32 last uc error address */
2176 	ushort saved_dvc_err_code;	/* 33 saved last dev. driver error code   */
2177 	ushort saved_adv_err_code;	/* 34 saved last uc and Adv Lib error code */
2178 	ushort saved_adv_err_addr;	/* 35 saved last uc error address         */
2179 	ushort num_of_err;	/* 36 number of error */
2180 } ADVEEP_3550_CONFIG;
2181 
2182 typedef struct adveep_38C0800_config {
2183 	/* Word Offset, Description */
2184 
2185 	ushort cfg_lsw;		/* 00 power up initialization */
2186 	/*  bit 13 set - Load CIS */
2187 	/*  bit 14 set - BIOS Enable */
2188 	/*  bit 15 set - Big Endian Mode */
2189 	ushort cfg_msw;		/* 01 unused      */
2190 	ushort disc_enable;	/* 02 disconnect enable */
2191 	ushort wdtr_able;	/* 03 Wide DTR able */
2192 	ushort sdtr_speed1;	/* 04 SDTR Speed TID 0-3 */
2193 	ushort start_motor;	/* 05 send start up motor */
2194 	ushort tagqng_able;	/* 06 tag queuing able */
2195 	ushort bios_scan;	/* 07 BIOS device control */
2196 	ushort scam_tolerant;	/* 08 no scam */
2197 
2198 	uchar adapter_scsi_id;	/* 09 Host Adapter ID */
2199 	uchar bios_boot_delay;	/*    power up wait */
2200 
2201 	uchar scsi_reset_delay;	/* 10 reset delay */
2202 	uchar bios_id_lun;	/*    first boot device scsi id & lun */
2203 	/*    high nibble is lun */
2204 	/*    low nibble is scsi id */
2205 
2206 	uchar termination_se;	/* 11 0 - automatic */
2207 	/*    1 - low off / high off */
2208 	/*    2 - low off / high on */
2209 	/*    3 - low on  / high on */
2210 	/*    There is no low on  / high off */
2211 
2212 	uchar termination_lvd;	/* 11 0 - automatic */
2213 	/*    1 - low off / high off */
2214 	/*    2 - low off / high on */
2215 	/*    3 - low on  / high on */
2216 	/*    There is no low on  / high off */
2217 
2218 	ushort bios_ctrl;	/* 12 BIOS control bits */
2219 	/*  bit 0  BIOS don't act as initiator. */
2220 	/*  bit 1  BIOS > 1 GB support */
2221 	/*  bit 2  BIOS > 2 Disk Support */
2222 	/*  bit 3  BIOS don't support removables */
2223 	/*  bit 4  BIOS support bootable CD */
2224 	/*  bit 5  BIOS scan enabled */
2225 	/*  bit 6  BIOS support multiple LUNs */
2226 	/*  bit 7  BIOS display of message */
2227 	/*  bit 8  SCAM disabled */
2228 	/*  bit 9  Reset SCSI bus during init. */
2229 	/*  bit 10 */
2230 	/*  bit 11 No verbose initialization. */
2231 	/*  bit 12 SCSI parity enabled */
2232 	/*  bit 13 */
2233 	/*  bit 14 */
2234 	/*  bit 15 */
2235 	ushort sdtr_speed2;	/* 13 SDTR speed TID 4-7 */
2236 	ushort sdtr_speed3;	/* 14 SDTR speed TID 8-11 */
2237 	uchar max_host_qng;	/* 15 maximum host queueing */
2238 	uchar max_dvc_qng;	/*    maximum per device queuing */
2239 	ushort dvc_cntl;	/* 16 control bit for driver */
2240 	ushort sdtr_speed4;	/* 17 SDTR speed 4 TID 12-15 */
2241 	ushort serial_number_word1;	/* 18 Board serial number word 1 */
2242 	ushort serial_number_word2;	/* 19 Board serial number word 2 */
2243 	ushort serial_number_word3;	/* 20 Board serial number word 3 */
2244 	ushort check_sum;	/* 21 EEP check sum */
2245 	uchar oem_name[16];	/* 22 OEM name */
2246 	ushort dvc_err_code;	/* 30 last device driver error code */
2247 	ushort adv_err_code;	/* 31 last uc and Adv Lib error code */
2248 	ushort adv_err_addr;	/* 32 last uc error address */
2249 	ushort saved_dvc_err_code;	/* 33 saved last dev. driver error code   */
2250 	ushort saved_adv_err_code;	/* 34 saved last uc and Adv Lib error code */
2251 	ushort saved_adv_err_addr;	/* 35 saved last uc error address         */
2252 	ushort reserved36;	/* 36 reserved */
2253 	ushort reserved37;	/* 37 reserved */
2254 	ushort reserved38;	/* 38 reserved */
2255 	ushort reserved39;	/* 39 reserved */
2256 	ushort reserved40;	/* 40 reserved */
2257 	ushort reserved41;	/* 41 reserved */
2258 	ushort reserved42;	/* 42 reserved */
2259 	ushort reserved43;	/* 43 reserved */
2260 	ushort reserved44;	/* 44 reserved */
2261 	ushort reserved45;	/* 45 reserved */
2262 	ushort reserved46;	/* 46 reserved */
2263 	ushort reserved47;	/* 47 reserved */
2264 	ushort reserved48;	/* 48 reserved */
2265 	ushort reserved49;	/* 49 reserved */
2266 	ushort reserved50;	/* 50 reserved */
2267 	ushort reserved51;	/* 51 reserved */
2268 	ushort reserved52;	/* 52 reserved */
2269 	ushort reserved53;	/* 53 reserved */
2270 	ushort reserved54;	/* 54 reserved */
2271 	ushort reserved55;	/* 55 reserved */
2272 	ushort cisptr_lsw;	/* 56 CIS PTR LSW */
2273 	ushort cisprt_msw;	/* 57 CIS PTR MSW */
2274 	ushort subsysvid;	/* 58 SubSystem Vendor ID */
2275 	ushort subsysid;	/* 59 SubSystem ID */
2276 	ushort reserved60;	/* 60 reserved */
2277 	ushort reserved61;	/* 61 reserved */
2278 	ushort reserved62;	/* 62 reserved */
2279 	ushort reserved63;	/* 63 reserved */
2280 } ADVEEP_38C0800_CONFIG;
2281 
2282 typedef struct adveep_38C1600_config {
2283 	/* Word Offset, Description */
2284 
2285 	ushort cfg_lsw;		/* 00 power up initialization */
2286 	/*  bit 11 set - Func. 0 INTB, Func. 1 INTA */
2287 	/*       clear - Func. 0 INTA, Func. 1 INTB */
2288 	/*  bit 13 set - Load CIS */
2289 	/*  bit 14 set - BIOS Enable */
2290 	/*  bit 15 set - Big Endian Mode */
2291 	ushort cfg_msw;		/* 01 unused */
2292 	ushort disc_enable;	/* 02 disconnect enable */
2293 	ushort wdtr_able;	/* 03 Wide DTR able */
2294 	ushort sdtr_speed1;	/* 04 SDTR Speed TID 0-3 */
2295 	ushort start_motor;	/* 05 send start up motor */
2296 	ushort tagqng_able;	/* 06 tag queuing able */
2297 	ushort bios_scan;	/* 07 BIOS device control */
2298 	ushort scam_tolerant;	/* 08 no scam */
2299 
2300 	uchar adapter_scsi_id;	/* 09 Host Adapter ID */
2301 	uchar bios_boot_delay;	/*    power up wait */
2302 
2303 	uchar scsi_reset_delay;	/* 10 reset delay */
2304 	uchar bios_id_lun;	/*    first boot device scsi id & lun */
2305 	/*    high nibble is lun */
2306 	/*    low nibble is scsi id */
2307 
2308 	uchar termination_se;	/* 11 0 - automatic */
2309 	/*    1 - low off / high off */
2310 	/*    2 - low off / high on */
2311 	/*    3 - low on  / high on */
2312 	/*    There is no low on  / high off */
2313 
2314 	uchar termination_lvd;	/* 11 0 - automatic */
2315 	/*    1 - low off / high off */
2316 	/*    2 - low off / high on */
2317 	/*    3 - low on  / high on */
2318 	/*    There is no low on  / high off */
2319 
2320 	ushort bios_ctrl;	/* 12 BIOS control bits */
2321 	/*  bit 0  BIOS don't act as initiator. */
2322 	/*  bit 1  BIOS > 1 GB support */
2323 	/*  bit 2  BIOS > 2 Disk Support */
2324 	/*  bit 3  BIOS don't support removables */
2325 	/*  bit 4  BIOS support bootable CD */
2326 	/*  bit 5  BIOS scan enabled */
2327 	/*  bit 6  BIOS support multiple LUNs */
2328 	/*  bit 7  BIOS display of message */
2329 	/*  bit 8  SCAM disabled */
2330 	/*  bit 9  Reset SCSI bus during init. */
2331 	/*  bit 10 Basic Integrity Checking disabled */
2332 	/*  bit 11 No verbose initialization. */
2333 	/*  bit 12 SCSI parity enabled */
2334 	/*  bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
2335 	/*  bit 14 */
2336 	/*  bit 15 */
2337 	ushort sdtr_speed2;	/* 13 SDTR speed TID 4-7 */
2338 	ushort sdtr_speed3;	/* 14 SDTR speed TID 8-11 */
2339 	uchar max_host_qng;	/* 15 maximum host queueing */
2340 	uchar max_dvc_qng;	/*    maximum per device queuing */
2341 	ushort dvc_cntl;	/* 16 control bit for driver */
2342 	ushort sdtr_speed4;	/* 17 SDTR speed 4 TID 12-15 */
2343 	ushort serial_number_word1;	/* 18 Board serial number word 1 */
2344 	ushort serial_number_word2;	/* 19 Board serial number word 2 */
2345 	ushort serial_number_word3;	/* 20 Board serial number word 3 */
2346 	ushort check_sum;	/* 21 EEP check sum */
2347 	uchar oem_name[16];	/* 22 OEM name */
2348 	ushort dvc_err_code;	/* 30 last device driver error code */
2349 	ushort adv_err_code;	/* 31 last uc and Adv Lib error code */
2350 	ushort adv_err_addr;	/* 32 last uc error address */
2351 	ushort saved_dvc_err_code;	/* 33 saved last dev. driver error code   */
2352 	ushort saved_adv_err_code;	/* 34 saved last uc and Adv Lib error code */
2353 	ushort saved_adv_err_addr;	/* 35 saved last uc error address         */
2354 	ushort reserved36;	/* 36 reserved */
2355 	ushort reserved37;	/* 37 reserved */
2356 	ushort reserved38;	/* 38 reserved */
2357 	ushort reserved39;	/* 39 reserved */
2358 	ushort reserved40;	/* 40 reserved */
2359 	ushort reserved41;	/* 41 reserved */
2360 	ushort reserved42;	/* 42 reserved */
2361 	ushort reserved43;	/* 43 reserved */
2362 	ushort reserved44;	/* 44 reserved */
2363 	ushort reserved45;	/* 45 reserved */
2364 	ushort reserved46;	/* 46 reserved */
2365 	ushort reserved47;	/* 47 reserved */
2366 	ushort reserved48;	/* 48 reserved */
2367 	ushort reserved49;	/* 49 reserved */
2368 	ushort reserved50;	/* 50 reserved */
2369 	ushort reserved51;	/* 51 reserved */
2370 	ushort reserved52;	/* 52 reserved */
2371 	ushort reserved53;	/* 53 reserved */
2372 	ushort reserved54;	/* 54 reserved */
2373 	ushort reserved55;	/* 55 reserved */
2374 	ushort cisptr_lsw;	/* 56 CIS PTR LSW */
2375 	ushort cisprt_msw;	/* 57 CIS PTR MSW */
2376 	ushort subsysvid;	/* 58 SubSystem Vendor ID */
2377 	ushort subsysid;	/* 59 SubSystem ID */
2378 	ushort reserved60;	/* 60 reserved */
2379 	ushort reserved61;	/* 61 reserved */
2380 	ushort reserved62;	/* 62 reserved */
2381 	ushort reserved63;	/* 63 reserved */
2382 } ADVEEP_38C1600_CONFIG;
2383 
2384 /*
2385  * EEPROM Commands
2386  */
2387 #define ASC_EEP_CMD_DONE             0x0200
2388 #define ASC_EEP_CMD_DONE_ERR         0x0001
2389 
2390 /* cfg_word */
2391 #define EEP_CFG_WORD_BIG_ENDIAN      0x8000
2392 
2393 /* bios_ctrl */
2394 #define BIOS_CTRL_BIOS               0x0001
2395 #define BIOS_CTRL_EXTENDED_XLAT      0x0002
2396 #define BIOS_CTRL_GT_2_DISK          0x0004
2397 #define BIOS_CTRL_BIOS_REMOVABLE     0x0008
2398 #define BIOS_CTRL_BOOTABLE_CD        0x0010
2399 #define BIOS_CTRL_MULTIPLE_LUN       0x0040
2400 #define BIOS_CTRL_DISPLAY_MSG        0x0080
2401 #define BIOS_CTRL_NO_SCAM            0x0100
2402 #define BIOS_CTRL_RESET_SCSI_BUS     0x0200
2403 #define BIOS_CTRL_INIT_VERBOSE       0x0800
2404 #define BIOS_CTRL_SCSI_PARITY        0x1000
2405 #define BIOS_CTRL_AIPP_DIS           0x2000
2406 
2407 #define ADV_3550_MEMSIZE   0x2000	/* 8 KB Internal Memory */
2408 #define ADV_3550_IOLEN     0x40	/* I/O Port Range in bytes */
2409 
2410 #define ADV_38C0800_MEMSIZE  0x4000	/* 16 KB Internal Memory */
2411 #define ADV_38C0800_IOLEN    0x100	/* I/O Port Range in bytes */
2412 
2413 /*
2414  * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
2415  * a special 16K Adv Library and Microcode version. After the issue is
2416  * resolved, should restore 32K support.
2417  *
2418  * #define ADV_38C1600_MEMSIZE  0x8000L   * 32 KB Internal Memory *
2419  */
2420 #define ADV_38C1600_MEMSIZE  0x4000	/* 16 KB Internal Memory */
2421 #define ADV_38C1600_IOLEN    0x100	/* I/O Port Range 256 bytes */
2422 #define ADV_38C1600_MEMLEN   0x1000	/* Memory Range 4KB bytes */
2423 
2424 /*
2425  * Byte I/O register address from base of 'iop_base'.
2426  */
2427 #define IOPB_INTR_STATUS_REG    0x00
2428 #define IOPB_CHIP_ID_1          0x01
2429 #define IOPB_INTR_ENABLES       0x02
2430 #define IOPB_CHIP_TYPE_REV      0x03
2431 #define IOPB_RES_ADDR_4         0x04
2432 #define IOPB_RES_ADDR_5         0x05
2433 #define IOPB_RAM_DATA           0x06
2434 #define IOPB_RES_ADDR_7         0x07
2435 #define IOPB_FLAG_REG           0x08
2436 #define IOPB_RES_ADDR_9         0x09
2437 #define IOPB_RISC_CSR           0x0A
2438 #define IOPB_RES_ADDR_B         0x0B
2439 #define IOPB_RES_ADDR_C         0x0C
2440 #define IOPB_RES_ADDR_D         0x0D
2441 #define IOPB_SOFT_OVER_WR       0x0E
2442 #define IOPB_RES_ADDR_F         0x0F
2443 #define IOPB_MEM_CFG            0x10
2444 #define IOPB_RES_ADDR_11        0x11
2445 #define IOPB_GPIO_DATA          0x12
2446 #define IOPB_RES_ADDR_13        0x13
2447 #define IOPB_FLASH_PAGE         0x14
2448 #define IOPB_RES_ADDR_15        0x15
2449 #define IOPB_GPIO_CNTL          0x16
2450 #define IOPB_RES_ADDR_17        0x17
2451 #define IOPB_FLASH_DATA         0x18
2452 #define IOPB_RES_ADDR_19        0x19
2453 #define IOPB_RES_ADDR_1A        0x1A
2454 #define IOPB_RES_ADDR_1B        0x1B
2455 #define IOPB_RES_ADDR_1C        0x1C
2456 #define IOPB_RES_ADDR_1D        0x1D
2457 #define IOPB_RES_ADDR_1E        0x1E
2458 #define IOPB_RES_ADDR_1F        0x1F
2459 #define IOPB_DMA_CFG0           0x20
2460 #define IOPB_DMA_CFG1           0x21
2461 #define IOPB_TICKLE             0x22
2462 #define IOPB_DMA_REG_WR         0x23
2463 #define IOPB_SDMA_STATUS        0x24
2464 #define IOPB_SCSI_BYTE_CNT      0x25
2465 #define IOPB_HOST_BYTE_CNT      0x26
2466 #define IOPB_BYTE_LEFT_TO_XFER  0x27
2467 #define IOPB_BYTE_TO_XFER_0     0x28
2468 #define IOPB_BYTE_TO_XFER_1     0x29
2469 #define IOPB_BYTE_TO_XFER_2     0x2A
2470 #define IOPB_BYTE_TO_XFER_3     0x2B
2471 #define IOPB_ACC_GRP            0x2C
2472 #define IOPB_RES_ADDR_2D        0x2D
2473 #define IOPB_DEV_ID             0x2E
2474 #define IOPB_RES_ADDR_2F        0x2F
2475 #define IOPB_SCSI_DATA          0x30
2476 #define IOPB_RES_ADDR_31        0x31
2477 #define IOPB_RES_ADDR_32        0x32
2478 #define IOPB_SCSI_DATA_HSHK     0x33
2479 #define IOPB_SCSI_CTRL          0x34
2480 #define IOPB_RES_ADDR_35        0x35
2481 #define IOPB_RES_ADDR_36        0x36
2482 #define IOPB_RES_ADDR_37        0x37
2483 #define IOPB_RAM_BIST           0x38
2484 #define IOPB_PLL_TEST           0x39
2485 #define IOPB_PCI_INT_CFG        0x3A
2486 #define IOPB_RES_ADDR_3B        0x3B
2487 #define IOPB_RFIFO_CNT          0x3C
2488 #define IOPB_RES_ADDR_3D        0x3D
2489 #define IOPB_RES_ADDR_3E        0x3E
2490 #define IOPB_RES_ADDR_3F        0x3F
2491 
2492 /*
2493  * Word I/O register address from base of 'iop_base'.
2494  */
2495 #define IOPW_CHIP_ID_0          0x00	/* CID0  */
2496 #define IOPW_CTRL_REG           0x02	/* CC    */
2497 #define IOPW_RAM_ADDR           0x04	/* LA    */
2498 #define IOPW_RAM_DATA           0x06	/* LD    */
2499 #define IOPW_RES_ADDR_08        0x08
2500 #define IOPW_RISC_CSR           0x0A	/* CSR   */
2501 #define IOPW_SCSI_CFG0          0x0C	/* CFG0  */
2502 #define IOPW_SCSI_CFG1          0x0E	/* CFG1  */
2503 #define IOPW_RES_ADDR_10        0x10
2504 #define IOPW_SEL_MASK           0x12	/* SM    */
2505 #define IOPW_RES_ADDR_14        0x14
2506 #define IOPW_FLASH_ADDR         0x16	/* FA    */
2507 #define IOPW_RES_ADDR_18        0x18
2508 #define IOPW_EE_CMD             0x1A	/* EC    */
2509 #define IOPW_EE_DATA            0x1C	/* ED    */
2510 #define IOPW_SFIFO_CNT          0x1E	/* SFC   */
2511 #define IOPW_RES_ADDR_20        0x20
2512 #define IOPW_Q_BASE             0x22	/* QB    */
2513 #define IOPW_QP                 0x24	/* QP    */
2514 #define IOPW_IX                 0x26	/* IX    */
2515 #define IOPW_SP                 0x28	/* SP    */
2516 #define IOPW_PC                 0x2A	/* PC    */
2517 #define IOPW_RES_ADDR_2C        0x2C
2518 #define IOPW_RES_ADDR_2E        0x2E
2519 #define IOPW_SCSI_DATA          0x30	/* SD    */
2520 #define IOPW_SCSI_DATA_HSHK     0x32	/* SDH   */
2521 #define IOPW_SCSI_CTRL          0x34	/* SC    */
2522 #define IOPW_HSHK_CFG           0x36	/* HCFG  */
2523 #define IOPW_SXFR_STATUS        0x36	/* SXS   */
2524 #define IOPW_SXFR_CNTL          0x38	/* SXL   */
2525 #define IOPW_SXFR_CNTH          0x3A	/* SXH   */
2526 #define IOPW_RES_ADDR_3C        0x3C
2527 #define IOPW_RFIFO_DATA         0x3E	/* RFD   */
2528 
2529 /*
2530  * Doubleword I/O register address from base of 'iop_base'.
2531  */
2532 #define IOPDW_RES_ADDR_0         0x00
2533 #define IOPDW_RAM_DATA           0x04
2534 #define IOPDW_RES_ADDR_8         0x08
2535 #define IOPDW_RES_ADDR_C         0x0C
2536 #define IOPDW_RES_ADDR_10        0x10
2537 #define IOPDW_COMMA              0x14
2538 #define IOPDW_COMMB              0x18
2539 #define IOPDW_RES_ADDR_1C        0x1C
2540 #define IOPDW_SDMA_ADDR0         0x20
2541 #define IOPDW_SDMA_ADDR1         0x24
2542 #define IOPDW_SDMA_COUNT         0x28
2543 #define IOPDW_SDMA_ERROR         0x2C
2544 #define IOPDW_RDMA_ADDR0         0x30
2545 #define IOPDW_RDMA_ADDR1         0x34
2546 #define IOPDW_RDMA_COUNT         0x38
2547 #define IOPDW_RDMA_ERROR         0x3C
2548 
2549 #define ADV_CHIP_ID_BYTE         0x25
2550 #define ADV_CHIP_ID_WORD         0x04C1
2551 
2552 #define ADV_SC_SCSI_BUS_RESET    0x2000
2553 
2554 #define ADV_INTR_ENABLE_HOST_INTR                   0x01
2555 #define ADV_INTR_ENABLE_SEL_INTR                    0x02
2556 #define ADV_INTR_ENABLE_DPR_INTR                    0x04
2557 #define ADV_INTR_ENABLE_RTA_INTR                    0x08
2558 #define ADV_INTR_ENABLE_RMA_INTR                    0x10
2559 #define ADV_INTR_ENABLE_RST_INTR                    0x20
2560 #define ADV_INTR_ENABLE_DPE_INTR                    0x40
2561 #define ADV_INTR_ENABLE_GLOBAL_INTR                 0x80
2562 
2563 #define ADV_INTR_STATUS_INTRA            0x01
2564 #define ADV_INTR_STATUS_INTRB            0x02
2565 #define ADV_INTR_STATUS_INTRC            0x04
2566 
2567 #define ADV_RISC_CSR_STOP           (0x0000)
2568 #define ADV_RISC_TEST_COND          (0x2000)
2569 #define ADV_RISC_CSR_RUN            (0x4000)
2570 #define ADV_RISC_CSR_SINGLE_STEP    (0x8000)
2571 
2572 #define ADV_CTRL_REG_HOST_INTR      0x0100
2573 #define ADV_CTRL_REG_SEL_INTR       0x0200
2574 #define ADV_CTRL_REG_DPR_INTR       0x0400
2575 #define ADV_CTRL_REG_RTA_INTR       0x0800
2576 #define ADV_CTRL_REG_RMA_INTR       0x1000
2577 #define ADV_CTRL_REG_RES_BIT14      0x2000
2578 #define ADV_CTRL_REG_DPE_INTR       0x4000
2579 #define ADV_CTRL_REG_POWER_DONE     0x8000
2580 #define ADV_CTRL_REG_ANY_INTR       0xFF00
2581 
2582 #define ADV_CTRL_REG_CMD_RESET             0x00C6
2583 #define ADV_CTRL_REG_CMD_WR_IO_REG         0x00C5
2584 #define ADV_CTRL_REG_CMD_RD_IO_REG         0x00C4
2585 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE  0x00C3
2586 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE  0x00C2
2587 
2588 #define ADV_TICKLE_NOP                      0x00
2589 #define ADV_TICKLE_A                        0x01
2590 #define ADV_TICKLE_B                        0x02
2591 #define ADV_TICKLE_C                        0x03
2592 
2593 #define ADV_SCSI_CTRL_RSTOUT        0x2000
2594 
2595 #define AdvIsIntPending(port) \
2596     (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2597 
2598 /*
2599  * SCSI_CFG0 Register bit definitions
2600  */
2601 #define TIMER_MODEAB    0xC000	/* Watchdog, Second, and Select. Timer Ctrl. */
2602 #define PARITY_EN       0x2000	/* Enable SCSI Parity Error detection */
2603 #define EVEN_PARITY     0x1000	/* Select Even Parity */
2604 #define WD_LONG         0x0800	/* Watchdog Interval, 1: 57 min, 0: 13 sec */
2605 #define QUEUE_128       0x0400	/* Queue Size, 1: 128 byte, 0: 64 byte */
2606 #define PRIM_MODE       0x0100	/* Primitive SCSI mode */
2607 #define SCAM_EN         0x0080	/* Enable SCAM selection */
2608 #define SEL_TMO_LONG    0x0040	/* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2609 #define CFRM_ID         0x0020	/* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2610 #define OUR_ID_EN       0x0010	/* Enable OUR_ID bits */
2611 #define OUR_ID          0x000F	/* SCSI ID */
2612 
2613 /*
2614  * SCSI_CFG1 Register bit definitions
2615  */
2616 #define BIG_ENDIAN      0x8000	/* Enable Big Endian Mode MIO:15, EEP:15 */
2617 #define TERM_POL        0x2000	/* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2618 #define SLEW_RATE       0x1000	/* SCSI output buffer slew rate */
2619 #define FILTER_SEL      0x0C00	/* Filter Period Selection */
2620 #define  FLTR_DISABLE    0x0000	/* Input Filtering Disabled */
2621 #define  FLTR_11_TO_20NS 0x0800	/* Input Filtering 11ns to 20ns */
2622 #define  FLTR_21_TO_39NS 0x0C00	/* Input Filtering 21ns to 39ns */
2623 #define ACTIVE_DBL      0x0200	/* Disable Active Negation */
2624 #define DIFF_MODE       0x0100	/* SCSI differential Mode (Read-Only) */
2625 #define DIFF_SENSE      0x0080	/* 1: No SE cables, 0: SE cable (Read-Only) */
2626 #define TERM_CTL_SEL    0x0040	/* Enable TERM_CTL_H and TERM_CTL_L */
2627 #define TERM_CTL        0x0030	/* External SCSI Termination Bits */
2628 #define  TERM_CTL_H      0x0020	/* Enable External SCSI Upper Termination */
2629 #define  TERM_CTL_L      0x0010	/* Enable External SCSI Lower Termination */
2630 #define CABLE_DETECT    0x000F	/* External SCSI Cable Connection Status */
2631 
2632 /*
2633  * Addendum for ASC-38C0800 Chip
2634  *
2635  * The ASC-38C1600 Chip uses the same definitions except that the
2636  * bus mode override bits [12:10] have been moved to byte register
2637  * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
2638  * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
2639  * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
2640  * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
2641  * and [1:0]. Bits [14], [7:6], [3:2] are unused.
2642  */
2643 #define DIS_TERM_DRV    0x4000	/* 1: Read c_det[3:0], 0: cannot read */
2644 #define HVD_LVD_SE      0x1C00	/* Device Detect Bits */
2645 #define  HVD             0x1000	/* HVD Device Detect */
2646 #define  LVD             0x0800	/* LVD Device Detect */
2647 #define  SE              0x0400	/* SE Device Detect */
2648 #define TERM_LVD        0x00C0	/* LVD Termination Bits */
2649 #define  TERM_LVD_HI     0x0080	/* Enable LVD Upper Termination */
2650 #define  TERM_LVD_LO     0x0040	/* Enable LVD Lower Termination */
2651 #define TERM_SE         0x0030	/* SE Termination Bits */
2652 #define  TERM_SE_HI      0x0020	/* Enable SE Upper Termination */
2653 #define  TERM_SE_LO      0x0010	/* Enable SE Lower Termination */
2654 #define C_DET_LVD       0x000C	/* LVD Cable Detect Bits */
2655 #define  C_DET3          0x0008	/* Cable Detect for LVD External Wide */
2656 #define  C_DET2          0x0004	/* Cable Detect for LVD Internal Wide */
2657 #define C_DET_SE        0x0003	/* SE Cable Detect Bits */
2658 #define  C_DET1          0x0002	/* Cable Detect for SE Internal Wide */
2659 #define  C_DET0          0x0001	/* Cable Detect for SE Internal Narrow */
2660 
2661 #define CABLE_ILLEGAL_A 0x7
2662     /* x 0 0 0  | on  on | Illegal (all 3 connectors are used) */
2663 
2664 #define CABLE_ILLEGAL_B 0xB
2665     /* 0 x 0 0  | on  on | Illegal (all 3 connectors are used) */
2666 
2667 /*
2668  * MEM_CFG Register bit definitions
2669  */
2670 #define BIOS_EN         0x40	/* BIOS Enable MIO:14,EEP:14 */
2671 #define FAST_EE_CLK     0x20	/* Diagnostic Bit */
2672 #define RAM_SZ          0x1C	/* Specify size of RAM to RISC */
2673 #define  RAM_SZ_2KB      0x00	/* 2 KB */
2674 #define  RAM_SZ_4KB      0x04	/* 4 KB */
2675 #define  RAM_SZ_8KB      0x08	/* 8 KB */
2676 #define  RAM_SZ_16KB     0x0C	/* 16 KB */
2677 #define  RAM_SZ_32KB     0x10	/* 32 KB */
2678 #define  RAM_SZ_64KB     0x14	/* 64 KB */
2679 
2680 /*
2681  * DMA_CFG0 Register bit definitions
2682  *
2683  * This register is only accessible to the host.
2684  */
2685 #define BC_THRESH_ENB   0x80	/* PCI DMA Start Conditions */
2686 #define FIFO_THRESH     0x70	/* PCI DMA FIFO Threshold */
2687 #define  FIFO_THRESH_16B  0x00	/* 16 bytes */
2688 #define  FIFO_THRESH_32B  0x20	/* 32 bytes */
2689 #define  FIFO_THRESH_48B  0x30	/* 48 bytes */
2690 #define  FIFO_THRESH_64B  0x40	/* 64 bytes */
2691 #define  FIFO_THRESH_80B  0x50	/* 80 bytes (default) */
2692 #define  FIFO_THRESH_96B  0x60	/* 96 bytes */
2693 #define  FIFO_THRESH_112B 0x70	/* 112 bytes */
2694 #define START_CTL       0x0C	/* DMA start conditions */
2695 #define  START_CTL_TH    0x00	/* Wait threshold level (default) */
2696 #define  START_CTL_ID    0x04	/* Wait SDMA/SBUS idle */
2697 #define  START_CTL_THID  0x08	/* Wait threshold and SDMA/SBUS idle */
2698 #define  START_CTL_EMFU  0x0C	/* Wait SDMA FIFO empty/full */
2699 #define READ_CMD        0x03	/* Memory Read Method */
2700 #define  READ_CMD_MR     0x00	/* Memory Read */
2701 #define  READ_CMD_MRL    0x02	/* Memory Read Long */
2702 #define  READ_CMD_MRM    0x03	/* Memory Read Multiple (default) */
2703 
2704 /*
2705  * ASC-38C0800 RAM BIST Register bit definitions
2706  */
2707 #define RAM_TEST_MODE         0x80
2708 #define PRE_TEST_MODE         0x40
2709 #define NORMAL_MODE           0x00
2710 #define RAM_TEST_DONE         0x10
2711 #define RAM_TEST_STATUS       0x0F
2712 #define  RAM_TEST_HOST_ERROR   0x08
2713 #define  RAM_TEST_INTRAM_ERROR 0x04
2714 #define  RAM_TEST_RISC_ERROR   0x02
2715 #define  RAM_TEST_SCSI_ERROR   0x01
2716 #define  RAM_TEST_SUCCESS      0x00
2717 #define PRE_TEST_VALUE        0x05
2718 #define NORMAL_VALUE          0x00
2719 
2720 /*
2721  * ASC38C1600 Definitions
2722  *
2723  * IOPB_PCI_INT_CFG Bit Field Definitions
2724  */
2725 
2726 #define INTAB_LD        0x80	/* Value loaded from EEPROM Bit 11. */
2727 
2728 /*
2729  * Bit 1 can be set to change the interrupt for the Function to operate in
2730  * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
2731  * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
2732  * mode, otherwise the operating mode is undefined.
2733  */
2734 #define TOTEMPOLE       0x02
2735 
2736 /*
2737  * Bit 0 can be used to change the Int Pin for the Function. The value is
2738  * 0 by default for both Functions with Function 0 using INT A and Function
2739  * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
2740  * INT A is used.
2741  *
2742  * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
2743  * value specified in the PCI Configuration Space.
2744  */
2745 #define INTAB           0x01
2746 
2747 /* a_advlib.h */
2748 
2749 /*
2750  * Adv Library Status Definitions
2751  */
2752 #define ADV_TRUE        1
2753 #define ADV_FALSE       0
2754 #define ADV_NOERROR     1
2755 #define ADV_SUCCESS     1
2756 #define ADV_BUSY        0
2757 #define ADV_ERROR       (-1)
2758 
2759 /*
2760  * ADV_DVC_VAR 'warn_code' values
2761  */
2762 #define ASC_WARN_BUSRESET_ERROR         0x0001	/* SCSI Bus Reset error */
2763 #define ASC_WARN_EEPROM_CHKSUM          0x0002	/* EEP check sum error */
2764 #define ASC_WARN_EEPROM_TERMINATION     0x0004	/* EEP termination bad field */
2765 #define ASC_WARN_SET_PCI_CONFIG_SPACE   0x0080	/* PCI config space set error */
2766 #define ASC_WARN_ERROR                  0xFFFF	/* ADV_ERROR return */
2767 
2768 #define ADV_MAX_TID                     15	/* max. target identifier */
2769 #define ADV_MAX_LUN                     7	/* max. logical unit number */
2770 
2771 /*
2772  * Error code values are set in ADV_DVC_VAR 'err_code'.
2773  */
2774 #define ASC_IERR_WRITE_EEPROM       0x0001	/* write EEPROM error */
2775 #define ASC_IERR_MCODE_CHKSUM       0x0002	/* micro code check sum error */
2776 #define ASC_IERR_NO_CARRIER         0x0004	/* No more carrier memory. */
2777 #define ASC_IERR_START_STOP_CHIP    0x0008	/* start/stop chip failed */
2778 #define ASC_IERR_CHIP_VERSION       0x0040	/* wrong chip version */
2779 #define ASC_IERR_SET_SCSI_ID        0x0080	/* set SCSI ID failed */
2780 #define ASC_IERR_HVD_DEVICE         0x0100	/* HVD attached to LVD connector. */
2781 #define ASC_IERR_BAD_SIGNATURE      0x0200	/* signature not found */
2782 #define ASC_IERR_ILLEGAL_CONNECTION 0x0400	/* Illegal cable connection */
2783 #define ASC_IERR_SINGLE_END_DEVICE  0x0800	/* Single-end used w/differential */
2784 #define ASC_IERR_REVERSED_CABLE     0x1000	/* Narrow flat cable reversed */
2785 #define ASC_IERR_BIST_PRE_TEST      0x2000	/* BIST pre-test error */
2786 #define ASC_IERR_BIST_RAM_TEST      0x4000	/* BIST RAM test error */
2787 #define ASC_IERR_BAD_CHIPTYPE       0x8000	/* Invalid 'chip_type' setting. */
2788 
2789 /*
2790  * Fixed locations of microcode operating variables.
2791  */
2792 #define ASC_MC_CODE_BEGIN_ADDR          0x0028	/* microcode start address */
2793 #define ASC_MC_CODE_END_ADDR            0x002A	/* microcode end address */
2794 #define ASC_MC_CODE_CHK_SUM             0x002C	/* microcode code checksum */
2795 #define ASC_MC_VERSION_DATE             0x0038	/* microcode version */
2796 #define ASC_MC_VERSION_NUM              0x003A	/* microcode number */
2797 #define ASC_MC_BIOSMEM                  0x0040	/* BIOS RISC Memory Start */
2798 #define ASC_MC_BIOSLEN                  0x0050	/* BIOS RISC Memory Length */
2799 #define ASC_MC_BIOS_SIGNATURE           0x0058	/* BIOS Signature 0x55AA */
2800 #define ASC_MC_BIOS_VERSION             0x005A	/* BIOS Version (2 bytes) */
2801 #define ASC_MC_SDTR_SPEED1              0x0090	/* SDTR Speed for TID 0-3 */
2802 #define ASC_MC_SDTR_SPEED2              0x0092	/* SDTR Speed for TID 4-7 */
2803 #define ASC_MC_SDTR_SPEED3              0x0094	/* SDTR Speed for TID 8-11 */
2804 #define ASC_MC_SDTR_SPEED4              0x0096	/* SDTR Speed for TID 12-15 */
2805 #define ASC_MC_CHIP_TYPE                0x009A
2806 #define ASC_MC_INTRB_CODE               0x009B
2807 #define ASC_MC_WDTR_ABLE                0x009C
2808 #define ASC_MC_SDTR_ABLE                0x009E
2809 #define ASC_MC_TAGQNG_ABLE              0x00A0
2810 #define ASC_MC_DISC_ENABLE              0x00A2
2811 #define ASC_MC_IDLE_CMD_STATUS          0x00A4
2812 #define ASC_MC_IDLE_CMD                 0x00A6
2813 #define ASC_MC_IDLE_CMD_PARAMETER       0x00A8
2814 #define ASC_MC_DEFAULT_SCSI_CFG0        0x00AC
2815 #define ASC_MC_DEFAULT_SCSI_CFG1        0x00AE
2816 #define ASC_MC_DEFAULT_MEM_CFG          0x00B0
2817 #define ASC_MC_DEFAULT_SEL_MASK         0x00B2
2818 #define ASC_MC_SDTR_DONE                0x00B6
2819 #define ASC_MC_NUMBER_OF_QUEUED_CMD     0x00C0
2820 #define ASC_MC_NUMBER_OF_MAX_CMD        0x00D0
2821 #define ASC_MC_DEVICE_HSHK_CFG_TABLE    0x0100
2822 #define ASC_MC_CONTROL_FLAG             0x0122	/* Microcode control flag. */
2823 #define ASC_MC_WDTR_DONE                0x0124
2824 #define ASC_MC_CAM_MODE_MASK            0x015E	/* CAM mode TID bitmask. */
2825 #define ASC_MC_ICQ                      0x0160
2826 #define ASC_MC_IRQ                      0x0164
2827 #define ASC_MC_PPR_ABLE                 0x017A
2828 
2829 /*
2830  * BIOS LRAM variable absolute offsets.
2831  */
2832 #define BIOS_CODESEG    0x54
2833 #define BIOS_CODELEN    0x56
2834 #define BIOS_SIGNATURE  0x58
2835 #define BIOS_VERSION    0x5A
2836 
2837 /*
2838  * Microcode Control Flags
2839  *
2840  * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2841  * and handled by the microcode.
2842  */
2843 #define CONTROL_FLAG_IGNORE_PERR        0x0001	/* Ignore DMA Parity Errors */
2844 #define CONTROL_FLAG_ENABLE_AIPP        0x0002	/* Enabled AIPP checking. */
2845 
2846 /*
2847  * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2848  */
2849 #define HSHK_CFG_WIDE_XFR       0x8000
2850 #define HSHK_CFG_RATE           0x0F00
2851 #define HSHK_CFG_OFFSET         0x001F
2852 
2853 #define ASC_DEF_MAX_HOST_QNG    0xFD	/* Max. number of host commands (253) */
2854 #define ASC_DEF_MIN_HOST_QNG    0x10	/* Min. number of host commands (16) */
2855 #define ASC_DEF_MAX_DVC_QNG     0x3F	/* Max. number commands per device (63) */
2856 #define ASC_DEF_MIN_DVC_QNG     0x04	/* Min. number commands per device (4) */
2857 
2858 #define ASC_QC_DATA_CHECK  0x01	/* Require ASC_QC_DATA_OUT set or clear. */
2859 #define ASC_QC_DATA_OUT    0x02	/* Data out DMA transfer. */
2860 #define ASC_QC_START_MOTOR 0x04	/* Send auto-start motor before request. */
2861 #define ASC_QC_NO_OVERRUN  0x08	/* Don't report overrun. */
2862 #define ASC_QC_FREEZE_TIDQ 0x10	/* Freeze TID queue after request. XXX TBD */
2863 
2864 #define ASC_QSC_NO_DISC     0x01	/* Don't allow disconnect for request. */
2865 #define ASC_QSC_NO_TAGMSG   0x02	/* Don't allow tag queuing for request. */
2866 #define ASC_QSC_NO_SYNC     0x04	/* Don't use Synch. transfer on request. */
2867 #define ASC_QSC_NO_WIDE     0x08	/* Don't use Wide transfer on request. */
2868 #define ASC_QSC_REDO_DTR    0x10	/* Renegotiate WDTR/SDTR before request. */
2869 /*
2870  * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
2871  * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
2872  */
2873 #define ASC_QSC_HEAD_TAG    0x40	/* Use Head Tag Message (0x21). */
2874 #define ASC_QSC_ORDERED_TAG 0x80	/* Use Ordered Tag Message (0x22). */
2875 
2876 /*
2877  * All fields here are accessed by the board microcode and need to be
2878  * little-endian.
2879  */
2880 typedef struct adv_carr_t {
2881 	ADV_VADDR carr_va;	/* Carrier Virtual Address */
2882 	ADV_PADDR carr_pa;	/* Carrier Physical Address */
2883 	ADV_VADDR areq_vpa;	/* ASC_SCSI_REQ_Q Virtual or Physical Address */
2884 	/*
2885 	 * next_vpa [31:4]            Carrier Virtual or Physical Next Pointer
2886 	 *
2887 	 * next_vpa [3:1]             Reserved Bits
2888 	 * next_vpa [0]               Done Flag set in Response Queue.
2889 	 */
2890 	ADV_VADDR next_vpa;
2891 } ADV_CARR_T;
2892 
2893 /*
2894  * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2895  */
2896 #define ASC_NEXT_VPA_MASK       0xFFFFFFF0
2897 
2898 #define ASC_RQ_DONE             0x00000001
2899 #define ASC_RQ_GOOD             0x00000002
2900 #define ASC_CQ_STOPPER          0x00000000
2901 
2902 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2903 
2904 #define ADV_CARRIER_NUM_PAGE_CROSSING \
2905     (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2906         (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2907 
2908 #define ADV_CARRIER_BUFSIZE \
2909     ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2910 
2911 /*
2912  * ASC_SCSI_REQ_Q 'a_flag' definitions
2913  *
2914  * The Adv Library should limit use to the lower nibble (4 bits) of
2915  * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2916  */
2917 #define ADV_POLL_REQUEST                0x01	/* poll for request completion */
2918 #define ADV_SCSIQ_DONE                  0x02	/* request done */
2919 #define ADV_DONT_RETRY                  0x08	/* don't do retry */
2920 
2921 #define ADV_CHIP_ASC3550          0x01	/* Ultra-Wide IC */
2922 #define ADV_CHIP_ASC38C0800       0x02	/* Ultra2-Wide/LVD IC */
2923 #define ADV_CHIP_ASC38C1600       0x03	/* Ultra3-Wide/LVD2 IC */
2924 
2925 /*
2926  * Adapter temporary configuration structure
2927  *
2928  * This structure can be discarded after initialization. Don't add
2929  * fields here needed after initialization.
2930  *
2931  * Field naming convention:
2932  *
2933  *  *_enable indicates the field enables or disables a feature. The
2934  *  value of the field is never reset.
2935  */
2936 typedef struct adv_dvc_cfg {
2937 	ushort disc_enable;	/* enable disconnection */
2938 	uchar chip_version;	/* chip version */
2939 	uchar termination;	/* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2940 	ushort lib_version;	/* Adv Library version number */
2941 	ushort control_flag;	/* Microcode Control Flag */
2942 	ushort mcode_date;	/* Microcode date */
2943 	ushort mcode_version;	/* Microcode version */
2944 	ushort pci_slot_info;	/* high byte device/function number */
2945 	/* bits 7-3 device num., bits 2-0 function num. */
2946 	/* low byte bus num. */
2947 	ushort serial1;		/* EEPROM serial number word 1 */
2948 	ushort serial2;		/* EEPROM serial number word 2 */
2949 	ushort serial3;		/* EEPROM serial number word 3 */
2950 	struct device *dev;	/* pointer to the pci dev structure for this board */
2951 } ADV_DVC_CFG;
2952 
2953 struct adv_dvc_var;
2954 struct adv_scsi_req_q;
2955 
2956 typedef void (*ADV_ISR_CALLBACK)
2957  (struct adv_dvc_var *, struct adv_scsi_req_q *);
2958 
2959 typedef void (*ADV_ASYNC_CALLBACK)
2960  (struct adv_dvc_var *, uchar);
2961 
2962 /*
2963  * Adapter operation variable structure.
2964  *
2965  * One structure is required per host adapter.
2966  *
2967  * Field naming convention:
2968  *
2969  *  *_able indicates both whether a feature should be enabled or disabled
2970  *  and whether a device isi capable of the feature. At initialization
2971  *  this field may be set, but later if a device is found to be incapable
2972  *  of the feature, the field is cleared.
2973  */
2974 typedef struct adv_dvc_var {
2975 	AdvPortAddr iop_base;	/* I/O port address */
2976 	ushort err_code;	/* fatal error code */
2977 	ushort bios_ctrl;	/* BIOS control word, EEPROM word 12 */
2978 	ADV_ISR_CALLBACK isr_callback;
2979 	ADV_ASYNC_CALLBACK async_callback;
2980 	ushort wdtr_able;	/* try WDTR for a device */
2981 	ushort sdtr_able;	/* try SDTR for a device */
2982 	ushort ultra_able;	/* try SDTR Ultra speed for a device */
2983 	ushort sdtr_speed1;	/* EEPROM SDTR Speed for TID 0-3   */
2984 	ushort sdtr_speed2;	/* EEPROM SDTR Speed for TID 4-7   */
2985 	ushort sdtr_speed3;	/* EEPROM SDTR Speed for TID 8-11  */
2986 	ushort sdtr_speed4;	/* EEPROM SDTR Speed for TID 12-15 */
2987 	ushort tagqng_able;	/* try tagged queuing with a device */
2988 	ushort ppr_able;	/* PPR message capable per TID bitmask. */
2989 	uchar max_dvc_qng;	/* maximum number of tagged commands per device */
2990 	ushort start_motor;	/* start motor command allowed */
2991 	uchar scsi_reset_wait;	/* delay in seconds after scsi bus reset */
2992 	uchar chip_no;		/* should be assigned by caller */
2993 	uchar max_host_qng;	/* maximum number of Q'ed command allowed */
2994 	uchar irq_no;		/* IRQ number */
2995 	ushort no_scam;		/* scam_tolerant of EEPROM */
2996 	struct asc_board *drv_ptr;	/* driver pointer to private structure */
2997 	uchar chip_scsi_id;	/* chip SCSI target ID */
2998 	uchar chip_type;
2999 	uchar bist_err_code;
3000 	ADV_CARR_T *carrier_buf;
3001 	ADV_CARR_T *carr_freelist;	/* Carrier free list. */
3002 	ADV_CARR_T *icq_sp;	/* Initiator command queue stopper pointer. */
3003 	ADV_CARR_T *irq_sp;	/* Initiator response queue stopper pointer. */
3004 	ushort carr_pending_cnt;	/* Count of pending carriers. */
3005 	/*
3006 	 * Note: The following fields will not be used after initialization. The
3007 	 * driver may discard the buffer after initialization is done.
3008 	 */
3009 	ADV_DVC_CFG *cfg;	/* temporary configuration structure  */
3010 } ADV_DVC_VAR;
3011 
3012 #define NO_OF_SG_PER_BLOCK              15
3013 
3014 typedef struct asc_sg_block {
3015 	uchar reserved1;
3016 	uchar reserved2;
3017 	uchar reserved3;
3018 	uchar sg_cnt;		/* Valid entries in block. */
3019 	ADV_PADDR sg_ptr;	/* Pointer to next sg block. */
3020 	struct {
3021 		ADV_PADDR sg_addr;	/* SG element address. */
3022 		ADV_DCNT sg_count;	/* SG element count. */
3023 	} sg_list[NO_OF_SG_PER_BLOCK];
3024 } ADV_SG_BLOCK;
3025 
3026 /*
3027  * ADV_SCSI_REQ_Q - microcode request structure
3028  *
3029  * All fields in this structure up to byte 60 are used by the microcode.
3030  * The microcode makes assumptions about the size and ordering of fields
3031  * in this structure. Do not change the structure definition here without
3032  * coordinating the change with the microcode.
3033  *
3034  * All fields accessed by microcode must be maintained in little_endian
3035  * order.
3036  */
3037 typedef struct adv_scsi_req_q {
3038 	uchar cntl;		/* Ucode flags and state (ASC_MC_QC_*). */
3039 	uchar target_cmd;
3040 	uchar target_id;	/* Device target identifier. */
3041 	uchar target_lun;	/* Device target logical unit number. */
3042 	ADV_PADDR data_addr;	/* Data buffer physical address. */
3043 	ADV_DCNT data_cnt;	/* Data count. Ucode sets to residual. */
3044 	ADV_PADDR sense_addr;
3045 	ADV_PADDR carr_pa;
3046 	uchar mflag;
3047 	uchar sense_len;
3048 	uchar cdb_len;		/* SCSI CDB length. Must <= 16 bytes. */
3049 	uchar scsi_cntl;
3050 	uchar done_status;	/* Completion status. */
3051 	uchar scsi_status;	/* SCSI status byte. */
3052 	uchar host_status;	/* Ucode host status. */
3053 	uchar sg_working_ix;
3054 	uchar cdb[12];		/* SCSI CDB bytes 0-11. */
3055 	ADV_PADDR sg_real_addr;	/* SG list physical address. */
3056 	ADV_PADDR scsiq_rptr;
3057 	uchar cdb16[4];		/* SCSI CDB bytes 12-15. */
3058 	ADV_VADDR scsiq_ptr;
3059 	ADV_VADDR carr_va;
3060 	/*
3061 	 * End of microcode structure - 60 bytes. The rest of the structure
3062 	 * is used by the Adv Library and ignored by the microcode.
3063 	 */
3064 	ADV_VADDR srb_ptr;
3065 	ADV_SG_BLOCK *sg_list_ptr;	/* SG list virtual address. */
3066 	char *vdata_addr;	/* Data buffer virtual address. */
3067 	uchar a_flag;
3068 	uchar pad[2];		/* Pad out to a word boundary. */
3069 } ADV_SCSI_REQ_Q;
3070 
3071 /*
3072  * Microcode idle loop commands
3073  */
3074 #define IDLE_CMD_COMPLETED           0
3075 #define IDLE_CMD_STOP_CHIP           0x0001
3076 #define IDLE_CMD_STOP_CHIP_SEND_INT  0x0002
3077 #define IDLE_CMD_SEND_INT            0x0004
3078 #define IDLE_CMD_ABORT               0x0008
3079 #define IDLE_CMD_DEVICE_RESET        0x0010
3080 #define IDLE_CMD_SCSI_RESET_START    0x0020	/* Assert SCSI Bus Reset */
3081 #define IDLE_CMD_SCSI_RESET_END      0x0040	/* Deassert SCSI Bus Reset */
3082 #define IDLE_CMD_SCSIREQ             0x0080
3083 
3084 #define IDLE_CMD_STATUS_SUCCESS      0x0001
3085 #define IDLE_CMD_STATUS_FAILURE      0x0002
3086 
3087 /*
3088  * AdvSendIdleCmd() flag definitions.
3089  */
3090 #define ADV_NOWAIT     0x01
3091 
3092 /*
3093  * Wait loop time out values.
3094  */
3095 #define SCSI_WAIT_10_SEC             10UL	/* 10 seconds */
3096 #define SCSI_WAIT_100_MSEC           100UL	/* 100 milliseconds */
3097 #define SCSI_US_PER_MSEC             1000	/* microseconds per millisecond */
3098 #define SCSI_MS_PER_SEC              1000UL	/* milliseconds per second */
3099 #define SCSI_MAX_RETRY               10	/* retry count */
3100 
3101 #define ADV_ASYNC_RDMA_FAILURE          0x01	/* Fatal RDMA failure. */
3102 #define ADV_ASYNC_SCSI_BUS_RESET_DET    0x02	/* Detected SCSI Bus Reset. */
3103 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03	/* Carrier Ready failure. */
3104 #define ADV_RDMA_IN_CARR_AND_Q_INVALID  0x04	/* RDMAed-in data invalid. */
3105 
3106 #define ADV_HOST_SCSI_BUS_RESET      0x80	/* Host Initiated SCSI Bus Reset. */
3107 
3108 /*
3109  * Device drivers must define the following functions.
3110  */
3111 static inline ulong DvcEnterCritical(void);
3112 static inline void DvcLeaveCritical(ulong);
3113 static void DvcSleepMilliSecond(ADV_DCNT);
3114 static uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
3115 static void DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
3116 static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
3117 			       uchar *, ASC_SDCNT *, int);
3118 static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
3119 
3120 /*
3121  * Adv Library functions available to drivers.
3122  */
3123 static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3124 static int AdvISR(ADV_DVC_VAR *);
3125 static int AdvInitGetConfig(ADV_DVC_VAR *);
3126 static int AdvInitAsc3550Driver(ADV_DVC_VAR *);
3127 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
3128 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
3129 static int AdvResetChipAndSB(ADV_DVC_VAR *);
3130 static int AdvResetSB(ADV_DVC_VAR *asc_dvc);
3131 
3132 /*
3133  * Internal Adv Library functions.
3134  */
3135 static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
3136 static void AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3137 static int AdvInitFrom3550EEP(ADV_DVC_VAR *);
3138 static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
3139 static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
3140 static ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3141 static void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3142 static ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3143 static void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3144 static ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3145 static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3146 static void AdvWaitEEPCmd(AdvPortAddr);
3147 static ushort AdvReadEEPWord(AdvPortAddr, int);
3148 
3149 /*
3150  * PCI Bus Definitions
3151  */
3152 #define AscPCICmdRegBits_BusMastering     0x0007
3153 #define AscPCICmdRegBits_ParErrRespCtrl   0x0040
3154 
3155 /* Read byte from a register. */
3156 #define AdvReadByteRegister(iop_base, reg_off) \
3157      (ADV_MEM_READB((iop_base) + (reg_off)))
3158 
3159 /* Write byte to a register. */
3160 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
3161      (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3162 
3163 /* Read word (2 bytes) from a register. */
3164 #define AdvReadWordRegister(iop_base, reg_off) \
3165      (ADV_MEM_READW((iop_base) + (reg_off)))
3166 
3167 /* Write word (2 bytes) to a register. */
3168 #define AdvWriteWordRegister(iop_base, reg_off, word) \
3169      (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
3170 
3171 /* Write dword (4 bytes) to a register. */
3172 #define AdvWriteDWordRegister(iop_base, reg_off, dword) \
3173      (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
3174 
3175 /* Read byte from LRAM. */
3176 #define AdvReadByteLram(iop_base, addr, byte) \
3177 do { \
3178     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3179     (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3180 } while (0)
3181 
3182 /* Write byte to LRAM. */
3183 #define AdvWriteByteLram(iop_base, addr, byte) \
3184     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3185      ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3186 
3187 /* Read word (2 bytes) from LRAM. */
3188 #define AdvReadWordLram(iop_base, addr, word) \
3189 do { \
3190     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3191     (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3192 } while (0)
3193 
3194 /* Write word (2 bytes) to LRAM. */
3195 #define AdvWriteWordLram(iop_base, addr, word) \
3196     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3197      ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3198 
3199 /* Write little-endian double word (4 bytes) to LRAM */
3200 /* Because of unspecified C language ordering don't use auto-increment. */
3201 #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
3202     ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3203       ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3204                      cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3205      (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3206       ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3207                      cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3208 
3209 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
3210 #define AdvReadWordAutoIncLram(iop_base) \
3211      (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3212 
3213 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
3214 #define AdvWriteWordAutoIncLram(iop_base, word) \
3215      (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3216 
3217 /*
3218  * Define macro to check for Condor signature.
3219  *
3220  * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3221  * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3222  */
3223 #define AdvFindSignature(iop_base) \
3224     (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3225     ADV_CHIP_ID_BYTE) && \
3226      (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3227     ADV_CHIP_ID_WORD)) ?  ADV_TRUE : ADV_FALSE)
3228 
3229 /*
3230  * Define macro to Return the version number of the chip at 'iop_base'.
3231  *
3232  * The second parameter 'bus_type' is currently unused.
3233  */
3234 #define AdvGetChipVersion(iop_base, bus_type) \
3235     AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3236 
3237 /*
3238  * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3239  * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3240  *
3241  * If the request has not yet been sent to the device it will simply be
3242  * aborted from RISC memory. If the request is disconnected it will be
3243  * aborted on reselection by sending an Abort Message to the target ID.
3244  *
3245  * Return value:
3246  *      ADV_TRUE(1) - Queue was successfully aborted.
3247  *      ADV_FALSE(0) - Queue was not found on the active queue list.
3248  */
3249 #define AdvAbortQueue(asc_dvc, scsiq) \
3250         AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3251                        (ADV_DCNT) (scsiq))
3252 
3253 /*
3254  * Send a Bus Device Reset Message to the specified target ID.
3255  *
3256  * All outstanding commands will be purged if sending the
3257  * Bus Device Reset Message is successful.
3258  *
3259  * Return Value:
3260  *      ADV_TRUE(1) - All requests on the target are purged.
3261  *      ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3262  *                     are not purged.
3263  */
3264 #define AdvResetDevice(asc_dvc, target_id) \
3265         AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3266                     (ADV_DCNT) (target_id))
3267 
3268 /*
3269  * SCSI Wide Type definition.
3270  */
3271 #define ADV_SCSI_BIT_ID_TYPE   ushort
3272 
3273 /*
3274  * AdvInitScsiTarget() 'cntl_flag' options.
3275  */
3276 #define ADV_SCAN_LUN           0x01
3277 #define ADV_CAPINFO_NOLUN      0x02
3278 
3279 /*
3280  * Convert target id to target id bit mask.
3281  */
3282 #define ADV_TID_TO_TIDMASK(tid)   (0x01 << ((tid) & ADV_MAX_TID))
3283 
3284 /*
3285  * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3286  */
3287 
3288 #define QD_NO_STATUS         0x00	/* Request not completed yet. */
3289 #define QD_NO_ERROR          0x01
3290 #define QD_ABORTED_BY_HOST   0x02
3291 #define QD_WITH_ERROR        0x04
3292 
3293 #define QHSTA_NO_ERROR              0x00
3294 #define QHSTA_M_SEL_TIMEOUT         0x11
3295 #define QHSTA_M_DATA_OVER_RUN       0x12
3296 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3297 #define QHSTA_M_QUEUE_ABORTED       0x15
3298 #define QHSTA_M_SXFR_SDMA_ERR       0x16	/* SXFR_STATUS SCSI DMA Error */
3299 #define QHSTA_M_SXFR_SXFR_PERR      0x17	/* SXFR_STATUS SCSI Bus Parity Error */
3300 #define QHSTA_M_RDMA_PERR           0x18	/* RISC PCI DMA parity error */
3301 #define QHSTA_M_SXFR_OFF_UFLW       0x19	/* SXFR_STATUS Offset Underflow */
3302 #define QHSTA_M_SXFR_OFF_OFLW       0x20	/* SXFR_STATUS Offset Overflow */
3303 #define QHSTA_M_SXFR_WD_TMO         0x21	/* SXFR_STATUS Watchdog Timeout */
3304 #define QHSTA_M_SXFR_DESELECTED     0x22	/* SXFR_STATUS Deselected */
3305 /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
3306 #define QHSTA_M_SXFR_XFR_OFLW       0x12	/* SXFR_STATUS Transfer Overflow */
3307 #define QHSTA_M_SXFR_XFR_PH_ERR     0x24	/* SXFR_STATUS Transfer Phase Error */
3308 #define QHSTA_M_SXFR_UNKNOWN_ERROR  0x25	/* SXFR_STATUS Unknown Error */
3309 #define QHSTA_M_SCSI_BUS_RESET      0x30	/* Request aborted from SBR */
3310 #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31	/* Request aborted from unsol. SBR */
3311 #define QHSTA_M_BUS_DEVICE_RESET    0x32	/* Request aborted from BDR */
3312 #define QHSTA_M_DIRECTION_ERR       0x35	/* Data Phase mismatch */
3313 #define QHSTA_M_DIRECTION_ERR_HUNG  0x36	/* Data Phase mismatch and bus hang */
3314 #define QHSTA_M_WTM_TIMEOUT         0x41
3315 #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
3316 #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
3317 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
3318 #define QHSTA_M_INVALID_DEVICE      0x45	/* Bad target ID */
3319 #define QHSTA_M_FROZEN_TIDQ         0x46	/* TID Queue frozen. */
3320 #define QHSTA_M_SGBACKUP_ERROR      0x47	/* Scatter-Gather backup error */
3321 
3322 /*
3323  * Default EEPROM Configuration structure defined in a_init.c.
3324  */
3325 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
3326 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
3327 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
3328 
3329 /*
3330  * DvcGetPhyAddr() flag arguments
3331  */
3332 #define ADV_IS_SCSIQ_FLAG       0x01	/* 'addr' is ASC_SCSI_REQ_Q pointer */
3333 #define ADV_ASCGETSGLIST_VADDR  0x02	/* 'addr' is AscGetSGList() virtual addr */
3334 #define ADV_IS_SENSE_FLAG       0x04	/* 'addr' is sense virtual pointer */
3335 #define ADV_IS_DATA_FLAG        0x08	/* 'addr' is data virtual pointer */
3336 #define ADV_IS_SGLIST_FLAG      0x10	/* 'addr' is sglist virtual pointer */
3337 #define ADV_IS_CARRIER_FLAG     0x20	/* 'addr' is ADV_CARR_T pointer */
3338 
3339 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
3340 #define ADV_8BALIGN(addr)      (((ulong) (addr) + 0x7) & ~0x7)
3341 #define ADV_16BALIGN(addr)     (((ulong) (addr) + 0xF) & ~0xF)
3342 #define ADV_32BALIGN(addr)     (((ulong) (addr) + 0x1F) & ~0x1F)
3343 
3344 /*
3345  * Total contiguous memory needed for driver SG blocks.
3346  *
3347  * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3348  * number of scatter-gather elements the driver supports in a
3349  * single request.
3350  */
3351 
3352 #define ADV_SG_LIST_MAX_BYTE_SIZE \
3353          (sizeof(ADV_SG_BLOCK) * \
3354           ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3355 
3356 /*
3357  * Inquiry data structure and bitfield macros
3358  *
3359  * Using bitfields to access the subchar data isn't portable across
3360  * endianness, so instead mask and shift. Only quantities of more
3361  * than 1 bit are shifted, since the others are just tested for true
3362  * or false.
3363  */
3364 
3365 #define ADV_INQ_DVC_TYPE(inq)       ((inq)->periph & 0x1f)
3366 #define ADV_INQ_QUALIFIER(inq)      (((inq)->periph & 0xe0) >> 5)
3367 #define ADV_INQ_DVC_TYPE_MOD(inq)   ((inq)->devtype & 0x7f)
3368 #define ADV_INQ_REMOVABLE(inq)      ((inq)->devtype & 0x80)
3369 #define ADV_INQ_ANSI_VER(inq)       ((inq)->ver & 0x07)
3370 #define ADV_INQ_ECMA_VER(inq)       (((inq)->ver & 0x38) >> 3)
3371 #define ADV_INQ_ISO_VER(inq)        (((inq)->ver & 0xc0) >> 6)
3372 #define ADV_INQ_RESPONSE_FMT(inq)   ((inq)->byte3 & 0x0f)
3373 #define ADV_INQ_TERM_IO(inq)        ((inq)->byte3 & 0x40)
3374 #define ADV_INQ_ASYNC_NOTIF(inq)    ((inq)->byte3 & 0x80)
3375 #define ADV_INQ_SOFT_RESET(inq)     ((inq)->flags & 0x01)
3376 #define ADV_INQ_CMD_QUEUE(inq)      ((inq)->flags & 0x02)
3377 #define ADV_INQ_LINK_CMD(inq)       ((inq)->flags & 0x08)
3378 #define ADV_INQ_SYNC(inq)           ((inq)->flags & 0x10)
3379 #define ADV_INQ_WIDE16(inq)         ((inq)->flags & 0x20)
3380 #define ADV_INQ_WIDE32(inq)         ((inq)->flags & 0x40)
3381 #define ADV_INQ_REL_ADDR(inq)       ((inq)->flags & 0x80)
3382 #define ADV_INQ_INFO_UNIT(inq)      ((inq)->info & 0x01)
3383 #define ADV_INQ_QUICK_ARB(inq)      ((inq)->info & 0x02)
3384 #define ADV_INQ_CLOCKING(inq)       (((inq)->info & 0x0c) >> 2)
3385 
3386 typedef struct {
3387 	uchar periph;		/* peripheral device type [0:4] */
3388 	/* peripheral qualifier [5:7] */
3389 	uchar devtype;		/* device type modifier (for SCSI I) [0:6] */
3390 	/* RMB - removable medium bit [7] */
3391 	uchar ver;		/* ANSI approved version [0:2] */
3392 	/* ECMA version [3:5] */
3393 	/* ISO version [6:7] */
3394 	uchar byte3;		/* response data format [0:3] */
3395 	/* 0 SCSI 1 */
3396 	/* 1 CCS */
3397 	/* 2 SCSI-2 */
3398 	/* 3-F reserved */
3399 	/* reserved [4:5] */
3400 	/* terminate I/O process bit (see 5.6.22) [6] */
3401 	/* asynch. event notification (processor) [7] */
3402 	uchar add_len;		/* additional length */
3403 	uchar res1;		/* reserved */
3404 	uchar res2;		/* reserved */
3405 	uchar flags;		/* soft reset implemented [0] */
3406 	/* command queuing [1] */
3407 	/* reserved [2] */
3408 	/* linked command for this logical unit [3] */
3409 	/* synchronous data transfer [4] */
3410 	/* wide bus 16 bit data transfer [5] */
3411 	/* wide bus 32 bit data transfer [6] */
3412 	/* relative addressing mode [7] */
3413 	uchar vendor_id[8];	/* vendor identification */
3414 	uchar product_id[16];	/* product identification */
3415 	uchar product_rev_level[4];	/* product revision level */
3416 	uchar vendor_specific[20];	/* vendor specific */
3417 	uchar info;		/* information unit supported [0] */
3418 	/* quick arbitrate supported [1] */
3419 	/* clocking field [2:3] */
3420 	/* reserved [4:7] */
3421 	uchar res3;		/* reserved */
3422 } ADV_SCSI_INQUIRY;		/* 58 bytes */
3423 
3424 /*
3425  * --- Driver Constants and Macros
3426  */
3427 
3428 #define ASC_NUM_BOARD_SUPPORTED 16
3429 #define ASC_NUM_IOPORT_PROBE    4
3430 #define ASC_NUM_BUS             4
3431 
3432 /* Reference Scsi_Host hostdata */
3433 #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3434 
3435 /* asc_board_t flags */
3436 #define ASC_HOST_IN_RESET       0x01
3437 #define ASC_IS_WIDE_BOARD       0x04	/* AdvanSys Wide Board */
3438 #define ASC_SELECT_QUEUE_DEPTHS 0x08
3439 
3440 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3441 #define ASC_WIDE_BOARD(boardp)   ((boardp)->flags & ASC_IS_WIDE_BOARD)
3442 
3443 #define NO_ISA_DMA              0xff	/* No ISA DMA Channel Used */
3444 
3445 #define ASC_INFO_SIZE           128	/* advansys_info() line size */
3446 
3447 #ifdef CONFIG_PROC_FS
3448 /* /proc/scsi/advansys/[0...] related definitions */
3449 #define ASC_PRTBUF_SIZE         2048
3450 #define ASC_PRTLINE_SIZE        160
3451 
3452 #define ASC_PRT_NEXT() \
3453     if (cp) { \
3454         totlen += len; \
3455         leftlen -= len; \
3456         if (leftlen == 0) { \
3457             return totlen; \
3458         } \
3459         cp += len; \
3460     }
3461 #endif /* CONFIG_PROC_FS */
3462 
3463 /* Asc Library return codes */
3464 #define ASC_TRUE        1
3465 #define ASC_FALSE       0
3466 #define ASC_NOERROR     1
3467 #define ASC_BUSY        0
3468 #define ASC_ERROR       (-1)
3469 
3470 /* struct scsi_cmnd function return codes */
3471 #define STATUS_BYTE(byte)   (byte)
3472 #define MSG_BYTE(byte)      ((byte) << 8)
3473 #define HOST_BYTE(byte)     ((byte) << 16)
3474 #define DRIVER_BYTE(byte)   ((byte) << 24)
3475 
3476 /*
3477  * The following definitions and macros are OS independent interfaces to
3478  * the queue functions:
3479  *  REQ - SCSI request structure
3480  *  REQP - pointer to SCSI request structure
3481  *  REQPTID(reqp) - reqp's target id
3482  *  REQPNEXT(reqp) - reqp's next pointer
3483  *  REQPNEXTP(reqp) - pointer to reqp's next pointer
3484  *  REQPTIME(reqp) - reqp's time stamp value
3485  *  REQTIMESTAMP() - system time stamp value
3486  */
3487 typedef struct scsi_cmnd REQ, *REQP;
3488 #define REQPNEXT(reqp)       ((REQP) ((reqp)->host_scribble))
3489 #define REQPNEXTP(reqp)      ((REQP *) &((reqp)->host_scribble))
3490 #define REQPTID(reqp)        ((reqp)->device->id)
3491 #define REQPTIME(reqp)       ((reqp)->SCp.this_residual)
3492 #define REQTIMESTAMP()       (jiffies)
3493 
3494 #define REQTIMESTAT(function, ascq, reqp, tid) \
3495 { \
3496     /*
3497      * If the request time stamp is less than the system time stamp, then \
3498      * maybe the system time stamp wrapped. Set the request time to zero.\
3499      */ \
3500     if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3501         REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3502     } else { \
3503         /* Indicate an error occurred with the assertion. */ \
3504         ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3505         REQPTIME(reqp) = 0; \
3506     } \
3507     /* Handle first minimum time case without external initialization. */ \
3508     if (((ascq)->q_tot_cnt[tid] == 1) ||  \
3509         (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3510             (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3511             ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3512                 (function), (tid), (ascq)->q_min_tim[tid]); \
3513         } \
3514     if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3515         (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3516         ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3517             (function), tid, (ascq)->q_max_tim[tid]); \
3518     } \
3519     (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3520     /* Reset the time stamp field. */ \
3521     REQPTIME(reqp) = 0; \
3522 }
3523 
3524 /* asc_enqueue() flags */
3525 #define ASC_FRONT       1
3526 #define ASC_BACK        2
3527 
3528 /* asc_dequeue_list() argument */
3529 #define ASC_TID_ALL        (-1)
3530 
3531 /* Return non-zero, if the queue is empty. */
3532 #define ASC_QUEUE_EMPTY(ascq)    ((ascq)->q_tidmask == 0)
3533 
3534 #define PCI_MAX_SLOT            0x1F
3535 #define PCI_MAX_BUS             0xFF
3536 #define PCI_IOADDRESS_MASK      0xFFFE
3537 #define ASC_PCI_DEVICE_ID_CNT   6	/* PCI Device ID count. */
3538 
3539 #ifndef ADVANSYS_STATS
3540 #define ASC_STATS(shost, counter)
3541 #define ASC_STATS_ADD(shost, counter, count)
3542 #else /* ADVANSYS_STATS */
3543 #define ASC_STATS(shost, counter) \
3544     (ASC_BOARDP(shost)->asc_stats.counter++)
3545 
3546 #define ASC_STATS_ADD(shost, counter, count) \
3547     (ASC_BOARDP(shost)->asc_stats.counter += (count))
3548 #endif /* ADVANSYS_STATS */
3549 
3550 #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3551 
3552 /* If the result wraps when calculating tenths, return 0. */
3553 #define ASC_TENTHS(num, den) \
3554     (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3555     0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3556 
3557 /*
3558  * Display a message to the console.
3559  */
3560 #define ASC_PRINT(s) \
3561     { \
3562         printk("advansys: "); \
3563         printk(s); \
3564     }
3565 
3566 #define ASC_PRINT1(s, a1) \
3567     { \
3568         printk("advansys: "); \
3569         printk((s), (a1)); \
3570     }
3571 
3572 #define ASC_PRINT2(s, a1, a2) \
3573     { \
3574         printk("advansys: "); \
3575         printk((s), (a1), (a2)); \
3576     }
3577 
3578 #define ASC_PRINT3(s, a1, a2, a3) \
3579     { \
3580         printk("advansys: "); \
3581         printk((s), (a1), (a2), (a3)); \
3582     }
3583 
3584 #define ASC_PRINT4(s, a1, a2, a3, a4) \
3585     { \
3586         printk("advansys: "); \
3587         printk((s), (a1), (a2), (a3), (a4)); \
3588     }
3589 
3590 #ifndef ADVANSYS_DEBUG
3591 
3592 #define ASC_DBG(lvl, s)
3593 #define ASC_DBG1(lvl, s, a1)
3594 #define ASC_DBG2(lvl, s, a1, a2)
3595 #define ASC_DBG3(lvl, s, a1, a2, a3)
3596 #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3597 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3598 #define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3599 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3600 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3601 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3602 #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3603 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
3604 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
3605 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
3606 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3607 
3608 #else /* ADVANSYS_DEBUG */
3609 
3610 /*
3611  * Debugging Message Levels:
3612  * 0: Errors Only
3613  * 1: High-Level Tracing
3614  * 2-N: Verbose Tracing
3615  */
3616 
3617 #define ASC_DBG(lvl, s) \
3618     { \
3619         if (asc_dbglvl >= (lvl)) { \
3620             printk(s); \
3621         } \
3622     }
3623 
3624 #define ASC_DBG1(lvl, s, a1) \
3625     { \
3626         if (asc_dbglvl >= (lvl)) { \
3627             printk((s), (a1)); \
3628         } \
3629     }
3630 
3631 #define ASC_DBG2(lvl, s, a1, a2) \
3632     { \
3633         if (asc_dbglvl >= (lvl)) { \
3634             printk((s), (a1), (a2)); \
3635         } \
3636     }
3637 
3638 #define ASC_DBG3(lvl, s, a1, a2, a3) \
3639     { \
3640         if (asc_dbglvl >= (lvl)) { \
3641             printk((s), (a1), (a2), (a3)); \
3642         } \
3643     }
3644 
3645 #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3646     { \
3647         if (asc_dbglvl >= (lvl)) { \
3648             printk((s), (a1), (a2), (a3), (a4)); \
3649         } \
3650     }
3651 
3652 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3653     { \
3654         if (asc_dbglvl >= (lvl)) { \
3655             asc_prt_scsi_host(s); \
3656         } \
3657     }
3658 
3659 #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3660     { \
3661         if (asc_dbglvl >= (lvl)) { \
3662             asc_prt_scsi_cmnd(s); \
3663         } \
3664     }
3665 
3666 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3667     { \
3668         if (asc_dbglvl >= (lvl)) { \
3669             asc_prt_asc_scsi_q(scsiqp); \
3670         } \
3671     }
3672 
3673 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3674     { \
3675         if (asc_dbglvl >= (lvl)) { \
3676             asc_prt_asc_qdone_info(qdone); \
3677         } \
3678     }
3679 
3680 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3681     { \
3682         if (asc_dbglvl >= (lvl)) { \
3683             asc_prt_adv_scsi_req_q(scsiqp); \
3684         } \
3685     }
3686 
3687 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3688     { \
3689         if (asc_dbglvl >= (lvl)) { \
3690             asc_prt_hex((name), (start), (length)); \
3691         } \
3692     }
3693 
3694 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3695         ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3696 
3697 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3698         ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3699 
3700 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3701         ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3702 #endif /* ADVANSYS_DEBUG */
3703 
3704 #ifndef ADVANSYS_ASSERT
3705 #define ASC_ASSERT(a)
3706 #else /* ADVANSYS_ASSERT */
3707 
3708 #define ASC_ASSERT(a) \
3709     { \
3710         if (!(a)) { \
3711             printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3712                 __FILE__, __LINE__); \
3713         } \
3714     }
3715 
3716 #endif /* ADVANSYS_ASSERT */
3717 
3718 /*
3719  * --- Driver Structures
3720  */
3721 
3722 #ifdef ADVANSYS_STATS
3723 
3724 /* Per board statistics structure */
3725 struct asc_stats {
3726 	/* Driver Entrypoint Statistics */
3727 	ADV_DCNT queuecommand;	/* # calls to advansys_queuecommand() */
3728 	ADV_DCNT reset;		/* # calls to advansys_eh_bus_reset() */
3729 	ADV_DCNT biosparam;	/* # calls to advansys_biosparam() */
3730 	ADV_DCNT interrupt;	/* # advansys_interrupt() calls */
3731 	ADV_DCNT callback;	/* # calls to asc/adv_isr_callback() */
3732 	ADV_DCNT done;		/* # calls to request's scsi_done function */
3733 	ADV_DCNT build_error;	/* # asc/adv_build_req() ASC_ERROR returns. */
3734 	ADV_DCNT adv_build_noreq;	/* # adv_build_req() adv_req_t alloc. fail. */
3735 	ADV_DCNT adv_build_nosg;	/* # adv_build_req() adv_sgblk_t alloc. fail. */
3736 	/* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3737 	ADV_DCNT exe_noerror;	/* # ASC_NOERROR returns. */
3738 	ADV_DCNT exe_busy;	/* # ASC_BUSY returns. */
3739 	ADV_DCNT exe_error;	/* # ASC_ERROR returns. */
3740 	ADV_DCNT exe_unknown;	/* # unknown returns. */
3741 	/* Data Transfer Statistics */
3742 	ADV_DCNT cont_cnt;	/* # non-scatter-gather I/O requests received */
3743 	ADV_DCNT cont_xfer;	/* # contiguous transfer 512-bytes */
3744 	ADV_DCNT sg_cnt;	/* # scatter-gather I/O requests received */
3745 	ADV_DCNT sg_elem;	/* # scatter-gather elements */
3746 	ADV_DCNT sg_xfer;	/* # scatter-gather transfer 512-bytes */
3747 };
3748 #endif /* ADVANSYS_STATS */
3749 
3750 /*
3751  * Request queuing structure
3752  */
3753 typedef struct asc_queue {
3754 	ADV_SCSI_BIT_ID_TYPE q_tidmask;	/* queue mask */
3755 	REQP q_first[ADV_MAX_TID + 1];	/* first queued request */
3756 	REQP q_last[ADV_MAX_TID + 1];	/* last queued request */
3757 #ifdef ADVANSYS_STATS
3758 	short q_cur_cnt[ADV_MAX_TID + 1];	/* current queue count */
3759 	short q_max_cnt[ADV_MAX_TID + 1];	/* maximum queue count */
3760 	ADV_DCNT q_tot_cnt[ADV_MAX_TID + 1];	/* total enqueue count */
3761 	ADV_DCNT q_tot_tim[ADV_MAX_TID + 1];	/* total time queued */
3762 	ushort q_max_tim[ADV_MAX_TID + 1];	/* maximum time queued */
3763 	ushort q_min_tim[ADV_MAX_TID + 1];	/* minimum time queued */
3764 #endif				/* ADVANSYS_STATS */
3765 } asc_queue_t;
3766 
3767 /*
3768  * Adv Library Request Structures
3769  *
3770  * The following two structures are used to process Wide Board requests.
3771  *
3772  * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
3773  * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
3774  * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
3775  * Mid-Level SCSI request structure.
3776  *
3777  * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
3778  * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
3779  * up to 255 scatter-gather elements may be used per request or
3780  * ADV_SCSI_REQ_Q.
3781  *
3782  * Both structures must be 32 byte aligned.
3783  */
3784 typedef struct adv_sgblk {
3785 	ADV_SG_BLOCK sg_block;	/* Sgblock structure. */
3786 	uchar align[32];	/* Sgblock structure padding. */
3787 	struct adv_sgblk *next_sgblkp;	/* Next scatter-gather structure. */
3788 } adv_sgblk_t;
3789 
3790 typedef struct adv_req {
3791 	ADV_SCSI_REQ_Q scsi_req_q;	/* Adv Library request structure. */
3792 	uchar align[32];	/* Request structure padding. */
3793 	struct scsi_cmnd *cmndp;	/* Mid-Level SCSI command pointer. */
3794 	adv_sgblk_t *sgblkp;	/* Adv Library scatter-gather pointer. */
3795 	struct adv_req *next_reqp;	/* Next Request Structure. */
3796 } adv_req_t;
3797 
3798 /*
3799  * Structure allocated for each board.
3800  *
3801  * This structure is allocated by scsi_register() at the end
3802  * of the 'Scsi_Host' structure starting at the 'hostdata'
3803  * field. It is guaranteed to be allocated from DMA-able memory.
3804  */
3805 typedef struct asc_board {
3806 	int id;			/* Board Id */
3807 	uint flags;		/* Board flags */
3808 	union {
3809 		ASC_DVC_VAR asc_dvc_var;	/* Narrow board */
3810 		ADV_DVC_VAR adv_dvc_var;	/* Wide board */
3811 	} dvc_var;
3812 	union {
3813 		ASC_DVC_CFG asc_dvc_cfg;	/* Narrow board */
3814 		ADV_DVC_CFG adv_dvc_cfg;	/* Wide board */
3815 	} dvc_cfg;
3816 	ushort asc_n_io_port;	/* Number I/O ports. */
3817 	asc_queue_t active;	/* Active command queue */
3818 	asc_queue_t waiting;	/* Waiting command queue */
3819 	asc_queue_t done;	/* Done command queue */
3820 	ADV_SCSI_BIT_ID_TYPE init_tidmask;	/* Target init./valid mask */
3821 	struct scsi_device *device[ADV_MAX_TID + 1];	/* Mid-Level Scsi Device */
3822 	ushort reqcnt[ADV_MAX_TID + 1];	/* Starvation request count */
3823 	ADV_SCSI_BIT_ID_TYPE queue_full;	/* Queue full mask */
3824 	ushort queue_full_cnt[ADV_MAX_TID + 1];	/* Queue full count */
3825 	union {
3826 		ASCEEP_CONFIG asc_eep;	/* Narrow EEPROM config. */
3827 		ADVEEP_3550_CONFIG adv_3550_eep;	/* 3550 EEPROM config. */
3828 		ADVEEP_38C0800_CONFIG adv_38C0800_eep;	/* 38C0800 EEPROM config. */
3829 		ADVEEP_38C1600_CONFIG adv_38C1600_eep;	/* 38C1600 EEPROM config. */
3830 	} eep_config;
3831 	ulong last_reset;	/* Saved last reset time */
3832 	spinlock_t lock;	/* Board spinlock */
3833 #ifdef CONFIG_PROC_FS
3834 	/* /proc/scsi/advansys/[0...] */
3835 	char *prtbuf;		/* /proc print buffer */
3836 #endif				/* CONFIG_PROC_FS */
3837 #ifdef ADVANSYS_STATS
3838 	struct asc_stats asc_stats;	/* Board statistics */
3839 #endif				/* ADVANSYS_STATS */
3840 	/*
3841 	 * The following fields are used only for Narrow Boards.
3842 	 */
3843 	/* The following three structures must be in DMA-able memory. */
3844 	ASC_SCSI_REQ_Q scsireqq;
3845 	ASC_CAP_INFO cap_info;
3846 	ASC_SCSI_INQUIRY inquiry;
3847 	uchar sdtr_data[ASC_MAX_TID + 1];	/* SDTR information */
3848 	/*
3849 	 * The following fields are used only for Wide Boards.
3850 	 */
3851 	void __iomem *ioremap_addr;	/* I/O Memory remap address. */
3852 	ushort ioport;		/* I/O Port address. */
3853 	ADV_CARR_T *orig_carrp;	/* ADV_CARR_T memory block. */
3854 	adv_req_t *orig_reqp;	/* adv_req_t memory block. */
3855 	adv_req_t *adv_reqp;	/* Request structures. */
3856 	adv_sgblk_t *adv_sgblkp;	/* Scatter-gather structures. */
3857 	ushort bios_signature;	/* BIOS Signature. */
3858 	ushort bios_version;	/* BIOS Version. */
3859 	ushort bios_codeseg;	/* BIOS Code Segment. */
3860 	ushort bios_codelen;	/* BIOS Code Segment Length. */
3861 } asc_board_t;
3862 
3863 /*
3864  * PCI configuration structures
3865  */
3866 typedef struct _PCI_DATA_ {
3867 	uchar type;
3868 	uchar bus;
3869 	uchar slot;
3870 	uchar func;
3871 	uchar offset;
3872 } PCI_DATA;
3873 
3874 typedef struct _PCI_DEVICE_ {
3875 	ushort vendorID;
3876 	ushort deviceID;
3877 	ushort slotNumber;
3878 	ushort slotFound;
3879 	uchar busNumber;
3880 	uchar maxBusNumber;
3881 	uchar devFunc;
3882 	ushort startSlot;
3883 	ushort endSlot;
3884 	uchar bridge;
3885 	uchar type;
3886 } PCI_DEVICE;
3887 
3888 typedef struct _PCI_CONFIG_SPACE_ {
3889 	ushort vendorID;
3890 	ushort deviceID;
3891 	ushort command;
3892 	ushort status;
3893 	uchar revision;
3894 	uchar classCode[3];
3895 	uchar cacheSize;
3896 	uchar latencyTimer;
3897 	uchar headerType;
3898 	uchar bist;
3899 	ADV_PADDR baseAddress[6];
3900 	ushort reserved[4];
3901 	ADV_PADDR optionRomAddr;
3902 	ushort reserved2[4];
3903 	uchar irqLine;
3904 	uchar irqPin;
3905 	uchar minGnt;
3906 	uchar maxLatency;
3907 } PCI_CONFIG_SPACE;
3908 
3909 /*
3910  * --- Driver Data
3911  */
3912 
3913 /* Note: All driver global data should be initialized. */
3914 
3915 /* Number of boards detected in system. */
3916 static int asc_board_count = 0;
3917 static struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { NULL };
3918 
3919 /* Overrun buffer used by all narrow boards. */
3920 static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
3921 
3922 /*
3923  * Global structures required to issue a command.
3924  */
3925 static ASC_SCSI_Q asc_scsi_q = { {0} };
3926 static ASC_SG_HEAD asc_sg_head = { 0 };
3927 
3928 /* List of supported bus types. */
3929 static ushort asc_bus[ASC_NUM_BUS] __initdata = {
3930 	ASC_IS_ISA,
3931 	ASC_IS_VL,
3932 	ASC_IS_EISA,
3933 	ASC_IS_PCI,
3934 };
3935 
3936 static int asc_iopflag = ASC_FALSE;
3937 static int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
3938 
3939 #ifdef ADVANSYS_DEBUG
3940 static char *asc_bus_name[ASC_NUM_BUS] = {
3941 	"ASC_IS_ISA",
3942 	"ASC_IS_VL",
3943 	"ASC_IS_EISA",
3944 	"ASC_IS_PCI",
3945 };
3946 
3947 static int asc_dbglvl = 3;
3948 #endif /* ADVANSYS_DEBUG */
3949 
3950 /* Declaration for Asc Library internal data referenced by driver. */
3951 static PortAddr _asc_def_iop_base[];
3952 
3953 /*
3954  * --- Driver Function Prototypes
3955  *
3956  * advansys.h contains function prototypes for functions global to Linux.
3957  */
3958 
3959 static irqreturn_t advansys_interrupt(int, void *);
3960 static int advansys_slave_configure(struct scsi_device *);
3961 static void asc_scsi_done_list(struct scsi_cmnd *);
3962 static int asc_execute_scsi_cmnd(struct scsi_cmnd *);
3963 static int asc_build_req(asc_board_t *, struct scsi_cmnd *);
3964 static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
3965 static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
3966 static void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
3967 static void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3968 static void adv_async_callback(ADV_DVC_VAR *, uchar);
3969 static void asc_enqueue(asc_queue_t *, REQP, int);
3970 static REQP asc_dequeue(asc_queue_t *, int);
3971 static REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
3972 static int asc_rmqueue(asc_queue_t *, REQP);
3973 static void asc_execute_queue(asc_queue_t *);
3974 #ifdef CONFIG_PROC_FS
3975 static int asc_proc_copy(off_t, off_t, char *, int, char *, int);
3976 static int asc_prt_board_devices(struct Scsi_Host *, char *, int);
3977 static int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
3978 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
3979 static int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
3980 static int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
3981 static int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
3982 static int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
3983 static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
3984 static int asc_prt_line(char *, int, char *fmt, ...);
3985 #endif /* CONFIG_PROC_FS */
3986 
3987 /* Declaration for Asc Library internal functions referenced by driver. */
3988 static int AscFindSignature(PortAddr);
3989 static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
3990 
3991 /* Statistics function prototypes. */
3992 #ifdef ADVANSYS_STATS
3993 #ifdef CONFIG_PROC_FS
3994 static int asc_prt_board_stats(struct Scsi_Host *, char *, int);
3995 static int asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
3996 #endif /* CONFIG_PROC_FS */
3997 #endif /* ADVANSYS_STATS */
3998 
3999 /* Debug function prototypes. */
4000 #ifdef ADVANSYS_DEBUG
4001 static void asc_prt_scsi_host(struct Scsi_Host *);
4002 static void asc_prt_scsi_cmnd(struct scsi_cmnd *);
4003 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
4004 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
4005 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
4006 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
4007 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
4008 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
4009 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
4010 static void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
4011 static void asc_prt_hex(char *f, uchar *, int);
4012 #endif /* ADVANSYS_DEBUG */
4013 
4014 #ifdef CONFIG_PROC_FS
4015 /*
4016  * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
4017  *
4018  * *buffer: I/O buffer
4019  * **start: if inout == FALSE pointer into buffer where user read should start
4020  * offset: current offset into a /proc/scsi/advansys/[0...] file
4021  * length: length of buffer
4022  * hostno: Scsi_Host host_no
4023  * inout: TRUE - user is writing; FALSE - user is reading
4024  *
4025  * Return the number of bytes read from or written to a
4026  * /proc/scsi/advansys/[0...] file.
4027  *
4028  * Note: This function uses the per board buffer 'prtbuf' which is
4029  * allocated when the board is initialized in advansys_detect(). The
4030  * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
4031  * used to write to the buffer. The way asc_proc_copy() is written
4032  * if 'prtbuf' is too small it will not be overwritten. Instead the
4033  * user just won't get all the available statistics.
4034  */
4035 static int
4036 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
4037 		   off_t offset, int length, int inout)
4038 {
4039 	struct Scsi_Host *shp;
4040 	asc_board_t *boardp;
4041 	int i;
4042 	char *cp;
4043 	int cplen;
4044 	int cnt;
4045 	int totcnt;
4046 	int leftlen;
4047 	char *curbuf;
4048 	off_t advoffset;
4049 #ifdef ADVANSYS_STATS
4050 	int tgt_id;
4051 #endif /* ADVANSYS_STATS */
4052 
4053 	ASC_DBG(1, "advansys_proc_info: begin\n");
4054 
4055 	/*
4056 	 * User write not supported.
4057 	 */
4058 	if (inout == TRUE) {
4059 		return (-ENOSYS);
4060 	}
4061 
4062 	/*
4063 	 * User read of /proc/scsi/advansys/[0...] file.
4064 	 */
4065 
4066 	/* Find the specified board. */
4067 	for (i = 0; i < asc_board_count; i++) {
4068 		if (asc_host[i]->host_no == shost->host_no) {
4069 			break;
4070 		}
4071 	}
4072 	if (i == asc_board_count) {
4073 		return (-ENOENT);
4074 	}
4075 
4076 	shp = asc_host[i];
4077 	boardp = ASC_BOARDP(shp);
4078 
4079 	/* Copy read data starting at the beginning of the buffer. */
4080 	*start = buffer;
4081 	curbuf = buffer;
4082 	advoffset = 0;
4083 	totcnt = 0;
4084 	leftlen = length;
4085 
4086 	/*
4087 	 * Get board configuration information.
4088 	 *
4089 	 * advansys_info() returns the board string from its own static buffer.
4090 	 */
4091 	cp = (char *)advansys_info(shp);
4092 	strcat(cp, "\n");
4093 	cplen = strlen(cp);
4094 	/* Copy board information. */
4095 	cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4096 	totcnt += cnt;
4097 	leftlen -= cnt;
4098 	if (leftlen == 0) {
4099 		ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4100 		return totcnt;
4101 	}
4102 	advoffset += cplen;
4103 	curbuf += cnt;
4104 
4105 	/*
4106 	 * Display Wide Board BIOS Information.
4107 	 */
4108 	if (ASC_WIDE_BOARD(boardp)) {
4109 		cp = boardp->prtbuf;
4110 		cplen = asc_prt_adv_bios(shp, cp, ASC_PRTBUF_SIZE);
4111 		ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4112 		cnt =
4113 		    asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
4114 				  cplen);
4115 		totcnt += cnt;
4116 		leftlen -= cnt;
4117 		if (leftlen == 0) {
4118 			ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4119 			return totcnt;
4120 		}
4121 		advoffset += cplen;
4122 		curbuf += cnt;
4123 	}
4124 
4125 	/*
4126 	 * Display driver information for each device attached to the board.
4127 	 */
4128 	cp = boardp->prtbuf;
4129 	cplen = asc_prt_board_devices(shp, cp, ASC_PRTBUF_SIZE);
4130 	ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4131 	cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4132 	totcnt += cnt;
4133 	leftlen -= cnt;
4134 	if (leftlen == 0) {
4135 		ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4136 		return totcnt;
4137 	}
4138 	advoffset += cplen;
4139 	curbuf += cnt;
4140 
4141 	/*
4142 	 * Display EEPROM configuration for the board.
4143 	 */
4144 	cp = boardp->prtbuf;
4145 	if (ASC_NARROW_BOARD(boardp)) {
4146 		cplen = asc_prt_asc_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4147 	} else {
4148 		cplen = asc_prt_adv_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4149 	}
4150 	ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4151 	cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4152 	totcnt += cnt;
4153 	leftlen -= cnt;
4154 	if (leftlen == 0) {
4155 		ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4156 		return totcnt;
4157 	}
4158 	advoffset += cplen;
4159 	curbuf += cnt;
4160 
4161 	/*
4162 	 * Display driver configuration and information for the board.
4163 	 */
4164 	cp = boardp->prtbuf;
4165 	cplen = asc_prt_driver_conf(shp, cp, ASC_PRTBUF_SIZE);
4166 	ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4167 	cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4168 	totcnt += cnt;
4169 	leftlen -= cnt;
4170 	if (leftlen == 0) {
4171 		ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4172 		return totcnt;
4173 	}
4174 	advoffset += cplen;
4175 	curbuf += cnt;
4176 
4177 #ifdef ADVANSYS_STATS
4178 	/*
4179 	 * Display driver statistics for the board.
4180 	 */
4181 	cp = boardp->prtbuf;
4182 	cplen = asc_prt_board_stats(shp, cp, ASC_PRTBUF_SIZE);
4183 	ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4184 	cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4185 	totcnt += cnt;
4186 	leftlen -= cnt;
4187 	if (leftlen == 0) {
4188 		ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4189 		return totcnt;
4190 	}
4191 	advoffset += cplen;
4192 	curbuf += cnt;
4193 
4194 	/*
4195 	 * Display driver statistics for each target.
4196 	 */
4197 	for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
4198 		cp = boardp->prtbuf;
4199 		cplen = asc_prt_target_stats(shp, tgt_id, cp, ASC_PRTBUF_SIZE);
4200 		ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4201 		cnt =
4202 		    asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
4203 				  cplen);
4204 		totcnt += cnt;
4205 		leftlen -= cnt;
4206 		if (leftlen == 0) {
4207 			ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4208 			return totcnt;
4209 		}
4210 		advoffset += cplen;
4211 		curbuf += cnt;
4212 	}
4213 #endif /* ADVANSYS_STATS */
4214 
4215 	/*
4216 	 * Display Asc Library dynamic configuration information
4217 	 * for the board.
4218 	 */
4219 	cp = boardp->prtbuf;
4220 	if (ASC_NARROW_BOARD(boardp)) {
4221 		cplen = asc_prt_asc_board_info(shp, cp, ASC_PRTBUF_SIZE);
4222 	} else {
4223 		cplen = asc_prt_adv_board_info(shp, cp, ASC_PRTBUF_SIZE);
4224 	}
4225 	ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4226 	cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4227 	totcnt += cnt;
4228 	leftlen -= cnt;
4229 	if (leftlen == 0) {
4230 		ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4231 		return totcnt;
4232 	}
4233 	advoffset += cplen;
4234 	curbuf += cnt;
4235 
4236 	ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4237 
4238 	return totcnt;
4239 }
4240 #endif /* CONFIG_PROC_FS */
4241 
4242 /*
4243  * advansys_info()
4244  *
4245  * Return suitable for printing on the console with the argument
4246  * adapter's configuration information.
4247  *
4248  * Note: The information line should not exceed ASC_INFO_SIZE bytes,
4249  * otherwise the static 'info' array will be overrun.
4250  */
4251 static const char *advansys_info(struct Scsi_Host *shost)
4252 {
4253 	static char info[ASC_INFO_SIZE];
4254 	asc_board_t *boardp;
4255 	ASC_DVC_VAR *asc_dvc_varp;
4256 	ADV_DVC_VAR *adv_dvc_varp;
4257 	char *busname;
4258 	int iolen;
4259 	char *widename = NULL;
4260 
4261 	boardp = ASC_BOARDP(shost);
4262 	if (ASC_NARROW_BOARD(boardp)) {
4263 		asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4264 		ASC_DBG(1, "advansys_info: begin\n");
4265 		if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
4266 			if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
4267 			    ASC_IS_ISAPNP) {
4268 				busname = "ISA PnP";
4269 			} else {
4270 				busname = "ISA";
4271 			}
4272 			/* Don't reference 'shost->n_io_port'; It may be truncated. */
4273 			sprintf(info,
4274 				"AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
4275 				ASC_VERSION, busname,
4276 				(ulong)shost->io_port,
4277 				(ulong)shost->io_port + boardp->asc_n_io_port -
4278 				1, shost->irq, shost->dma_channel);
4279 		} else {
4280 			if (asc_dvc_varp->bus_type & ASC_IS_VL) {
4281 				busname = "VL";
4282 			} else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
4283 				busname = "EISA";
4284 			} else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
4285 				if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
4286 				    == ASC_IS_PCI_ULTRA) {
4287 					busname = "PCI Ultra";
4288 				} else {
4289 					busname = "PCI";
4290 				}
4291 			} else {
4292 				busname = "?";
4293 				ASC_PRINT2
4294 				    ("advansys_info: board %d: unknown bus type %d\n",
4295 				     boardp->id, asc_dvc_varp->bus_type);
4296 			}
4297 			/* Don't reference 'shost->n_io_port'; It may be truncated. */
4298 			sprintf(info,
4299 				"AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
4300 				ASC_VERSION, busname,
4301 				(ulong)shost->io_port,
4302 				(ulong)shost->io_port + boardp->asc_n_io_port -
4303 				1, shost->irq);
4304 		}
4305 	} else {
4306 		/*
4307 		 * Wide Adapter Information
4308 		 *
4309 		 * Memory-mapped I/O is used instead of I/O space to access
4310 		 * the adapter, but display the I/O Port range. The Memory
4311 		 * I/O address is displayed through the driver /proc file.
4312 		 */
4313 		adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4314 		if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4315 			iolen = ADV_3550_IOLEN;
4316 			widename = "Ultra-Wide";
4317 		} else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4318 			iolen = ADV_38C0800_IOLEN;
4319 			widename = "Ultra2-Wide";
4320 		} else {
4321 			iolen = ADV_38C1600_IOLEN;
4322 			widename = "Ultra3-Wide";
4323 		}
4324 		sprintf(info,
4325 			"AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
4326 			ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
4327 			(ulong)adv_dvc_varp->iop_base + iolen - 1, shost->irq);
4328 	}
4329 	ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
4330 	ASC_DBG(1, "advansys_info: end\n");
4331 	return info;
4332 }
4333 
4334 /*
4335  * advansys_queuecommand() - interrupt-driven I/O entrypoint.
4336  *
4337  * This function always returns 0. Command return status is saved
4338  * in the 'scp' result field.
4339  */
4340 static int
4341 advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *))
4342 {
4343 	struct Scsi_Host *shost;
4344 	asc_board_t *boardp;
4345 	ulong flags;
4346 	struct scsi_cmnd *done_scp;
4347 
4348 	shost = scp->device->host;
4349 	boardp = ASC_BOARDP(shost);
4350 	ASC_STATS(shost, queuecommand);
4351 
4352 	/* host_lock taken by mid-level prior to call but need to protect */
4353 	/* against own ISR */
4354 	spin_lock_irqsave(&boardp->lock, flags);
4355 
4356 	/*
4357 	 * Block new commands while handling a reset or abort request.
4358 	 */
4359 	if (boardp->flags & ASC_HOST_IN_RESET) {
4360 		ASC_DBG1(1,
4361 			 "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
4362 			 (ulong)scp);
4363 		scp->result = HOST_BYTE(DID_RESET);
4364 
4365 		/*
4366 		 * Add blocked requests to the board's 'done' queue. The queued
4367 		 * requests will be completed at the end of the abort or reset
4368 		 * handling.
4369 		 */
4370 		asc_enqueue(&boardp->done, scp, ASC_BACK);
4371 		spin_unlock_irqrestore(&boardp->lock, flags);
4372 		return 0;
4373 	}
4374 
4375 	/*
4376 	 * Attempt to execute any waiting commands for the board.
4377 	 */
4378 	if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4379 		ASC_DBG(1,
4380 			"advansys_queuecommand: before asc_execute_queue() waiting\n");
4381 		asc_execute_queue(&boardp->waiting);
4382 	}
4383 
4384 	/*
4385 	 * Save the function pointer to Linux mid-level 'done' function
4386 	 * and attempt to execute the command.
4387 	 *
4388 	 * If ASC_NOERROR is returned the request has been added to the
4389 	 * board's 'active' queue and will be completed by the interrupt
4390 	 * handler.
4391 	 *
4392 	 * If ASC_BUSY is returned add the request to the board's per
4393 	 * target waiting list. This is the first time the request has
4394 	 * been tried. Add it to the back of the waiting list. It will be
4395 	 * retried later.
4396 	 *
4397 	 * If an error occurred, the request will have been placed on the
4398 	 * board's 'done' queue and must be completed before returning.
4399 	 */
4400 	scp->scsi_done = done;
4401 	switch (asc_execute_scsi_cmnd(scp)) {
4402 	case ASC_NOERROR:
4403 		break;
4404 	case ASC_BUSY:
4405 		asc_enqueue(&boardp->waiting, scp, ASC_BACK);
4406 		break;
4407 	case ASC_ERROR:
4408 	default:
4409 		done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
4410 		/* Interrupts could be enabled here. */
4411 		asc_scsi_done_list(done_scp);
4412 		break;
4413 	}
4414 	spin_unlock_irqrestore(&boardp->lock, flags);
4415 
4416 	return 0;
4417 }
4418 
4419 /*
4420  * advansys_reset()
4421  *
4422  * Reset the bus associated with the command 'scp'.
4423  *
4424  * This function runs its own thread. Interrupts must be blocked but
4425  * sleeping is allowed and no locking other than for host structures is
4426  * required. Returns SUCCESS or FAILED.
4427  */
4428 static int advansys_reset(struct scsi_cmnd *scp)
4429 {
4430 	struct Scsi_Host *shost;
4431 	asc_board_t *boardp;
4432 	ASC_DVC_VAR *asc_dvc_varp;
4433 	ADV_DVC_VAR *adv_dvc_varp;
4434 	ulong flags;
4435 	struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4436 	struct scsi_cmnd *tscp, *new_last_scp;
4437 	int status;
4438 	int ret = SUCCESS;
4439 
4440 	ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp);
4441 
4442 #ifdef ADVANSYS_STATS
4443 	if (scp->device->host != NULL) {
4444 		ASC_STATS(scp->device->host, reset);
4445 	}
4446 #endif /* ADVANSYS_STATS */
4447 
4448 	if ((shost = scp->device->host) == NULL) {
4449 		scp->result = HOST_BYTE(DID_ERROR);
4450 		return FAILED;
4451 	}
4452 
4453 	boardp = ASC_BOARDP(shost);
4454 
4455 	ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
4456 		   boardp->id);
4457 	/*
4458 	 * Check for re-entrancy.
4459 	 */
4460 	spin_lock_irqsave(&boardp->lock, flags);
4461 	if (boardp->flags & ASC_HOST_IN_RESET) {
4462 		spin_unlock_irqrestore(&boardp->lock, flags);
4463 		return FAILED;
4464 	}
4465 	boardp->flags |= ASC_HOST_IN_RESET;
4466 	spin_unlock_irqrestore(&boardp->lock, flags);
4467 
4468 	if (ASC_NARROW_BOARD(boardp)) {
4469 		/*
4470 		 * Narrow Board
4471 		 */
4472 		asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4473 
4474 		/*
4475 		 * Reset the chip and SCSI bus.
4476 		 */
4477 		ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
4478 		status = AscInitAsc1000Driver(asc_dvc_varp);
4479 
4480 		/* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
4481 		if (asc_dvc_varp->err_code) {
4482 			ASC_PRINT2
4483 			    ("advansys_reset: board %d: SCSI bus reset error: 0x%x\n",
4484 			     boardp->id, asc_dvc_varp->err_code);
4485 			ret = FAILED;
4486 		} else if (status) {
4487 			ASC_PRINT2
4488 			    ("advansys_reset: board %d: SCSI bus reset warning: 0x%x\n",
4489 			     boardp->id, status);
4490 		} else {
4491 			ASC_PRINT1
4492 			    ("advansys_reset: board %d: SCSI bus reset successful.\n",
4493 			     boardp->id);
4494 		}
4495 
4496 		ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
4497 		spin_lock_irqsave(&boardp->lock, flags);
4498 
4499 	} else {
4500 		/*
4501 		 * Wide Board
4502 		 *
4503 		 * If the suggest reset bus flags are set, then reset the bus.
4504 		 * Otherwise only reset the device.
4505 		 */
4506 		adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4507 
4508 		/*
4509 		 * Reset the target's SCSI bus.
4510 		 */
4511 		ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
4512 		switch (AdvResetChipAndSB(adv_dvc_varp)) {
4513 		case ASC_TRUE:
4514 			ASC_PRINT1
4515 			    ("advansys_reset: board %d: SCSI bus reset successful.\n",
4516 			     boardp->id);
4517 			break;
4518 		case ASC_FALSE:
4519 		default:
4520 			ASC_PRINT1
4521 			    ("advansys_reset: board %d: SCSI bus reset error.\n",
4522 			     boardp->id);
4523 			ret = FAILED;
4524 			break;
4525 		}
4526 		spin_lock_irqsave(&boardp->lock, flags);
4527 		(void)AdvISR(adv_dvc_varp);
4528 	}
4529 	/* Board lock is held. */
4530 
4531 	/*
4532 	 * Dequeue all board 'done' requests. A pointer to the last request
4533 	 * is returned in 'last_scp'.
4534 	 */
4535 	done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
4536 
4537 	/*
4538 	 * Dequeue all board 'active' requests for all devices and set
4539 	 * the request status to DID_RESET. A pointer to the last request
4540 	 * is returned in 'last_scp'.
4541 	 */
4542 	if (done_scp == NULL) {
4543 		done_scp =
4544 		    asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL);
4545 		for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4546 			tscp->result = HOST_BYTE(DID_RESET);
4547 		}
4548 	} else {
4549 		/* Append to 'done_scp' at the end with 'last_scp'. */
4550 		ASC_ASSERT(last_scp != NULL);
4551 		last_scp->host_scribble =
4552 		    (unsigned char *)asc_dequeue_list(&boardp->active,
4553 						      &new_last_scp,
4554 						      ASC_TID_ALL);
4555 		if (new_last_scp != NULL) {
4556 			ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4557 			for (tscp = REQPNEXT(last_scp); tscp;
4558 			     tscp = REQPNEXT(tscp)) {
4559 				tscp->result = HOST_BYTE(DID_RESET);
4560 			}
4561 			last_scp = new_last_scp;
4562 		}
4563 	}
4564 
4565 	/*
4566 	 * Dequeue all 'waiting' requests and set the request status
4567 	 * to DID_RESET.
4568 	 */
4569 	if (done_scp == NULL) {
4570 		done_scp =
4571 		    asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL);
4572 		for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4573 			tscp->result = HOST_BYTE(DID_RESET);
4574 		}
4575 	} else {
4576 		/* Append to 'done_scp' at the end with 'last_scp'. */
4577 		ASC_ASSERT(last_scp != NULL);
4578 		last_scp->host_scribble =
4579 		    (unsigned char *)asc_dequeue_list(&boardp->waiting,
4580 						      &new_last_scp,
4581 						      ASC_TID_ALL);
4582 		if (new_last_scp != NULL) {
4583 			ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4584 			for (tscp = REQPNEXT(last_scp); tscp;
4585 			     tscp = REQPNEXT(tscp)) {
4586 				tscp->result = HOST_BYTE(DID_RESET);
4587 			}
4588 			last_scp = new_last_scp;
4589 		}
4590 	}
4591 
4592 	/* Save the time of the most recently completed reset. */
4593 	boardp->last_reset = jiffies;
4594 
4595 	/* Clear reset flag. */
4596 	boardp->flags &= ~ASC_HOST_IN_RESET;
4597 	spin_unlock_irqrestore(&boardp->lock, flags);
4598 
4599 	/*
4600 	 * Complete all the 'done_scp' requests.
4601 	 */
4602 	if (done_scp != NULL) {
4603 		asc_scsi_done_list(done_scp);
4604 	}
4605 
4606 	ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
4607 
4608 	return ret;
4609 }
4610 
4611 /*
4612  * advansys_biosparam()
4613  *
4614  * Translate disk drive geometry if the "BIOS greater than 1 GB"
4615  * support is enabled for a drive.
4616  *
4617  * ip (information pointer) is an int array with the following definition:
4618  * ip[0]: heads
4619  * ip[1]: sectors
4620  * ip[2]: cylinders
4621  */
4622 static int
4623 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
4624 		   sector_t capacity, int ip[])
4625 {
4626 	asc_board_t *boardp;
4627 
4628 	ASC_DBG(1, "advansys_biosparam: begin\n");
4629 	ASC_STATS(sdev->host, biosparam);
4630 	boardp = ASC_BOARDP(sdev->host);
4631 	if (ASC_NARROW_BOARD(boardp)) {
4632 		if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
4633 		     ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
4634 			ip[0] = 255;
4635 			ip[1] = 63;
4636 		} else {
4637 			ip[0] = 64;
4638 			ip[1] = 32;
4639 		}
4640 	} else {
4641 		if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
4642 		     BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
4643 			ip[0] = 255;
4644 			ip[1] = 63;
4645 		} else {
4646 			ip[0] = 64;
4647 			ip[1] = 32;
4648 		}
4649 	}
4650 	ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
4651 	ASC_DBG(1, "advansys_biosparam: end\n");
4652 	return 0;
4653 }
4654 
4655 static int __init advansys_detect(struct scsi_host_template *tpnt);
4656 static int advansys_release(struct Scsi_Host *shp);
4657 
4658 static struct scsi_host_template driver_template = {
4659 	.proc_name = "advansys",
4660 #ifdef CONFIG_PROC_FS
4661 	.proc_info = advansys_proc_info,
4662 #endif
4663 	.name = "advansys",
4664 	.detect = advansys_detect,
4665 	.release = advansys_release,
4666 	.info = advansys_info,
4667 	.queuecommand = advansys_queuecommand,
4668 	.eh_bus_reset_handler = advansys_reset,
4669 	.bios_param = advansys_biosparam,
4670 	.slave_configure = advansys_slave_configure,
4671 	/*
4672 	 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
4673 	 * must be set. The flag will be cleared in advansys_detect for non-ISA
4674 	 * adapters. Refer to the comment in scsi_module.c for more information.
4675 	 */
4676 	.unchecked_isa_dma = 1,
4677 	/*
4678 	 * All adapters controlled by this driver are capable of large
4679 	 * scatter-gather lists. According to the mid-level SCSI documentation
4680 	 * this obviates any performance gain provided by setting
4681 	 * 'use_clustering'. But empirically while CPU utilization is increased
4682 	 * by enabling clustering, I/O throughput increases as well.
4683 	 */
4684 	.use_clustering = ENABLE_CLUSTERING,
4685 };
4686 
4687 #include "scsi_module.c"
4688 
4689 /*
4690  * --- Miscellaneous Driver Functions
4691  */
4692 
4693 /*
4694  * First-level interrupt handler.
4695  *
4696  * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
4697  * all boards are currently checked for interrupts on each interrupt, 'dev_id'
4698  * is not referenced. 'dev_id' could be used to identify an interrupt passed
4699  * to the AdvanSys driver which is for a device sharing an interrupt with
4700  * an AdvanSys adapter.
4701  */
4702 static irqreturn_t advansys_interrupt(int irq, void *dev_id)
4703 {
4704 	ulong flags;
4705 	int i;
4706 	asc_board_t *boardp;
4707 	struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4708 	struct scsi_cmnd *new_last_scp;
4709 	struct Scsi_Host *shost;
4710 
4711 	ASC_DBG(1, "advansys_interrupt: begin\n");
4712 
4713 	/*
4714 	 * Check for interrupts on all boards.
4715 	 * AscISR() will call asc_isr_callback().
4716 	 */
4717 	for (i = 0; i < asc_board_count; i++) {
4718 		shost = asc_host[i];
4719 		boardp = ASC_BOARDP(shost);
4720 		ASC_DBG2(2, "advansys_interrupt: i %d, boardp 0x%lx\n",
4721 			 i, (ulong)boardp);
4722 		spin_lock_irqsave(&boardp->lock, flags);
4723 		if (ASC_NARROW_BOARD(boardp)) {
4724 			/*
4725 			 * Narrow Board
4726 			 */
4727 			if (AscIsIntPending(shost->io_port)) {
4728 				ASC_STATS(shost, interrupt);
4729 				ASC_DBG(1,
4730 					"advansys_interrupt: before AscISR()\n");
4731 				AscISR(&boardp->dvc_var.asc_dvc_var);
4732 			}
4733 		} else {
4734 			/*
4735 			 * Wide Board
4736 			 */
4737 			ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
4738 			if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
4739 				ASC_STATS(shost, interrupt);
4740 			}
4741 		}
4742 
4743 		/*
4744 		 * Start waiting requests and create a list of completed requests.
4745 		 *
4746 		 * If a reset request is being performed for the board, the reset
4747 		 * handler will complete pending requests after it has completed.
4748 		 */
4749 		if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
4750 			ASC_DBG2(1,
4751 				 "advansys_interrupt: done_scp 0x%lx, last_scp 0x%lx\n",
4752 				 (ulong)done_scp, (ulong)last_scp);
4753 
4754 			/* Start any waiting commands for the board. */
4755 			if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4756 				ASC_DBG(1,
4757 					"advansys_interrupt: before asc_execute_queue()\n");
4758 				asc_execute_queue(&boardp->waiting);
4759 			}
4760 
4761 			/*
4762 			 * Add to the list of requests that must be completed.
4763 			 *
4764 			 * 'done_scp' will always be NULL on the first iteration
4765 			 * of this loop. 'last_scp' is set at the same time as
4766 			 * 'done_scp'.
4767 			 */
4768 			if (done_scp == NULL) {
4769 				done_scp =
4770 				    asc_dequeue_list(&boardp->done, &last_scp,
4771 						     ASC_TID_ALL);
4772 			} else {
4773 				ASC_ASSERT(last_scp != NULL);
4774 				last_scp->host_scribble =
4775 				    (unsigned char *)asc_dequeue_list(&boardp->
4776 								      done,
4777 								      &new_last_scp,
4778 								      ASC_TID_ALL);
4779 				if (new_last_scp != NULL) {
4780 					ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4781 					last_scp = new_last_scp;
4782 				}
4783 			}
4784 		}
4785 		spin_unlock_irqrestore(&boardp->lock, flags);
4786 	}
4787 
4788 	/*
4789 	 * If interrupts were enabled on entry, then they
4790 	 * are now enabled here.
4791 	 *
4792 	 * Complete all requests on the done list.
4793 	 */
4794 
4795 	asc_scsi_done_list(done_scp);
4796 
4797 	ASC_DBG(1, "advansys_interrupt: end\n");
4798 	return IRQ_HANDLED;
4799 }
4800 
4801 /*
4802  * Set the number of commands to queue per device for the
4803  * specified host adapter.
4804  */
4805 static int advansys_slave_configure(struct scsi_device *device)
4806 {
4807 	asc_board_t *boardp;
4808 
4809 	boardp = ASC_BOARDP(device->host);
4810 	boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
4811 	/*
4812 	 * Save a pointer to the device and set its initial/maximum
4813 	 * queue depth.  Only save the pointer for a lun0 dev though.
4814 	 */
4815 	if (device->lun == 0)
4816 		boardp->device[device->id] = device;
4817 	if (device->tagged_supported) {
4818 		if (ASC_NARROW_BOARD(boardp)) {
4819 			scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
4820 						boardp->dvc_var.asc_dvc_var.
4821 						max_dvc_qng[device->id]);
4822 		} else {
4823 			scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
4824 						boardp->dvc_var.adv_dvc_var.
4825 						max_dvc_qng);
4826 		}
4827 	} else {
4828 		scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun);
4829 	}
4830 	ASC_DBG4(1,
4831 		 "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n",
4832 		 (ulong)device, (ulong)boardp, device->id, device->queue_depth);
4833 	return 0;
4834 }
4835 
4836 /*
4837  * Complete all requests on the singly linked list pointed
4838  * to by 'scp'.
4839  *
4840  * Interrupts can be enabled on entry.
4841  */
4842 static void asc_scsi_done_list(struct scsi_cmnd *scp)
4843 {
4844 	struct scsi_cmnd *tscp;
4845 
4846 	ASC_DBG(2, "asc_scsi_done_list: begin\n");
4847 	while (scp != NULL) {
4848 		asc_board_t *boardp;
4849 		struct device *dev;
4850 
4851 		ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp);
4852 		tscp = REQPNEXT(scp);
4853 		scp->host_scribble = NULL;
4854 
4855 		boardp = ASC_BOARDP(scp->device->host);
4856 
4857 		if (ASC_NARROW_BOARD(boardp))
4858 			dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
4859 		else
4860 			dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
4861 
4862 		if (scp->use_sg)
4863 			dma_unmap_sg(dev,
4864 				     (struct scatterlist *)scp->request_buffer,
4865 				     scp->use_sg, scp->sc_data_direction);
4866 		else if (scp->request_bufflen)
4867 			dma_unmap_single(dev, scp->SCp.dma_handle,
4868 					 scp->request_bufflen,
4869 					 scp->sc_data_direction);
4870 
4871 		ASC_STATS(scp->device->host, done);
4872 		ASC_ASSERT(scp->scsi_done != NULL);
4873 
4874 		scp->scsi_done(scp);
4875 
4876 		scp = tscp;
4877 	}
4878 	ASC_DBG(2, "asc_scsi_done_list: done\n");
4879 	return;
4880 }
4881 
4882 /*
4883  * Execute a single 'Scsi_Cmnd'.
4884  *
4885  * The function 'done' is called when the request has been completed.
4886  *
4887  * Scsi_Cmnd:
4888  *
4889  *  host - board controlling device
4890  *  device - device to send command
4891  *  target - target of device
4892  *  lun - lun of device
4893  *  cmd_len - length of SCSI CDB
4894  *  cmnd - buffer for SCSI 8, 10, or 12 byte CDB
4895  *  use_sg - if non-zero indicates scatter-gather request with use_sg elements
4896  *
4897  *  if (use_sg == 0) {
4898  *    request_buffer - buffer address for request
4899  *    request_bufflen - length of request buffer
4900  *  } else {
4901  *    request_buffer - pointer to scatterlist structure
4902  *  }
4903  *
4904  *  sense_buffer - sense command buffer
4905  *
4906  *  result (4 bytes of an int):
4907  *    Byte Meaning
4908  *    0 SCSI Status Byte Code
4909  *    1 SCSI One Byte Message Code
4910  *    2 Host Error Code
4911  *    3 Mid-Level Error Code
4912  *
4913  *  host driver fields:
4914  *    SCp - Scsi_Pointer used for command processing status
4915  *    scsi_done - used to save caller's done function
4916  *    host_scribble - used for pointer to another struct scsi_cmnd
4917  *
4918  * If this function returns ASC_NOERROR the request has been enqueued
4919  * on the board's 'active' queue and will be completed from the
4920  * interrupt handler.
4921  *
4922  * If this function returns ASC_NOERROR the request has been enqueued
4923  * on the board's 'done' queue and must be completed by the caller.
4924  *
4925  * If ASC_BUSY is returned the request will be enqueued by the
4926  * caller on the target's waiting queue and re-tried later.
4927  */
4928 static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
4929 {
4930 	asc_board_t *boardp;
4931 	ASC_DVC_VAR *asc_dvc_varp;
4932 	ADV_DVC_VAR *adv_dvc_varp;
4933 	ADV_SCSI_REQ_Q *adv_scsiqp;
4934 	struct scsi_device *device;
4935 	int ret;
4936 
4937 	ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
4938 		 (ulong)scp, (ulong)scp->scsi_done);
4939 
4940 	boardp = ASC_BOARDP(scp->device->host);
4941 	device = boardp->device[scp->device->id];
4942 
4943 	if (ASC_NARROW_BOARD(boardp)) {
4944 		/*
4945 		 * Build and execute Narrow Board request.
4946 		 */
4947 
4948 		asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4949 
4950 		/*
4951 		 * Build Asc Library request structure using the
4952 		 * global structures 'asc_scsi_req' and 'asc_sg_head'.
4953 		 *
4954 		 * If an error is returned, then the request has been
4955 		 * queued on the board done queue. It will be completed
4956 		 * by the caller.
4957 		 *
4958 		 * asc_build_req() can not return ASC_BUSY.
4959 		 */
4960 		if (asc_build_req(boardp, scp) == ASC_ERROR) {
4961 			ASC_STATS(scp->device->host, build_error);
4962 			return ASC_ERROR;
4963 		}
4964 
4965 		/*
4966 		 * Execute the command. If there is no error, add the command
4967 		 * to the active queue.
4968 		 */
4969 		switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
4970 		case ASC_NOERROR:
4971 			ASC_STATS(scp->device->host, exe_noerror);
4972 			/*
4973 			 * Increment monotonically increasing per device successful
4974 			 * request counter. Wrapping doesn't matter.
4975 			 */
4976 			boardp->reqcnt[scp->device->id]++;
4977 			asc_enqueue(&boardp->active, scp, ASC_BACK);
4978 			ASC_DBG(1,
4979 				"asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
4980 			break;
4981 		case ASC_BUSY:
4982 			/*
4983 			 * Caller will enqueue request on the target's waiting queue
4984 			 * and retry later.
4985 			 */
4986 			ASC_STATS(scp->device->host, exe_busy);
4987 			break;
4988 		case ASC_ERROR:
4989 			ASC_PRINT2
4990 			    ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4991 			     boardp->id, asc_dvc_varp->err_code);
4992 			ASC_STATS(scp->device->host, exe_error);
4993 			scp->result = HOST_BYTE(DID_ERROR);
4994 			asc_enqueue(&boardp->done, scp, ASC_BACK);
4995 			break;
4996 		default:
4997 			ASC_PRINT2
4998 			    ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
4999 			     boardp->id, asc_dvc_varp->err_code);
5000 			ASC_STATS(scp->device->host, exe_unknown);
5001 			scp->result = HOST_BYTE(DID_ERROR);
5002 			asc_enqueue(&boardp->done, scp, ASC_BACK);
5003 			break;
5004 		}
5005 	} else {
5006 		/*
5007 		 * Build and execute Wide Board request.
5008 		 */
5009 		adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5010 
5011 		/*
5012 		 * Build and get a pointer to an Adv Library request structure.
5013 		 *
5014 		 * If the request is successfully built then send it below,
5015 		 * otherwise return with an error.
5016 		 */
5017 		switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
5018 		case ASC_NOERROR:
5019 			ASC_DBG(3,
5020 				"asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
5021 			break;
5022 		case ASC_BUSY:
5023 			ASC_DBG(1,
5024 				"asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
5025 			/*
5026 			 * If busy is returned the request has not been enqueued.
5027 			 * It will be enqueued by the caller on the target's waiting
5028 			 * queue and retried later.
5029 			 *
5030 			 * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg'
5031 			 * count wide board busy conditions. They are updated in
5032 			 * adv_build_req and adv_get_sglist, respectively.
5033 			 */
5034 			return ASC_BUSY;
5035 		case ASC_ERROR:
5036 			/*
5037 			 * If an error is returned, then the request has been
5038 			 * queued on the board done queue. It will be completed
5039 			 * by the caller.
5040 			 */
5041 		default:
5042 			ASC_DBG(1,
5043 				"asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
5044 			ASC_STATS(scp->device->host, build_error);
5045 			return ASC_ERROR;
5046 		}
5047 
5048 		/*
5049 		 * Execute the command. If there is no error, add the command
5050 		 * to the active queue.
5051 		 */
5052 		switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
5053 		case ASC_NOERROR:
5054 			ASC_STATS(scp->device->host, exe_noerror);
5055 			/*
5056 			 * Increment monotonically increasing per device successful
5057 			 * request counter. Wrapping doesn't matter.
5058 			 */
5059 			boardp->reqcnt[scp->device->id]++;
5060 			asc_enqueue(&boardp->active, scp, ASC_BACK);
5061 			ASC_DBG(1,
5062 				"asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
5063 			break;
5064 		case ASC_BUSY:
5065 			/*
5066 			 * Caller will enqueue request on the target's waiting queue
5067 			 * and retry later.
5068 			 */
5069 			ASC_STATS(scp->device->host, exe_busy);
5070 			break;
5071 		case ASC_ERROR:
5072 			ASC_PRINT2
5073 			    ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
5074 			     boardp->id, adv_dvc_varp->err_code);
5075 			ASC_STATS(scp->device->host, exe_error);
5076 			scp->result = HOST_BYTE(DID_ERROR);
5077 			asc_enqueue(&boardp->done, scp, ASC_BACK);
5078 			break;
5079 		default:
5080 			ASC_PRINT2
5081 			    ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
5082 			     boardp->id, adv_dvc_varp->err_code);
5083 			ASC_STATS(scp->device->host, exe_unknown);
5084 			scp->result = HOST_BYTE(DID_ERROR);
5085 			asc_enqueue(&boardp->done, scp, ASC_BACK);
5086 			break;
5087 		}
5088 	}
5089 
5090 	ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
5091 	return ret;
5092 }
5093 
5094 /*
5095  * Build a request structure for the Asc Library (Narrow Board).
5096  *
5097  * The global structures 'asc_scsi_q' and 'asc_sg_head' are
5098  * used to build the request.
5099  *
5100  * If an error occurs, then queue the request on the board done
5101  * queue and return ASC_ERROR.
5102  */
5103 static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
5104 {
5105 	struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
5106 
5107 	/*
5108 	 * Mutually exclusive access is required to 'asc_scsi_q' and
5109 	 * 'asc_sg_head' until after the request is started.
5110 	 */
5111 	memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
5112 
5113 	/*
5114 	 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
5115 	 */
5116 	asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
5117 
5118 	/*
5119 	 * Build the ASC_SCSI_Q request.
5120 	 *
5121 	 * For narrow boards a CDB length maximum of 12 bytes
5122 	 * is supported.
5123 	 */
5124 	if (scp->cmd_len > ASC_MAX_CDB_LEN) {
5125 		ASC_PRINT3
5126 		    ("asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN  %d\n",
5127 		     boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN);
5128 		scp->result = HOST_BYTE(DID_ERROR);
5129 		asc_enqueue(&boardp->done, scp, ASC_BACK);
5130 		return ASC_ERROR;
5131 	}
5132 	asc_scsi_q.cdbptr = &scp->cmnd[0];
5133 	asc_scsi_q.q2.cdb_len = scp->cmd_len;
5134 	asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
5135 	asc_scsi_q.q1.target_lun = scp->device->lun;
5136 	asc_scsi_q.q2.target_ix =
5137 	    ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
5138 	asc_scsi_q.q1.sense_addr =
5139 	    cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
5140 	asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
5141 
5142 	/*
5143 	 * If there are any outstanding requests for the current target,
5144 	 * then every 255th request send an ORDERED request. This heuristic
5145 	 * tries to retain the benefit of request sorting while preventing
5146 	 * request starvation. 255 is the max number of tags or pending commands
5147 	 * a device may have outstanding.
5148 	 *
5149 	 * The request count is incremented below for every successfully
5150 	 * started request.
5151 	 *
5152 	 */
5153 	if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
5154 	    (boardp->reqcnt[scp->device->id] % 255) == 0) {
5155 		asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
5156 	} else {
5157 		asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
5158 	}
5159 
5160 	/*
5161 	 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
5162 	 * buffer command.
5163 	 */
5164 	if (scp->use_sg == 0) {
5165 		/*
5166 		 * CDB request of single contiguous buffer.
5167 		 */
5168 		ASC_STATS(scp->device->host, cont_cnt);
5169 		scp->SCp.dma_handle = scp->request_bufflen ?
5170 		    dma_map_single(dev, scp->request_buffer,
5171 				   scp->request_bufflen,
5172 				   scp->sc_data_direction) : 0;
5173 		asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
5174 		asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
5175 		ASC_STATS_ADD(scp->device->host, cont_xfer,
5176 			      ASC_CEILING(scp->request_bufflen, 512));
5177 		asc_scsi_q.q1.sg_queue_cnt = 0;
5178 		asc_scsi_q.sg_head = NULL;
5179 	} else {
5180 		/*
5181 		 * CDB scatter-gather request list.
5182 		 */
5183 		int sgcnt;
5184 		int use_sg;
5185 		struct scatterlist *slp;
5186 
5187 		slp = (struct scatterlist *)scp->request_buffer;
5188 		use_sg =
5189 		    dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
5190 
5191 		if (use_sg > scp->device->host->sg_tablesize) {
5192 			ASC_PRINT3
5193 			    ("asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
5194 			     boardp->id, use_sg,
5195 			     scp->device->host->sg_tablesize);
5196 			dma_unmap_sg(dev, slp, scp->use_sg,
5197 				     scp->sc_data_direction);
5198 			scp->result = HOST_BYTE(DID_ERROR);
5199 			asc_enqueue(&boardp->done, scp, ASC_BACK);
5200 			return ASC_ERROR;
5201 		}
5202 
5203 		ASC_STATS(scp->device->host, sg_cnt);
5204 
5205 		/*
5206 		 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
5207 		 * structure to point to it.
5208 		 */
5209 		memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
5210 
5211 		asc_scsi_q.q1.cntl |= QC_SG_HEAD;
5212 		asc_scsi_q.sg_head = &asc_sg_head;
5213 		asc_scsi_q.q1.data_cnt = 0;
5214 		asc_scsi_q.q1.data_addr = 0;
5215 		/* This is a byte value, otherwise it would need to be swapped. */
5216 		asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
5217 		ASC_STATS_ADD(scp->device->host, sg_elem,
5218 			      asc_sg_head.entry_cnt);
5219 
5220 		/*
5221 		 * Convert scatter-gather list into ASC_SG_HEAD list.
5222 		 */
5223 		for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
5224 			asc_sg_head.sg_list[sgcnt].addr =
5225 			    cpu_to_le32(sg_dma_address(slp));
5226 			asc_sg_head.sg_list[sgcnt].bytes =
5227 			    cpu_to_le32(sg_dma_len(slp));
5228 			ASC_STATS_ADD(scp->device->host, sg_xfer,
5229 				      ASC_CEILING(sg_dma_len(slp), 512));
5230 		}
5231 	}
5232 
5233 	ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
5234 	ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
5235 
5236 	return ASC_NOERROR;
5237 }
5238 
5239 /*
5240  * Build a request structure for the Adv Library (Wide Board).
5241  *
5242  * If an adv_req_t can not be allocated to issue the request,
5243  * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
5244  *
5245  * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
5246  * microcode for DMA addresses or math operations are byte swapped
5247  * to little-endian order.
5248  */
5249 static int
5250 adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
5251 	      ADV_SCSI_REQ_Q **adv_scsiqpp)
5252 {
5253 	adv_req_t *reqp;
5254 	ADV_SCSI_REQ_Q *scsiqp;
5255 	int i;
5256 	int ret;
5257 	struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
5258 
5259 	/*
5260 	 * Allocate an adv_req_t structure from the board to execute
5261 	 * the command.
5262 	 */
5263 	if (boardp->adv_reqp == NULL) {
5264 		ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
5265 		ASC_STATS(scp->device->host, adv_build_noreq);
5266 		return ASC_BUSY;
5267 	} else {
5268 		reqp = boardp->adv_reqp;
5269 		boardp->adv_reqp = reqp->next_reqp;
5270 		reqp->next_reqp = NULL;
5271 	}
5272 
5273 	/*
5274 	 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
5275 	 */
5276 	scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5277 
5278 	/*
5279 	 * Initialize the structure.
5280 	 */
5281 	scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
5282 
5283 	/*
5284 	 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
5285 	 */
5286 	scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
5287 
5288 	/*
5289 	 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
5290 	 */
5291 	reqp->cmndp = scp;
5292 
5293 	/*
5294 	 * Build the ADV_SCSI_REQ_Q request.
5295 	 */
5296 
5297 	/*
5298 	 * Set CDB length and copy it to the request structure.
5299 	 * For wide  boards a CDB length maximum of 16 bytes
5300 	 * is supported.
5301 	 */
5302 	if (scp->cmd_len > ADV_MAX_CDB_LEN) {
5303 		ASC_PRINT3
5304 		    ("adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN  %d\n",
5305 		     boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
5306 		scp->result = HOST_BYTE(DID_ERROR);
5307 		asc_enqueue(&boardp->done, scp, ASC_BACK);
5308 		return ASC_ERROR;
5309 	}
5310 	scsiqp->cdb_len = scp->cmd_len;
5311 	/* Copy first 12 CDB bytes to cdb[]. */
5312 	for (i = 0; i < scp->cmd_len && i < 12; i++) {
5313 		scsiqp->cdb[i] = scp->cmnd[i];
5314 	}
5315 	/* Copy last 4 CDB bytes, if present, to cdb16[]. */
5316 	for (; i < scp->cmd_len; i++) {
5317 		scsiqp->cdb16[i - 12] = scp->cmnd[i];
5318 	}
5319 
5320 	scsiqp->target_id = scp->device->id;
5321 	scsiqp->target_lun = scp->device->lun;
5322 
5323 	scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
5324 	scsiqp->sense_len = sizeof(scp->sense_buffer);
5325 
5326 	/*
5327 	 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
5328 	 * buffer command.
5329 	 */
5330 
5331 	scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
5332 	scsiqp->vdata_addr = scp->request_buffer;
5333 	scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
5334 
5335 	if (scp->use_sg == 0) {
5336 		/*
5337 		 * CDB request of single contiguous buffer.
5338 		 */
5339 		reqp->sgblkp = NULL;
5340 		scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
5341 		if (scp->request_bufflen) {
5342 			scsiqp->vdata_addr = scp->request_buffer;
5343 			scp->SCp.dma_handle =
5344 			    dma_map_single(dev, scp->request_buffer,
5345 					   scp->request_bufflen,
5346 					   scp->sc_data_direction);
5347 		} else {
5348 			scsiqp->vdata_addr = NULL;
5349 			scp->SCp.dma_handle = 0;
5350 		}
5351 		scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
5352 		scsiqp->sg_list_ptr = NULL;
5353 		scsiqp->sg_real_addr = 0;
5354 		ASC_STATS(scp->device->host, cont_cnt);
5355 		ASC_STATS_ADD(scp->device->host, cont_xfer,
5356 			      ASC_CEILING(scp->request_bufflen, 512));
5357 	} else {
5358 		/*
5359 		 * CDB scatter-gather request list.
5360 		 */
5361 		struct scatterlist *slp;
5362 		int use_sg;
5363 
5364 		slp = (struct scatterlist *)scp->request_buffer;
5365 		use_sg =
5366 		    dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
5367 
5368 		if (use_sg > ADV_MAX_SG_LIST) {
5369 			ASC_PRINT3
5370 			    ("adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
5371 			     boardp->id, use_sg,
5372 			     scp->device->host->sg_tablesize);
5373 			dma_unmap_sg(dev, slp, scp->use_sg,
5374 				     scp->sc_data_direction);
5375 			scp->result = HOST_BYTE(DID_ERROR);
5376 			asc_enqueue(&boardp->done, scp, ASC_BACK);
5377 
5378 			/*
5379 			 * Free the 'adv_req_t' structure by adding it back to the
5380 			 * board free list.
5381 			 */
5382 			reqp->next_reqp = boardp->adv_reqp;
5383 			boardp->adv_reqp = reqp;
5384 
5385 			return ASC_ERROR;
5386 		}
5387 
5388 		if ((ret =
5389 		     adv_get_sglist(boardp, reqp, scp,
5390 				    use_sg)) != ADV_SUCCESS) {
5391 			/*
5392 			 * Free the adv_req_t structure by adding it back to the
5393 			 * board free list.
5394 			 */
5395 			reqp->next_reqp = boardp->adv_reqp;
5396 			boardp->adv_reqp = reqp;
5397 
5398 			return ret;
5399 		}
5400 
5401 		ASC_STATS(scp->device->host, sg_cnt);
5402 		ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
5403 	}
5404 
5405 	ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5406 	ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
5407 
5408 	*adv_scsiqpp = scsiqp;
5409 
5410 	return ASC_NOERROR;
5411 }
5412 
5413 /*
5414  * Build scatter-gather list for Adv Library (Wide Board).
5415  *
5416  * Additional ADV_SG_BLOCK structures will need to be allocated
5417  * if the total number of scatter-gather elements exceeds
5418  * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
5419  * assumed to be physically contiguous.
5420  *
5421  * Return:
5422  *      ADV_SUCCESS(1) - SG List successfully created
5423  *      ADV_ERROR(-1) - SG List creation failed
5424  */
5425 static int
5426 adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
5427 	       int use_sg)
5428 {
5429 	adv_sgblk_t *sgblkp;
5430 	ADV_SCSI_REQ_Q *scsiqp;
5431 	struct scatterlist *slp;
5432 	int sg_elem_cnt;
5433 	ADV_SG_BLOCK *sg_block, *prev_sg_block;
5434 	ADV_PADDR sg_block_paddr;
5435 	int i;
5436 
5437 	scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5438 	slp = (struct scatterlist *)scp->request_buffer;
5439 	sg_elem_cnt = use_sg;
5440 	prev_sg_block = NULL;
5441 	reqp->sgblkp = NULL;
5442 
5443 	do {
5444 		/*
5445 		 * Allocate a 'adv_sgblk_t' structure from the board free
5446 		 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
5447 		 * (15) scatter-gather elements.
5448 		 */
5449 		if ((sgblkp = boardp->adv_sgblkp) == NULL) {
5450 			ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
5451 			ASC_STATS(scp->device->host, adv_build_nosg);
5452 
5453 			/*
5454 			 * Allocation failed. Free 'adv_sgblk_t' structures already
5455 			 * allocated for the request.
5456 			 */
5457 			while ((sgblkp = reqp->sgblkp) != NULL) {
5458 				/* Remove 'sgblkp' from the request list. */
5459 				reqp->sgblkp = sgblkp->next_sgblkp;
5460 
5461 				/* Add 'sgblkp' to the board free list. */
5462 				sgblkp->next_sgblkp = boardp->adv_sgblkp;
5463 				boardp->adv_sgblkp = sgblkp;
5464 			}
5465 			return ASC_BUSY;
5466 		} else {
5467 			/* Complete 'adv_sgblk_t' board allocation. */
5468 			boardp->adv_sgblkp = sgblkp->next_sgblkp;
5469 			sgblkp->next_sgblkp = NULL;
5470 
5471 			/*
5472 			 * Get 8 byte aligned virtual and physical addresses for
5473 			 * the allocated ADV_SG_BLOCK structure.
5474 			 */
5475 			sg_block =
5476 			    (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
5477 			sg_block_paddr = virt_to_bus(sg_block);
5478 
5479 			/*
5480 			 * Check if this is the first 'adv_sgblk_t' for the request.
5481 			 */
5482 			if (reqp->sgblkp == NULL) {
5483 				/* Request's first scatter-gather block. */
5484 				reqp->sgblkp = sgblkp;
5485 
5486 				/*
5487 				 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
5488 				 * address pointers.
5489 				 */
5490 				scsiqp->sg_list_ptr = sg_block;
5491 				scsiqp->sg_real_addr =
5492 				    cpu_to_le32(sg_block_paddr);
5493 			} else {
5494 				/* Request's second or later scatter-gather block. */
5495 				sgblkp->next_sgblkp = reqp->sgblkp;
5496 				reqp->sgblkp = sgblkp;
5497 
5498 				/*
5499 				 * Point the previous ADV_SG_BLOCK structure to
5500 				 * the newly allocated ADV_SG_BLOCK structure.
5501 				 */
5502 				ASC_ASSERT(prev_sg_block != NULL);
5503 				prev_sg_block->sg_ptr =
5504 				    cpu_to_le32(sg_block_paddr);
5505 			}
5506 		}
5507 
5508 		for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
5509 			sg_block->sg_list[i].sg_addr =
5510 			    cpu_to_le32(sg_dma_address(slp));
5511 			sg_block->sg_list[i].sg_count =
5512 			    cpu_to_le32(sg_dma_len(slp));
5513 			ASC_STATS_ADD(scp->device->host, sg_xfer,
5514 				      ASC_CEILING(sg_dma_len(slp), 512));
5515 
5516 			if (--sg_elem_cnt == 0) {	/* Last ADV_SG_BLOCK and scatter-gather entry. */
5517 				sg_block->sg_cnt = i + 1;
5518 				sg_block->sg_ptr = 0L;	/* Last ADV_SG_BLOCK in list. */
5519 				return ADV_SUCCESS;
5520 			}
5521 			slp++;
5522 		}
5523 		sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
5524 		prev_sg_block = sg_block;
5525 	}
5526 	while (1);
5527 	/* NOTREACHED */
5528 }
5529 
5530 /*
5531  * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
5532  *
5533  * Interrupt callback function for the Narrow SCSI Asc Library.
5534  */
5535 static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
5536 {
5537 	asc_board_t *boardp;
5538 	struct scsi_cmnd *scp;
5539 	struct Scsi_Host *shost;
5540 	int i;
5541 
5542 	ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
5543 		 (ulong)asc_dvc_varp, (ulong)qdonep);
5544 	ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
5545 
5546 	/*
5547 	 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5548 	 * command that has been completed.
5549 	 */
5550 	scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
5551 	ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp);
5552 
5553 	if (scp == NULL) {
5554 		ASC_PRINT("asc_isr_callback: scp is NULL\n");
5555 		return;
5556 	}
5557 	ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5558 
5559 	/*
5560 	 * If the request's host pointer is not valid, display a
5561 	 * message and return.
5562 	 */
5563 	shost = scp->device->host;
5564 	for (i = 0; i < asc_board_count; i++) {
5565 		if (asc_host[i] == shost) {
5566 			break;
5567 		}
5568 	}
5569 	if (i == asc_board_count) {
5570 		ASC_PRINT2
5571 		    ("asc_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
5572 		     (ulong)scp, (ulong)shost);
5573 		return;
5574 	}
5575 
5576 	ASC_STATS(shost, callback);
5577 	ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
5578 
5579 	/*
5580 	 * If the request isn't found on the active queue, it may
5581 	 * have been removed to handle a reset request.
5582 	 * Display a message and return.
5583 	 */
5584 	boardp = ASC_BOARDP(shost);
5585 	ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
5586 	if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5587 		ASC_PRINT2
5588 		    ("asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
5589 		     boardp->id, (ulong)scp);
5590 		return;
5591 	}
5592 
5593 	/*
5594 	 * 'qdonep' contains the command's ending status.
5595 	 */
5596 	switch (qdonep->d3.done_stat) {
5597 	case QD_NO_ERROR:
5598 		ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
5599 		scp->result = 0;
5600 
5601 		/*
5602 		 * If an INQUIRY command completed successfully, then call
5603 		 * the AscInquiryHandling() function to set-up the device.
5604 		 */
5605 		if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 &&
5606 		    (scp->request_bufflen - qdonep->remain_bytes) >= 8) {
5607 			AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7,
5608 					   (ASC_SCSI_INQUIRY *)scp->
5609 					   request_buffer);
5610 		}
5611 
5612 		/*
5613 		 * Check for an underrun condition.
5614 		 *
5615 		 * If there was no error and an underrun condition, then
5616 		 * then return the number of underrun bytes.
5617 		 */
5618 		if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
5619 		    qdonep->remain_bytes <= scp->request_bufflen) {
5620 			ASC_DBG1(1,
5621 				 "asc_isr_callback: underrun condition %u bytes\n",
5622 				 (unsigned)qdonep->remain_bytes);
5623 			scp->resid = qdonep->remain_bytes;
5624 		}
5625 		break;
5626 
5627 	case QD_WITH_ERROR:
5628 		ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
5629 		switch (qdonep->d3.host_stat) {
5630 		case QHSTA_NO_ERROR:
5631 			if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
5632 				ASC_DBG(2,
5633 					"asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5634 				ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5635 						  sizeof(scp->sense_buffer));
5636 				/*
5637 				 * Note: The 'status_byte()' macro used by target drivers
5638 				 * defined in scsi.h shifts the status byte returned by
5639 				 * host drivers right by 1 bit. This is why target drivers
5640 				 * also use right shifted status byte definitions. For
5641 				 * instance target drivers use CHECK_CONDITION, defined to
5642 				 * 0x1, instead of the SCSI defined check condition value
5643 				 * of 0x2. Host drivers are supposed to return the status
5644 				 * byte as it is defined by SCSI.
5645 				 */
5646 				scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5647 				    STATUS_BYTE(qdonep->d3.scsi_stat);
5648 			} else {
5649 				scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
5650 			}
5651 			break;
5652 
5653 		default:
5654 			/* QHSTA error occurred */
5655 			ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
5656 				 qdonep->d3.host_stat);
5657 			scp->result = HOST_BYTE(DID_BAD_TARGET);
5658 			break;
5659 		}
5660 		break;
5661 
5662 	case QD_ABORTED_BY_HOST:
5663 		ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
5664 		scp->result =
5665 		    HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
5666 						    scsi_msg) |
5667 		    STATUS_BYTE(qdonep->d3.scsi_stat);
5668 		break;
5669 
5670 	default:
5671 		ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n",
5672 			 qdonep->d3.done_stat);
5673 		scp->result =
5674 		    HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
5675 						    scsi_msg) |
5676 		    STATUS_BYTE(qdonep->d3.scsi_stat);
5677 		break;
5678 	}
5679 
5680 	/*
5681 	 * If the 'init_tidmask' bit isn't already set for the target and the
5682 	 * current request finished normally, then set the bit for the target
5683 	 * to indicate that a device is present.
5684 	 */
5685 	if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5686 	    qdonep->d3.done_stat == QD_NO_ERROR &&
5687 	    qdonep->d3.host_stat == QHSTA_NO_ERROR) {
5688 		boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5689 	}
5690 
5691 	/*
5692 	 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5693 	 * function, add the command to the end of the board's done queue.
5694 	 * The done function for the command will be called from
5695 	 * advansys_interrupt().
5696 	 */
5697 	asc_enqueue(&boardp->done, scp, ASC_BACK);
5698 
5699 	return;
5700 }
5701 
5702 /*
5703  * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
5704  *
5705  * Callback function for the Wide SCSI Adv Library.
5706  */
5707 static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
5708 {
5709 	asc_board_t *boardp;
5710 	adv_req_t *reqp;
5711 	adv_sgblk_t *sgblkp;
5712 	struct scsi_cmnd *scp;
5713 	struct Scsi_Host *shost;
5714 	int i;
5715 	ADV_DCNT resid_cnt;
5716 
5717 	ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
5718 		 (ulong)adv_dvc_varp, (ulong)scsiqp);
5719 	ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5720 
5721 	/*
5722 	 * Get the adv_req_t structure for the command that has been
5723 	 * completed. The adv_req_t structure actually contains the
5724 	 * completed ADV_SCSI_REQ_Q structure.
5725 	 */
5726 	reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
5727 	ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp);
5728 	if (reqp == NULL) {
5729 		ASC_PRINT("adv_isr_callback: reqp is NULL\n");
5730 		return;
5731 	}
5732 
5733 	/*
5734 	 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5735 	 * command that has been completed.
5736 	 *
5737 	 * Note: The adv_req_t request structure and adv_sgblk_t structure,
5738 	 * if any, are dropped, because a board structure pointer can not be
5739 	 * determined.
5740 	 */
5741 	scp = reqp->cmndp;
5742 	ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp);
5743 	if (scp == NULL) {
5744 		ASC_PRINT
5745 		    ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
5746 		return;
5747 	}
5748 	ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5749 
5750 	/*
5751 	 * If the request's host pointer is not valid, display a message
5752 	 * and return.
5753 	 */
5754 	shost = scp->device->host;
5755 	for (i = 0; i < asc_board_count; i++) {
5756 		if (asc_host[i] == shost) {
5757 			break;
5758 		}
5759 	}
5760 	/*
5761 	 * Note: If the host structure is not found, the adv_req_t request
5762 	 * structure and adv_sgblk_t structure, if any, is dropped.
5763 	 */
5764 	if (i == asc_board_count) {
5765 		ASC_PRINT2
5766 		    ("adv_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
5767 		     (ulong)scp, (ulong)shost);
5768 		return;
5769 	}
5770 
5771 	ASC_STATS(shost, callback);
5772 	ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
5773 
5774 	/*
5775 	 * If the request isn't found on the active queue, it may have been
5776 	 * removed to handle a reset request. Display a message and return.
5777 	 *
5778 	 * Note: Because the structure may still be in use don't attempt
5779 	 * to free the adv_req_t and adv_sgblk_t, if any, structures.
5780 	 */
5781 	boardp = ASC_BOARDP(shost);
5782 	ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
5783 	if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5784 		ASC_PRINT2
5785 		    ("adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
5786 		     boardp->id, (ulong)scp);
5787 		return;
5788 	}
5789 
5790 	/*
5791 	 * 'done_status' contains the command's ending status.
5792 	 */
5793 	switch (scsiqp->done_status) {
5794 	case QD_NO_ERROR:
5795 		ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
5796 		scp->result = 0;
5797 
5798 		/*
5799 		 * Check for an underrun condition.
5800 		 *
5801 		 * If there was no error and an underrun condition, then
5802 		 * then return the number of underrun bytes.
5803 		 */
5804 		resid_cnt = le32_to_cpu(scsiqp->data_cnt);
5805 		if (scp->request_bufflen != 0 && resid_cnt != 0 &&
5806 		    resid_cnt <= scp->request_bufflen) {
5807 			ASC_DBG1(1,
5808 				 "adv_isr_callback: underrun condition %lu bytes\n",
5809 				 (ulong)resid_cnt);
5810 			scp->resid = resid_cnt;
5811 		}
5812 		break;
5813 
5814 	case QD_WITH_ERROR:
5815 		ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
5816 		switch (scsiqp->host_status) {
5817 		case QHSTA_NO_ERROR:
5818 			if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
5819 				ASC_DBG(2,
5820 					"adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5821 				ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5822 						  sizeof(scp->sense_buffer));
5823 				/*
5824 				 * Note: The 'status_byte()' macro used by target drivers
5825 				 * defined in scsi.h shifts the status byte returned by
5826 				 * host drivers right by 1 bit. This is why target drivers
5827 				 * also use right shifted status byte definitions. For
5828 				 * instance target drivers use CHECK_CONDITION, defined to
5829 				 * 0x1, instead of the SCSI defined check condition value
5830 				 * of 0x2. Host drivers are supposed to return the status
5831 				 * byte as it is defined by SCSI.
5832 				 */
5833 				scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5834 				    STATUS_BYTE(scsiqp->scsi_status);
5835 			} else {
5836 				scp->result = STATUS_BYTE(scsiqp->scsi_status);
5837 			}
5838 			break;
5839 
5840 		default:
5841 			/* Some other QHSTA error occurred. */
5842 			ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
5843 				 scsiqp->host_status);
5844 			scp->result = HOST_BYTE(DID_BAD_TARGET);
5845 			break;
5846 		}
5847 		break;
5848 
5849 	case QD_ABORTED_BY_HOST:
5850 		ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
5851 		scp->result =
5852 		    HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
5853 		break;
5854 
5855 	default:
5856 		ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n",
5857 			 scsiqp->done_status);
5858 		scp->result =
5859 		    HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
5860 		break;
5861 	}
5862 
5863 	/*
5864 	 * If the 'init_tidmask' bit isn't already set for the target and the
5865 	 * current request finished normally, then set the bit for the target
5866 	 * to indicate that a device is present.
5867 	 */
5868 	if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5869 	    scsiqp->done_status == QD_NO_ERROR &&
5870 	    scsiqp->host_status == QHSTA_NO_ERROR) {
5871 		boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5872 	}
5873 
5874 	/*
5875 	 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5876 	 * function, add the command to the end of the board's done queue.
5877 	 * The done function for the command will be called from
5878 	 * advansys_interrupt().
5879 	 */
5880 	asc_enqueue(&boardp->done, scp, ASC_BACK);
5881 
5882 	/*
5883 	 * Free all 'adv_sgblk_t' structures allocated for the request.
5884 	 */
5885 	while ((sgblkp = reqp->sgblkp) != NULL) {
5886 		/* Remove 'sgblkp' from the request list. */
5887 		reqp->sgblkp = sgblkp->next_sgblkp;
5888 
5889 		/* Add 'sgblkp' to the board free list. */
5890 		sgblkp->next_sgblkp = boardp->adv_sgblkp;
5891 		boardp->adv_sgblkp = sgblkp;
5892 	}
5893 
5894 	/*
5895 	 * Free the adv_req_t structure used with the command by adding
5896 	 * it back to the board free list.
5897 	 */
5898 	reqp->next_reqp = boardp->adv_reqp;
5899 	boardp->adv_reqp = reqp;
5900 
5901 	ASC_DBG(1, "adv_isr_callback: done\n");
5902 
5903 	return;
5904 }
5905 
5906 /*
5907  * adv_async_callback() - Adv Library asynchronous event callback function.
5908  */
5909 static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
5910 {
5911 	switch (code) {
5912 	case ADV_ASYNC_SCSI_BUS_RESET_DET:
5913 		/*
5914 		 * The firmware detected a SCSI Bus reset.
5915 		 */
5916 		ASC_DBG(0,
5917 			"adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
5918 		break;
5919 
5920 	case ADV_ASYNC_RDMA_FAILURE:
5921 		/*
5922 		 * Handle RDMA failure by resetting the SCSI Bus and
5923 		 * possibly the chip if it is unresponsive. Log the error
5924 		 * with a unique code.
5925 		 */
5926 		ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
5927 		AdvResetChipAndSB(adv_dvc_varp);
5928 		break;
5929 
5930 	case ADV_HOST_SCSI_BUS_RESET:
5931 		/*
5932 		 * Host generated SCSI bus reset occurred.
5933 		 */
5934 		ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
5935 		break;
5936 
5937 	default:
5938 		ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
5939 		break;
5940 	}
5941 }
5942 
5943 /*
5944  * Add a 'REQP' to the end of specified queue. Set 'tidmask'
5945  * to indicate a command is queued for the device.
5946  *
5947  * 'flag' may be either ASC_FRONT or ASC_BACK.
5948  *
5949  * 'REQPNEXT(reqp)' returns reqp's next pointer.
5950  */
5951 static void asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
5952 {
5953 	int tid;
5954 
5955 	ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
5956 		 (ulong)ascq, (ulong)reqp, flag);
5957 	ASC_ASSERT(reqp != NULL);
5958 	ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
5959 	tid = REQPTID(reqp);
5960 	ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5961 	if (flag == ASC_FRONT) {
5962 		reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
5963 		ascq->q_first[tid] = reqp;
5964 		/* If the queue was empty, set the last pointer. */
5965 		if (ascq->q_last[tid] == NULL) {
5966 			ascq->q_last[tid] = reqp;
5967 		}
5968 	} else {		/* ASC_BACK */
5969 		if (ascq->q_last[tid] != NULL) {
5970 			ascq->q_last[tid]->host_scribble =
5971 			    (unsigned char *)reqp;
5972 		}
5973 		ascq->q_last[tid] = reqp;
5974 		reqp->host_scribble = NULL;
5975 		/* If the queue was empty, set the first pointer. */
5976 		if (ascq->q_first[tid] == NULL) {
5977 			ascq->q_first[tid] = reqp;
5978 		}
5979 	}
5980 	/* The queue has at least one entry, set its bit. */
5981 	ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
5982 #ifdef ADVANSYS_STATS
5983 	/* Maintain request queue statistics. */
5984 	ascq->q_tot_cnt[tid]++;
5985 	ascq->q_cur_cnt[tid]++;
5986 	if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
5987 		ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
5988 		ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
5989 			 tid, ascq->q_max_cnt[tid]);
5990 	}
5991 	REQPTIME(reqp) = REQTIMESTAMP();
5992 #endif /* ADVANSYS_STATS */
5993 	ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong)reqp);
5994 	return;
5995 }
5996 
5997 /*
5998  * Return first queued 'REQP' on the specified queue for
5999  * the specified target device. Clear the 'tidmask' bit for
6000  * the device if no more commands are left queued for it.
6001  *
6002  * 'REQPNEXT(reqp)' returns reqp's next pointer.
6003  */
6004 static REQP asc_dequeue(asc_queue_t *ascq, int tid)
6005 {
6006 	REQP reqp;
6007 
6008 	ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
6009 	ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
6010 	if ((reqp = ascq->q_first[tid]) != NULL) {
6011 		ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
6012 		ascq->q_first[tid] = REQPNEXT(reqp);
6013 		/* If the queue is empty, clear its bit and the last pointer. */
6014 		if (ascq->q_first[tid] == NULL) {
6015 			ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
6016 			ASC_ASSERT(ascq->q_last[tid] == reqp);
6017 			ascq->q_last[tid] = NULL;
6018 		}
6019 #ifdef ADVANSYS_STATS
6020 		/* Maintain request queue statistics. */
6021 		ascq->q_cur_cnt[tid]--;
6022 		ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
6023 		REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
6024 #endif /* ADVANSYS_STATS */
6025 	}
6026 	ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong)reqp);
6027 	return reqp;
6028 }
6029 
6030 /*
6031  * Return a pointer to a singly linked list of all the requests queued
6032  * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
6033  *
6034  * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
6035  * the last request returned in the singly linked list.
6036  *
6037  * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
6038  * then all queued requests are concatenated into one list and
6039  * returned.
6040  *
6041  * Note: If 'lastpp' is used to append a new list to the end of
6042  * an old list, only change the old list last pointer if '*lastpp'
6043  * (or the function return value) is not NULL, i.e. use a temporary
6044  * variable for 'lastpp' and check its value after the function return
6045  * before assigning it to the list last pointer.
6046  *
6047  * Unfortunately collecting queuing time statistics adds overhead to
6048  * the function that isn't inherent to the function's algorithm.
6049  */
6050 static REQP asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
6051 {
6052 	REQP firstp, lastp;
6053 	int i;
6054 
6055 	ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
6056 	ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
6057 
6058 	/*
6059 	 * If 'tid' is not ASC_TID_ALL, return requests only for
6060 	 * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
6061 	 * requests for all tids.
6062 	 */
6063 	if (tid != ASC_TID_ALL) {
6064 		/* Return all requests for the specified 'tid'. */
6065 		if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
6066 			/* List is empty; Set first and last return pointers to NULL. */
6067 			firstp = lastp = NULL;
6068 		} else {
6069 			firstp = ascq->q_first[tid];
6070 			lastp = ascq->q_last[tid];
6071 			ascq->q_first[tid] = ascq->q_last[tid] = NULL;
6072 			ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
6073 #ifdef ADVANSYS_STATS
6074 			{
6075 				REQP reqp;
6076 				ascq->q_cur_cnt[tid] = 0;
6077 				for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
6078 					REQTIMESTAT("asc_dequeue_list", ascq,
6079 						    reqp, tid);
6080 				}
6081 			}
6082 #endif /* ADVANSYS_STATS */
6083 		}
6084 	} else {
6085 		/* Return all requests for all tids. */
6086 		firstp = lastp = NULL;
6087 		for (i = 0; i <= ADV_MAX_TID; i++) {
6088 			if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
6089 				if (firstp == NULL) {
6090 					firstp = ascq->q_first[i];
6091 					lastp = ascq->q_last[i];
6092 				} else {
6093 					ASC_ASSERT(lastp != NULL);
6094 					lastp->host_scribble =
6095 					    (unsigned char *)ascq->q_first[i];
6096 					lastp = ascq->q_last[i];
6097 				}
6098 				ascq->q_first[i] = ascq->q_last[i] = NULL;
6099 				ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
6100 #ifdef ADVANSYS_STATS
6101 				ascq->q_cur_cnt[i] = 0;
6102 #endif /* ADVANSYS_STATS */
6103 			}
6104 		}
6105 #ifdef ADVANSYS_STATS
6106 		{
6107 			REQP reqp;
6108 			for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
6109 				REQTIMESTAT("asc_dequeue_list", ascq, reqp,
6110 					    reqp->device->id);
6111 			}
6112 		}
6113 #endif /* ADVANSYS_STATS */
6114 	}
6115 	if (lastpp) {
6116 		*lastpp = lastp;
6117 	}
6118 	ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong)firstp);
6119 	return firstp;
6120 }
6121 
6122 /*
6123  * Remove the specified 'REQP' from the specified queue for
6124  * the specified target device. Clear the 'tidmask' bit for the
6125  * device if no more commands are left queued for it.
6126  *
6127  * 'REQPNEXT(reqp)' returns reqp's the next pointer.
6128  *
6129  * Return ASC_TRUE if the command was found and removed,
6130  * otherwise return ASC_FALSE.
6131  */
6132 static int asc_rmqueue(asc_queue_t *ascq, REQP reqp)
6133 {
6134 	REQP currp, prevp;
6135 	int tid;
6136 	int ret = ASC_FALSE;
6137 
6138 	ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
6139 		 (ulong)ascq, (ulong)reqp);
6140 	ASC_ASSERT(reqp != NULL);
6141 
6142 	tid = REQPTID(reqp);
6143 	ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
6144 
6145 	/*
6146 	 * Handle the common case of 'reqp' being the first
6147 	 * entry on the queue.
6148 	 */
6149 	if (reqp == ascq->q_first[tid]) {
6150 		ret = ASC_TRUE;
6151 		ascq->q_first[tid] = REQPNEXT(reqp);
6152 		/* If the queue is now empty, clear its bit and the last pointer. */
6153 		if (ascq->q_first[tid] == NULL) {
6154 			ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
6155 			ASC_ASSERT(ascq->q_last[tid] == reqp);
6156 			ascq->q_last[tid] = NULL;
6157 		}
6158 	} else if (ascq->q_first[tid] != NULL) {
6159 		ASC_ASSERT(ascq->q_last[tid] != NULL);
6160 		/*
6161 		 * Because the case of 'reqp' being the first entry has been
6162 		 * handled above and it is known the queue is not empty, if
6163 		 * 'reqp' is found on the queue it is guaranteed the queue will
6164 		 * not become empty and that 'q_first[tid]' will not be changed.
6165 		 *
6166 		 * Set 'prevp' to the first entry, 'currp' to the second entry,
6167 		 * and search for 'reqp'.
6168 		 */
6169 		for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
6170 		     currp; prevp = currp, currp = REQPNEXT(currp)) {
6171 			if (currp == reqp) {
6172 				ret = ASC_TRUE;
6173 				prevp->host_scribble =
6174 				    (unsigned char *)REQPNEXT(currp);
6175 				reqp->host_scribble = NULL;
6176 				if (ascq->q_last[tid] == reqp) {
6177 					ascq->q_last[tid] = prevp;
6178 				}
6179 				break;
6180 			}
6181 		}
6182 	}
6183 #ifdef ADVANSYS_STATS
6184 	/* Maintain request queue statistics. */
6185 	if (ret == ASC_TRUE) {
6186 		ascq->q_cur_cnt[tid]--;
6187 		REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
6188 	}
6189 	ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
6190 #endif /* ADVANSYS_STATS */
6191 	ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong)reqp, ret);
6192 	return ret;
6193 }
6194 
6195 /*
6196  * Execute as many queued requests as possible for the specified queue.
6197  *
6198  * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd.
6199  */
6200 static void asc_execute_queue(asc_queue_t *ascq)
6201 {
6202 	ADV_SCSI_BIT_ID_TYPE scan_tidmask;
6203 	REQP reqp;
6204 	int i;
6205 
6206 	ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong)ascq);
6207 	/*
6208 	 * Execute queued commands for devices attached to
6209 	 * the current board in round-robin fashion.
6210 	 */
6211 	scan_tidmask = ascq->q_tidmask;
6212 	do {
6213 		for (i = 0; i <= ADV_MAX_TID; i++) {
6214 			if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
6215 				if ((reqp = asc_dequeue(ascq, i)) == NULL) {
6216 					scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
6217 				} else
6218 				    if (asc_execute_scsi_cmnd
6219 					((struct scsi_cmnd *)reqp)
6220 					== ASC_BUSY) {
6221 					scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
6222 					/*
6223 					 * The request returned ASC_BUSY. Enqueue at the front of
6224 					 * target's waiting list to maintain correct ordering.
6225 					 */
6226 					asc_enqueue(ascq, reqp, ASC_FRONT);
6227 				}
6228 			}
6229 		}
6230 	} while (scan_tidmask);
6231 	return;
6232 }
6233 
6234 #ifdef CONFIG_PROC_FS
6235 /*
6236  * asc_prt_board_devices()
6237  *
6238  * Print driver information for devices attached to the board.
6239  *
6240  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6241  * cf. asc_prt_line().
6242  *
6243  * Return the number of characters copied into 'cp'. No more than
6244  * 'cplen' characters will be copied to 'cp'.
6245  */
6246 static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
6247 {
6248 	asc_board_t *boardp;
6249 	int leftlen;
6250 	int totlen;
6251 	int len;
6252 	int chip_scsi_id;
6253 	int i;
6254 
6255 	boardp = ASC_BOARDP(shost);
6256 	leftlen = cplen;
6257 	totlen = len = 0;
6258 
6259 	len = asc_prt_line(cp, leftlen,
6260 			   "\nDevice Information for AdvanSys SCSI Host %d:\n",
6261 			   shost->host_no);
6262 	ASC_PRT_NEXT();
6263 
6264 	if (ASC_NARROW_BOARD(boardp)) {
6265 		chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6266 	} else {
6267 		chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6268 	}
6269 
6270 	len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
6271 	ASC_PRT_NEXT();
6272 	for (i = 0; i <= ADV_MAX_TID; i++) {
6273 		if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
6274 			len = asc_prt_line(cp, leftlen, " %X,", i);
6275 			ASC_PRT_NEXT();
6276 		}
6277 	}
6278 	len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
6279 	ASC_PRT_NEXT();
6280 
6281 	return totlen;
6282 }
6283 
6284 /*
6285  * Display Wide Board BIOS Information.
6286  */
6287 static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
6288 {
6289 	asc_board_t *boardp;
6290 	int leftlen;
6291 	int totlen;
6292 	int len;
6293 	ushort major, minor, letter;
6294 
6295 	boardp = ASC_BOARDP(shost);
6296 	leftlen = cplen;
6297 	totlen = len = 0;
6298 
6299 	len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
6300 	ASC_PRT_NEXT();
6301 
6302 	/*
6303 	 * If the BIOS saved a valid signature, then fill in
6304 	 * the BIOS code segment base address.
6305 	 */
6306 	if (boardp->bios_signature != 0x55AA) {
6307 		len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
6308 		ASC_PRT_NEXT();
6309 		len = asc_prt_line(cp, leftlen,
6310 				   "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
6311 		ASC_PRT_NEXT();
6312 		len = asc_prt_line(cp, leftlen,
6313 				   "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
6314 		ASC_PRT_NEXT();
6315 	} else {
6316 		major = (boardp->bios_version >> 12) & 0xF;
6317 		minor = (boardp->bios_version >> 8) & 0xF;
6318 		letter = (boardp->bios_version & 0xFF);
6319 
6320 		len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
6321 				   major, minor,
6322 				   letter >= 26 ? '?' : letter + 'A');
6323 		ASC_PRT_NEXT();
6324 
6325 		/*
6326 		 * Current available ROM BIOS release is 3.1I for UW
6327 		 * and 3.2I for U2W. This code doesn't differentiate
6328 		 * UW and U2W boards.
6329 		 */
6330 		if (major < 3 || (major <= 3 && minor < 1) ||
6331 		    (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
6332 			len = asc_prt_line(cp, leftlen,
6333 					   "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
6334 			ASC_PRT_NEXT();
6335 			len = asc_prt_line(cp, leftlen,
6336 					   "ftp://ftp.connectcom.net/pub\n");
6337 			ASC_PRT_NEXT();
6338 		}
6339 	}
6340 
6341 	return totlen;
6342 }
6343 
6344 /*
6345  * Add serial number to information bar if signature AAh
6346  * is found in at bit 15-9 (7 bits) of word 1.
6347  *
6348  * Serial Number consists fo 12 alpha-numeric digits.
6349  *
6350  *       1 - Product type (A,B,C,D..)  Word0: 15-13 (3 bits)
6351  *       2 - MFG Location (A,B,C,D..)  Word0: 12-10 (3 bits)
6352  *     3-4 - Product ID (0-99)         Word0: 9-0 (10 bits)
6353  *       5 - Product revision (A-J)    Word0:  "         "
6354  *
6355  *           Signature                 Word1: 15-9 (7 bits)
6356  *       6 - Year (0-9)                Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
6357  *     7-8 - Week of the year (1-52)   Word1: 5-0 (6 bits)
6358  *
6359  *    9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
6360  *
6361  * Note 1: Only production cards will have a serial number.
6362  *
6363  * Note 2: Signature is most significant 7 bits (0xFE).
6364  *
6365  * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
6366  */
6367 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
6368 {
6369 	ushort w, num;
6370 
6371 	if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
6372 		return ASC_FALSE;
6373 	} else {
6374 		/*
6375 		 * First word - 6 digits.
6376 		 */
6377 		w = serialnum[0];
6378 
6379 		/* Product type - 1st digit. */
6380 		if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
6381 			/* Product type is P=Prototype */
6382 			*cp += 0x8;
6383 		}
6384 		cp++;
6385 
6386 		/* Manufacturing location - 2nd digit. */
6387 		*cp++ = 'A' + ((w & 0x1C00) >> 10);
6388 
6389 		/* Product ID - 3rd, 4th digits. */
6390 		num = w & 0x3FF;
6391 		*cp++ = '0' + (num / 100);
6392 		num %= 100;
6393 		*cp++ = '0' + (num / 10);
6394 
6395 		/* Product revision - 5th digit. */
6396 		*cp++ = 'A' + (num % 10);
6397 
6398 		/*
6399 		 * Second word
6400 		 */
6401 		w = serialnum[1];
6402 
6403 		/*
6404 		 * Year - 6th digit.
6405 		 *
6406 		 * If bit 15 of third word is set, then the
6407 		 * last digit of the year is greater than 7.
6408 		 */
6409 		if (serialnum[2] & 0x8000) {
6410 			*cp++ = '8' + ((w & 0x1C0) >> 6);
6411 		} else {
6412 			*cp++ = '0' + ((w & 0x1C0) >> 6);
6413 		}
6414 
6415 		/* Week of year - 7th, 8th digits. */
6416 		num = w & 0x003F;
6417 		*cp++ = '0' + num / 10;
6418 		num %= 10;
6419 		*cp++ = '0' + num;
6420 
6421 		/*
6422 		 * Third word
6423 		 */
6424 		w = serialnum[2] & 0x7FFF;
6425 
6426 		/* Serial number - 9th digit. */
6427 		*cp++ = 'A' + (w / 1000);
6428 
6429 		/* 10th, 11th, 12th digits. */
6430 		num = w % 1000;
6431 		*cp++ = '0' + num / 100;
6432 		num %= 100;
6433 		*cp++ = '0' + num / 10;
6434 		num %= 10;
6435 		*cp++ = '0' + num;
6436 
6437 		*cp = '\0';	/* Null Terminate the string. */
6438 		return ASC_TRUE;
6439 	}
6440 }
6441 
6442 /*
6443  * asc_prt_asc_board_eeprom()
6444  *
6445  * Print board EEPROM configuration.
6446  *
6447  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6448  * cf. asc_prt_line().
6449  *
6450  * Return the number of characters copied into 'cp'. No more than
6451  * 'cplen' characters will be copied to 'cp'.
6452  */
6453 static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
6454 {
6455 	asc_board_t *boardp;
6456 	ASC_DVC_VAR *asc_dvc_varp;
6457 	int leftlen;
6458 	int totlen;
6459 	int len;
6460 	ASCEEP_CONFIG *ep;
6461 	int i;
6462 #ifdef CONFIG_ISA
6463 	int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
6464 #endif /* CONFIG_ISA */
6465 	uchar serialstr[13];
6466 
6467 	boardp = ASC_BOARDP(shost);
6468 	asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6469 	ep = &boardp->eep_config.asc_eep;
6470 
6471 	leftlen = cplen;
6472 	totlen = len = 0;
6473 
6474 	len = asc_prt_line(cp, leftlen,
6475 			   "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6476 			   shost->host_no);
6477 	ASC_PRT_NEXT();
6478 
6479 	if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
6480 	    == ASC_TRUE) {
6481 		len =
6482 		    asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6483 				 serialstr);
6484 		ASC_PRT_NEXT();
6485 	} else {
6486 		if (ep->adapter_info[5] == 0xBB) {
6487 			len = asc_prt_line(cp, leftlen,
6488 					   " Default Settings Used for EEPROM-less Adapter.\n");
6489 			ASC_PRT_NEXT();
6490 		} else {
6491 			len = asc_prt_line(cp, leftlen,
6492 					   " Serial Number Signature Not Present.\n");
6493 			ASC_PRT_NEXT();
6494 		}
6495 	}
6496 
6497 	len = asc_prt_line(cp, leftlen,
6498 			   " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6499 			   ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
6500 			   ep->max_tag_qng);
6501 	ASC_PRT_NEXT();
6502 
6503 	len = asc_prt_line(cp, leftlen,
6504 			   " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
6505 	ASC_PRT_NEXT();
6506 
6507 	len = asc_prt_line(cp, leftlen, " Target ID:           ");
6508 	ASC_PRT_NEXT();
6509 	for (i = 0; i <= ASC_MAX_TID; i++) {
6510 		len = asc_prt_line(cp, leftlen, " %d", i);
6511 		ASC_PRT_NEXT();
6512 	}
6513 	len = asc_prt_line(cp, leftlen, "\n");
6514 	ASC_PRT_NEXT();
6515 
6516 	len = asc_prt_line(cp, leftlen, " Disconnects:         ");
6517 	ASC_PRT_NEXT();
6518 	for (i = 0; i <= ASC_MAX_TID; i++) {
6519 		len = asc_prt_line(cp, leftlen, " %c",
6520 				   (ep->
6521 				    disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6522 				   'N');
6523 		ASC_PRT_NEXT();
6524 	}
6525 	len = asc_prt_line(cp, leftlen, "\n");
6526 	ASC_PRT_NEXT();
6527 
6528 	len = asc_prt_line(cp, leftlen, " Command Queuing:     ");
6529 	ASC_PRT_NEXT();
6530 	for (i = 0; i <= ASC_MAX_TID; i++) {
6531 		len = asc_prt_line(cp, leftlen, " %c",
6532 				   (ep->
6533 				    use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6534 				   'N');
6535 		ASC_PRT_NEXT();
6536 	}
6537 	len = asc_prt_line(cp, leftlen, "\n");
6538 	ASC_PRT_NEXT();
6539 
6540 	len = asc_prt_line(cp, leftlen, " Start Motor:         ");
6541 	ASC_PRT_NEXT();
6542 	for (i = 0; i <= ASC_MAX_TID; i++) {
6543 		len = asc_prt_line(cp, leftlen, " %c",
6544 				   (ep->
6545 				    start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6546 				   'N');
6547 		ASC_PRT_NEXT();
6548 	}
6549 	len = asc_prt_line(cp, leftlen, "\n");
6550 	ASC_PRT_NEXT();
6551 
6552 	len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6553 	ASC_PRT_NEXT();
6554 	for (i = 0; i <= ASC_MAX_TID; i++) {
6555 		len = asc_prt_line(cp, leftlen, " %c",
6556 				   (ep->
6557 				    init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6558 				   'N');
6559 		ASC_PRT_NEXT();
6560 	}
6561 	len = asc_prt_line(cp, leftlen, "\n");
6562 	ASC_PRT_NEXT();
6563 
6564 #ifdef CONFIG_ISA
6565 	if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
6566 		len = asc_prt_line(cp, leftlen,
6567 				   " Host ISA DMA speed:   %d MB/S\n",
6568 				   isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
6569 		ASC_PRT_NEXT();
6570 	}
6571 #endif /* CONFIG_ISA */
6572 
6573 	return totlen;
6574 }
6575 
6576 /*
6577  * asc_prt_adv_board_eeprom()
6578  *
6579  * Print board EEPROM configuration.
6580  *
6581  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6582  * cf. asc_prt_line().
6583  *
6584  * Return the number of characters copied into 'cp'. No more than
6585  * 'cplen' characters will be copied to 'cp'.
6586  */
6587 static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
6588 {
6589 	asc_board_t *boardp;
6590 	ADV_DVC_VAR *adv_dvc_varp;
6591 	int leftlen;
6592 	int totlen;
6593 	int len;
6594 	int i;
6595 	char *termstr;
6596 	uchar serialstr[13];
6597 	ADVEEP_3550_CONFIG *ep_3550 = NULL;
6598 	ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
6599 	ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
6600 	ushort word;
6601 	ushort *wordp;
6602 	ushort sdtr_speed = 0;
6603 
6604 	boardp = ASC_BOARDP(shost);
6605 	adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6606 	if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6607 		ep_3550 = &boardp->eep_config.adv_3550_eep;
6608 	} else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6609 		ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
6610 	} else {
6611 		ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
6612 	}
6613 
6614 	leftlen = cplen;
6615 	totlen = len = 0;
6616 
6617 	len = asc_prt_line(cp, leftlen,
6618 			   "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6619 			   shost->host_no);
6620 	ASC_PRT_NEXT();
6621 
6622 	if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6623 		wordp = &ep_3550->serial_number_word1;
6624 	} else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6625 		wordp = &ep_38C0800->serial_number_word1;
6626 	} else {
6627 		wordp = &ep_38C1600->serial_number_word1;
6628 	}
6629 
6630 	if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
6631 		len =
6632 		    asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6633 				 serialstr);
6634 		ASC_PRT_NEXT();
6635 	} else {
6636 		len = asc_prt_line(cp, leftlen,
6637 				   " Serial Number Signature Not Present.\n");
6638 		ASC_PRT_NEXT();
6639 	}
6640 
6641 	if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6642 		len = asc_prt_line(cp, leftlen,
6643 				   " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6644 				   ep_3550->adapter_scsi_id,
6645 				   ep_3550->max_host_qng, ep_3550->max_dvc_qng);
6646 		ASC_PRT_NEXT();
6647 	} else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6648 		len = asc_prt_line(cp, leftlen,
6649 				   " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6650 				   ep_38C0800->adapter_scsi_id,
6651 				   ep_38C0800->max_host_qng,
6652 				   ep_38C0800->max_dvc_qng);
6653 		ASC_PRT_NEXT();
6654 	} else {
6655 		len = asc_prt_line(cp, leftlen,
6656 				   " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6657 				   ep_38C1600->adapter_scsi_id,
6658 				   ep_38C1600->max_host_qng,
6659 				   ep_38C1600->max_dvc_qng);
6660 		ASC_PRT_NEXT();
6661 	}
6662 	if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6663 		word = ep_3550->termination;
6664 	} else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6665 		word = ep_38C0800->termination_lvd;
6666 	} else {
6667 		word = ep_38C1600->termination_lvd;
6668 	}
6669 	switch (word) {
6670 	case 1:
6671 		termstr = "Low Off/High Off";
6672 		break;
6673 	case 2:
6674 		termstr = "Low Off/High On";
6675 		break;
6676 	case 3:
6677 		termstr = "Low On/High On";
6678 		break;
6679 	default:
6680 	case 0:
6681 		termstr = "Automatic";
6682 		break;
6683 	}
6684 
6685 	if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6686 		len = asc_prt_line(cp, leftlen,
6687 				   " termination: %u (%s), bios_ctrl: 0x%x\n",
6688 				   ep_3550->termination, termstr,
6689 				   ep_3550->bios_ctrl);
6690 		ASC_PRT_NEXT();
6691 	} else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6692 		len = asc_prt_line(cp, leftlen,
6693 				   " termination: %u (%s), bios_ctrl: 0x%x\n",
6694 				   ep_38C0800->termination_lvd, termstr,
6695 				   ep_38C0800->bios_ctrl);
6696 		ASC_PRT_NEXT();
6697 	} else {
6698 		len = asc_prt_line(cp, leftlen,
6699 				   " termination: %u (%s), bios_ctrl: 0x%x\n",
6700 				   ep_38C1600->termination_lvd, termstr,
6701 				   ep_38C1600->bios_ctrl);
6702 		ASC_PRT_NEXT();
6703 	}
6704 
6705 	len = asc_prt_line(cp, leftlen, " Target ID:           ");
6706 	ASC_PRT_NEXT();
6707 	for (i = 0; i <= ADV_MAX_TID; i++) {
6708 		len = asc_prt_line(cp, leftlen, " %X", i);
6709 		ASC_PRT_NEXT();
6710 	}
6711 	len = asc_prt_line(cp, leftlen, "\n");
6712 	ASC_PRT_NEXT();
6713 
6714 	if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6715 		word = ep_3550->disc_enable;
6716 	} else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6717 		word = ep_38C0800->disc_enable;
6718 	} else {
6719 		word = ep_38C1600->disc_enable;
6720 	}
6721 	len = asc_prt_line(cp, leftlen, " Disconnects:         ");
6722 	ASC_PRT_NEXT();
6723 	for (i = 0; i <= ADV_MAX_TID; i++) {
6724 		len = asc_prt_line(cp, leftlen, " %c",
6725 				   (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6726 		ASC_PRT_NEXT();
6727 	}
6728 	len = asc_prt_line(cp, leftlen, "\n");
6729 	ASC_PRT_NEXT();
6730 
6731 	if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6732 		word = ep_3550->tagqng_able;
6733 	} else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6734 		word = ep_38C0800->tagqng_able;
6735 	} else {
6736 		word = ep_38C1600->tagqng_able;
6737 	}
6738 	len = asc_prt_line(cp, leftlen, " Command Queuing:     ");
6739 	ASC_PRT_NEXT();
6740 	for (i = 0; i <= ADV_MAX_TID; i++) {
6741 		len = asc_prt_line(cp, leftlen, " %c",
6742 				   (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6743 		ASC_PRT_NEXT();
6744 	}
6745 	len = asc_prt_line(cp, leftlen, "\n");
6746 	ASC_PRT_NEXT();
6747 
6748 	if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6749 		word = ep_3550->start_motor;
6750 	} else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6751 		word = ep_38C0800->start_motor;
6752 	} else {
6753 		word = ep_38C1600->start_motor;
6754 	}
6755 	len = asc_prt_line(cp, leftlen, " Start Motor:         ");
6756 	ASC_PRT_NEXT();
6757 	for (i = 0; i <= ADV_MAX_TID; i++) {
6758 		len = asc_prt_line(cp, leftlen, " %c",
6759 				   (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6760 		ASC_PRT_NEXT();
6761 	}
6762 	len = asc_prt_line(cp, leftlen, "\n");
6763 	ASC_PRT_NEXT();
6764 
6765 	if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6766 		len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6767 		ASC_PRT_NEXT();
6768 		for (i = 0; i <= ADV_MAX_TID; i++) {
6769 			len = asc_prt_line(cp, leftlen, " %c",
6770 					   (ep_3550->
6771 					    sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
6772 					   'Y' : 'N');
6773 			ASC_PRT_NEXT();
6774 		}
6775 		len = asc_prt_line(cp, leftlen, "\n");
6776 		ASC_PRT_NEXT();
6777 	}
6778 
6779 	if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6780 		len = asc_prt_line(cp, leftlen, " Ultra Transfer:      ");
6781 		ASC_PRT_NEXT();
6782 		for (i = 0; i <= ADV_MAX_TID; i++) {
6783 			len = asc_prt_line(cp, leftlen, " %c",
6784 					   (ep_3550->
6785 					    ultra_able & ADV_TID_TO_TIDMASK(i))
6786 					   ? 'Y' : 'N');
6787 			ASC_PRT_NEXT();
6788 		}
6789 		len = asc_prt_line(cp, leftlen, "\n");
6790 		ASC_PRT_NEXT();
6791 	}
6792 
6793 	if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6794 		word = ep_3550->wdtr_able;
6795 	} else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6796 		word = ep_38C0800->wdtr_able;
6797 	} else {
6798 		word = ep_38C1600->wdtr_able;
6799 	}
6800 	len = asc_prt_line(cp, leftlen, " Wide Transfer:       ");
6801 	ASC_PRT_NEXT();
6802 	for (i = 0; i <= ADV_MAX_TID; i++) {
6803 		len = asc_prt_line(cp, leftlen, " %c",
6804 				   (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6805 		ASC_PRT_NEXT();
6806 	}
6807 	len = asc_prt_line(cp, leftlen, "\n");
6808 	ASC_PRT_NEXT();
6809 
6810 	if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
6811 	    adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
6812 		len = asc_prt_line(cp, leftlen,
6813 				   " Synchronous Transfer Speed (Mhz):\n  ");
6814 		ASC_PRT_NEXT();
6815 		for (i = 0; i <= ADV_MAX_TID; i++) {
6816 			char *speed_str;
6817 
6818 			if (i == 0) {
6819 				sdtr_speed = adv_dvc_varp->sdtr_speed1;
6820 			} else if (i == 4) {
6821 				sdtr_speed = adv_dvc_varp->sdtr_speed2;
6822 			} else if (i == 8) {
6823 				sdtr_speed = adv_dvc_varp->sdtr_speed3;
6824 			} else if (i == 12) {
6825 				sdtr_speed = adv_dvc_varp->sdtr_speed4;
6826 			}
6827 			switch (sdtr_speed & ADV_MAX_TID) {
6828 			case 0:
6829 				speed_str = "Off";
6830 				break;
6831 			case 1:
6832 				speed_str = "  5";
6833 				break;
6834 			case 2:
6835 				speed_str = " 10";
6836 				break;
6837 			case 3:
6838 				speed_str = " 20";
6839 				break;
6840 			case 4:
6841 				speed_str = " 40";
6842 				break;
6843 			case 5:
6844 				speed_str = " 80";
6845 				break;
6846 			default:
6847 				speed_str = "Unk";
6848 				break;
6849 			}
6850 			len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
6851 			ASC_PRT_NEXT();
6852 			if (i == 7) {
6853 				len = asc_prt_line(cp, leftlen, "\n  ");
6854 				ASC_PRT_NEXT();
6855 			}
6856 			sdtr_speed >>= 4;
6857 		}
6858 		len = asc_prt_line(cp, leftlen, "\n");
6859 		ASC_PRT_NEXT();
6860 	}
6861 
6862 	return totlen;
6863 }
6864 
6865 /*
6866  * asc_prt_driver_conf()
6867  *
6868  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6869  * cf. asc_prt_line().
6870  *
6871  * Return the number of characters copied into 'cp'. No more than
6872  * 'cplen' characters will be copied to 'cp'.
6873  */
6874 static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
6875 {
6876 	asc_board_t *boardp;
6877 	int leftlen;
6878 	int totlen;
6879 	int len;
6880 	int chip_scsi_id;
6881 
6882 	boardp = ASC_BOARDP(shost);
6883 
6884 	leftlen = cplen;
6885 	totlen = len = 0;
6886 
6887 	len = asc_prt_line(cp, leftlen,
6888 			   "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
6889 			   shost->host_no);
6890 	ASC_PRT_NEXT();
6891 
6892 	len = asc_prt_line(cp, leftlen,
6893 			   " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
6894 			   shost->host_busy, shost->last_reset, shost->max_id,
6895 			   shost->max_lun, shost->max_channel);
6896 	ASC_PRT_NEXT();
6897 
6898 	len = asc_prt_line(cp, leftlen,
6899 			   " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
6900 			   shost->unique_id, shost->can_queue, shost->this_id,
6901 			   shost->sg_tablesize, shost->cmd_per_lun);
6902 	ASC_PRT_NEXT();
6903 
6904 	len = asc_prt_line(cp, leftlen,
6905 			   " unchecked_isa_dma %d, use_clustering %d\n",
6906 			   shost->unchecked_isa_dma, shost->use_clustering);
6907 	ASC_PRT_NEXT();
6908 
6909 	len = asc_prt_line(cp, leftlen,
6910 			   " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
6911 			   boardp->flags, boardp->last_reset, jiffies,
6912 			   boardp->asc_n_io_port);
6913 	ASC_PRT_NEXT();
6914 
6915 	/* 'shost->n_io_port' may be truncated because it is only one byte. */
6916 	len = asc_prt_line(cp, leftlen,
6917 			   " io_port 0x%x, n_io_port 0x%x\n",
6918 			   shost->io_port, shost->n_io_port);
6919 	ASC_PRT_NEXT();
6920 
6921 	if (ASC_NARROW_BOARD(boardp)) {
6922 		chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6923 	} else {
6924 		chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6925 	}
6926 
6927 	return totlen;
6928 }
6929 
6930 /*
6931  * asc_prt_asc_board_info()
6932  *
6933  * Print dynamic board configuration information.
6934  *
6935  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6936  * cf. asc_prt_line().
6937  *
6938  * Return the number of characters copied into 'cp'. No more than
6939  * 'cplen' characters will be copied to 'cp'.
6940  */
6941 static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
6942 {
6943 	asc_board_t *boardp;
6944 	int chip_scsi_id;
6945 	int leftlen;
6946 	int totlen;
6947 	int len;
6948 	ASC_DVC_VAR *v;
6949 	ASC_DVC_CFG *c;
6950 	int i;
6951 	int renegotiate = 0;
6952 
6953 	boardp = ASC_BOARDP(shost);
6954 	v = &boardp->dvc_var.asc_dvc_var;
6955 	c = &boardp->dvc_cfg.asc_dvc_cfg;
6956 	chip_scsi_id = c->chip_scsi_id;
6957 
6958 	leftlen = cplen;
6959 	totlen = len = 0;
6960 
6961 	len = asc_prt_line(cp, leftlen,
6962 			   "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6963 			   shost->host_no);
6964 	ASC_PRT_NEXT();
6965 
6966 	len = asc_prt_line(cp, leftlen,
6967 			   " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
6968 			   c->chip_version, c->lib_version, c->lib_serial_no,
6969 			   c->mcode_date);
6970 	ASC_PRT_NEXT();
6971 
6972 	len = asc_prt_line(cp, leftlen,
6973 			   " mcode_version 0x%x, err_code %u\n",
6974 			   c->mcode_version, v->err_code);
6975 	ASC_PRT_NEXT();
6976 
6977 	/* Current number of commands waiting for the host. */
6978 	len = asc_prt_line(cp, leftlen,
6979 			   " Total Command Pending: %d\n", v->cur_total_qng);
6980 	ASC_PRT_NEXT();
6981 
6982 	len = asc_prt_line(cp, leftlen, " Command Queuing:");
6983 	ASC_PRT_NEXT();
6984 	for (i = 0; i <= ASC_MAX_TID; i++) {
6985 		if ((chip_scsi_id == i) ||
6986 		    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6987 			continue;
6988 		}
6989 		len = asc_prt_line(cp, leftlen, " %X:%c",
6990 				   i,
6991 				   (v->
6992 				    use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
6993 				   'Y' : 'N');
6994 		ASC_PRT_NEXT();
6995 	}
6996 	len = asc_prt_line(cp, leftlen, "\n");
6997 	ASC_PRT_NEXT();
6998 
6999 	/* Current number of commands waiting for a device. */
7000 	len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
7001 	ASC_PRT_NEXT();
7002 	for (i = 0; i <= ASC_MAX_TID; i++) {
7003 		if ((chip_scsi_id == i) ||
7004 		    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7005 			continue;
7006 		}
7007 		len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
7008 		ASC_PRT_NEXT();
7009 	}
7010 	len = asc_prt_line(cp, leftlen, "\n");
7011 	ASC_PRT_NEXT();
7012 
7013 	/* Current limit on number of commands that can be sent to a device. */
7014 	len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
7015 	ASC_PRT_NEXT();
7016 	for (i = 0; i <= ASC_MAX_TID; i++) {
7017 		if ((chip_scsi_id == i) ||
7018 		    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7019 			continue;
7020 		}
7021 		len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
7022 		ASC_PRT_NEXT();
7023 	}
7024 	len = asc_prt_line(cp, leftlen, "\n");
7025 	ASC_PRT_NEXT();
7026 
7027 	/* Indicate whether the device has returned queue full status. */
7028 	len = asc_prt_line(cp, leftlen, " Command Queue Full:");
7029 	ASC_PRT_NEXT();
7030 	for (i = 0; i <= ASC_MAX_TID; i++) {
7031 		if ((chip_scsi_id == i) ||
7032 		    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7033 			continue;
7034 		}
7035 		if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
7036 			len = asc_prt_line(cp, leftlen, " %X:Y-%d",
7037 					   i, boardp->queue_full_cnt[i]);
7038 		} else {
7039 			len = asc_prt_line(cp, leftlen, " %X:N", i);
7040 		}
7041 		ASC_PRT_NEXT();
7042 	}
7043 	len = asc_prt_line(cp, leftlen, "\n");
7044 	ASC_PRT_NEXT();
7045 
7046 	len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
7047 	ASC_PRT_NEXT();
7048 	for (i = 0; i <= ASC_MAX_TID; i++) {
7049 		if ((chip_scsi_id == i) ||
7050 		    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7051 			continue;
7052 		}
7053 		len = asc_prt_line(cp, leftlen, " %X:%c",
7054 				   i,
7055 				   (v->
7056 				    sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7057 				   'N');
7058 		ASC_PRT_NEXT();
7059 	}
7060 	len = asc_prt_line(cp, leftlen, "\n");
7061 	ASC_PRT_NEXT();
7062 
7063 	for (i = 0; i <= ASC_MAX_TID; i++) {
7064 		uchar syn_period_ix;
7065 
7066 		if ((chip_scsi_id == i) ||
7067 		    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
7068 		    ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
7069 			continue;
7070 		}
7071 
7072 		len = asc_prt_line(cp, leftlen, "  %X:", i);
7073 		ASC_PRT_NEXT();
7074 
7075 		if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
7076 			len = asc_prt_line(cp, leftlen, " Asynchronous");
7077 			ASC_PRT_NEXT();
7078 		} else {
7079 			syn_period_ix =
7080 			    (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
7081 							   1);
7082 
7083 			len = asc_prt_line(cp, leftlen,
7084 					   " Transfer Period Factor: %d (%d.%d Mhz),",
7085 					   v->sdtr_period_tbl[syn_period_ix],
7086 					   250 /
7087 					   v->sdtr_period_tbl[syn_period_ix],
7088 					   ASC_TENTHS(250,
7089 						      v->
7090 						      sdtr_period_tbl
7091 						      [syn_period_ix]));
7092 			ASC_PRT_NEXT();
7093 
7094 			len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
7095 					   boardp->
7096 					   sdtr_data[i] & ASC_SYN_MAX_OFFSET);
7097 			ASC_PRT_NEXT();
7098 		}
7099 
7100 		if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7101 			len = asc_prt_line(cp, leftlen, "*\n");
7102 			renegotiate = 1;
7103 		} else {
7104 			len = asc_prt_line(cp, leftlen, "\n");
7105 		}
7106 		ASC_PRT_NEXT();
7107 	}
7108 
7109 	if (renegotiate) {
7110 		len = asc_prt_line(cp, leftlen,
7111 				   " * = Re-negotiation pending before next command.\n");
7112 		ASC_PRT_NEXT();
7113 	}
7114 
7115 	return totlen;
7116 }
7117 
7118 /*
7119  * asc_prt_adv_board_info()
7120  *
7121  * Print dynamic board configuration information.
7122  *
7123  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7124  * cf. asc_prt_line().
7125  *
7126  * Return the number of characters copied into 'cp'. No more than
7127  * 'cplen' characters will be copied to 'cp'.
7128  */
7129 static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
7130 {
7131 	asc_board_t *boardp;
7132 	int leftlen;
7133 	int totlen;
7134 	int len;
7135 	int i;
7136 	ADV_DVC_VAR *v;
7137 	ADV_DVC_CFG *c;
7138 	AdvPortAddr iop_base;
7139 	ushort chip_scsi_id;
7140 	ushort lramword;
7141 	uchar lrambyte;
7142 	ushort tagqng_able;
7143 	ushort sdtr_able, wdtr_able;
7144 	ushort wdtr_done, sdtr_done;
7145 	ushort period = 0;
7146 	int renegotiate = 0;
7147 
7148 	boardp = ASC_BOARDP(shost);
7149 	v = &boardp->dvc_var.adv_dvc_var;
7150 	c = &boardp->dvc_cfg.adv_dvc_cfg;
7151 	iop_base = v->iop_base;
7152 	chip_scsi_id = v->chip_scsi_id;
7153 
7154 	leftlen = cplen;
7155 	totlen = len = 0;
7156 
7157 	len = asc_prt_line(cp, leftlen,
7158 			   "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
7159 			   shost->host_no);
7160 	ASC_PRT_NEXT();
7161 
7162 	len = asc_prt_line(cp, leftlen,
7163 			   " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
7164 			   v->iop_base,
7165 			   AdvReadWordRegister(iop_base,
7166 					       IOPW_SCSI_CFG1) & CABLE_DETECT,
7167 			   v->err_code);
7168 	ASC_PRT_NEXT();
7169 
7170 	len = asc_prt_line(cp, leftlen,
7171 			   " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
7172 			   c->chip_version, c->lib_version, c->mcode_date,
7173 			   c->mcode_version);
7174 	ASC_PRT_NEXT();
7175 
7176 	AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
7177 	len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
7178 	ASC_PRT_NEXT();
7179 	for (i = 0; i <= ADV_MAX_TID; i++) {
7180 		if ((chip_scsi_id == i) ||
7181 		    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7182 			continue;
7183 		}
7184 
7185 		len = asc_prt_line(cp, leftlen, " %X:%c",
7186 				   i,
7187 				   (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7188 				   'N');
7189 		ASC_PRT_NEXT();
7190 	}
7191 	len = asc_prt_line(cp, leftlen, "\n");
7192 	ASC_PRT_NEXT();
7193 
7194 	len = asc_prt_line(cp, leftlen, " Queue Limit:");
7195 	ASC_PRT_NEXT();
7196 	for (i = 0; i <= ADV_MAX_TID; i++) {
7197 		if ((chip_scsi_id == i) ||
7198 		    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7199 			continue;
7200 		}
7201 
7202 		AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
7203 				lrambyte);
7204 
7205 		len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
7206 		ASC_PRT_NEXT();
7207 	}
7208 	len = asc_prt_line(cp, leftlen, "\n");
7209 	ASC_PRT_NEXT();
7210 
7211 	len = asc_prt_line(cp, leftlen, " Command Pending:");
7212 	ASC_PRT_NEXT();
7213 	for (i = 0; i <= ADV_MAX_TID; i++) {
7214 		if ((chip_scsi_id == i) ||
7215 		    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7216 			continue;
7217 		}
7218 
7219 		AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
7220 				lrambyte);
7221 
7222 		len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
7223 		ASC_PRT_NEXT();
7224 	}
7225 	len = asc_prt_line(cp, leftlen, "\n");
7226 	ASC_PRT_NEXT();
7227 
7228 	AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7229 	len = asc_prt_line(cp, leftlen, " Wide Enabled:");
7230 	ASC_PRT_NEXT();
7231 	for (i = 0; i <= ADV_MAX_TID; i++) {
7232 		if ((chip_scsi_id == i) ||
7233 		    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7234 			continue;
7235 		}
7236 
7237 		len = asc_prt_line(cp, leftlen, " %X:%c",
7238 				   i,
7239 				   (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7240 				   'N');
7241 		ASC_PRT_NEXT();
7242 	}
7243 	len = asc_prt_line(cp, leftlen, "\n");
7244 	ASC_PRT_NEXT();
7245 
7246 	AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
7247 	len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
7248 	ASC_PRT_NEXT();
7249 	for (i = 0; i <= ADV_MAX_TID; i++) {
7250 		if ((chip_scsi_id == i) ||
7251 		    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7252 			continue;
7253 		}
7254 
7255 		AdvReadWordLram(iop_base,
7256 				ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7257 				lramword);
7258 
7259 		len = asc_prt_line(cp, leftlen, " %X:%d",
7260 				   i, (lramword & 0x8000) ? 16 : 8);
7261 		ASC_PRT_NEXT();
7262 
7263 		if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
7264 		    (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7265 			len = asc_prt_line(cp, leftlen, "*");
7266 			ASC_PRT_NEXT();
7267 			renegotiate = 1;
7268 		}
7269 	}
7270 	len = asc_prt_line(cp, leftlen, "\n");
7271 	ASC_PRT_NEXT();
7272 
7273 	AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7274 	len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
7275 	ASC_PRT_NEXT();
7276 	for (i = 0; i <= ADV_MAX_TID; i++) {
7277 		if ((chip_scsi_id == i) ||
7278 		    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7279 			continue;
7280 		}
7281 
7282 		len = asc_prt_line(cp, leftlen, " %X:%c",
7283 				   i,
7284 				   (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7285 				   'N');
7286 		ASC_PRT_NEXT();
7287 	}
7288 	len = asc_prt_line(cp, leftlen, "\n");
7289 	ASC_PRT_NEXT();
7290 
7291 	AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
7292 	for (i = 0; i <= ADV_MAX_TID; i++) {
7293 
7294 		AdvReadWordLram(iop_base,
7295 				ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7296 				lramword);
7297 		lramword &= ~0x8000;
7298 
7299 		if ((chip_scsi_id == i) ||
7300 		    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
7301 		    ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
7302 			continue;
7303 		}
7304 
7305 		len = asc_prt_line(cp, leftlen, "  %X:", i);
7306 		ASC_PRT_NEXT();
7307 
7308 		if ((lramword & 0x1F) == 0) {	/* Check for REQ/ACK Offset 0. */
7309 			len = asc_prt_line(cp, leftlen, " Asynchronous");
7310 			ASC_PRT_NEXT();
7311 		} else {
7312 			len =
7313 			    asc_prt_line(cp, leftlen,
7314 					 " Transfer Period Factor: ");
7315 			ASC_PRT_NEXT();
7316 
7317 			if ((lramword & 0x1F00) == 0x1100) {	/* 80 Mhz */
7318 				len =
7319 				    asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
7320 				ASC_PRT_NEXT();
7321 			} else if ((lramword & 0x1F00) == 0x1000) {	/* 40 Mhz */
7322 				len =
7323 				    asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
7324 				ASC_PRT_NEXT();
7325 			} else {	/* 20 Mhz or below. */
7326 
7327 				period = (((lramword >> 8) * 25) + 50) / 4;
7328 
7329 				if (period == 0) {	/* Should never happen. */
7330 					len =
7331 					    asc_prt_line(cp, leftlen,
7332 							 "%d (? Mhz), ");
7333 					ASC_PRT_NEXT();
7334 				} else {
7335 					len = asc_prt_line(cp, leftlen,
7336 							   "%d (%d.%d Mhz),",
7337 							   period, 250 / period,
7338 							   ASC_TENTHS(250,
7339 								      period));
7340 					ASC_PRT_NEXT();
7341 				}
7342 			}
7343 
7344 			len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
7345 					   lramword & 0x1F);
7346 			ASC_PRT_NEXT();
7347 		}
7348 
7349 		if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7350 			len = asc_prt_line(cp, leftlen, "*\n");
7351 			renegotiate = 1;
7352 		} else {
7353 			len = asc_prt_line(cp, leftlen, "\n");
7354 		}
7355 		ASC_PRT_NEXT();
7356 	}
7357 
7358 	if (renegotiate) {
7359 		len = asc_prt_line(cp, leftlen,
7360 				   " * = Re-negotiation pending before next command.\n");
7361 		ASC_PRT_NEXT();
7362 	}
7363 
7364 	return totlen;
7365 }
7366 
7367 /*
7368  * asc_proc_copy()
7369  *
7370  * Copy proc information to a read buffer taking into account the current
7371  * read offset in the file and the remaining space in the read buffer.
7372  */
7373 static int
7374 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
7375 	      char *cp, int cplen)
7376 {
7377 	int cnt = 0;
7378 
7379 	ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
7380 		 (unsigned)offset, (unsigned)advoffset, cplen);
7381 	if (offset <= advoffset) {
7382 		/* Read offset below current offset, copy everything. */
7383 		cnt = min(cplen, leftlen);
7384 		ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7385 			 (ulong)curbuf, (ulong)cp, cnt);
7386 		memcpy(curbuf, cp, cnt);
7387 	} else if (offset < advoffset + cplen) {
7388 		/* Read offset within current range, partial copy. */
7389 		cnt = (advoffset + cplen) - offset;
7390 		cp = (cp + cplen) - cnt;
7391 		cnt = min(cnt, leftlen);
7392 		ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7393 			 (ulong)curbuf, (ulong)cp, cnt);
7394 		memcpy(curbuf, cp, cnt);
7395 	}
7396 	return cnt;
7397 }
7398 
7399 /*
7400  * asc_prt_line()
7401  *
7402  * If 'cp' is NULL print to the console, otherwise print to a buffer.
7403  *
7404  * Return 0 if printing to the console, otherwise return the number of
7405  * bytes written to the buffer.
7406  *
7407  * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
7408  * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
7409  */
7410 static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
7411 {
7412 	va_list args;
7413 	int ret;
7414 	char s[ASC_PRTLINE_SIZE];
7415 
7416 	va_start(args, fmt);
7417 	ret = vsprintf(s, fmt, args);
7418 	ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
7419 	if (buf == NULL) {
7420 		(void)printk(s);
7421 		ret = 0;
7422 	} else {
7423 		ret = min(buflen, ret);
7424 		memcpy(buf, s, ret);
7425 	}
7426 	va_end(args);
7427 	return ret;
7428 }
7429 #endif /* CONFIG_PROC_FS */
7430 
7431 /*
7432  * --- Functions Required by the Asc Library
7433  */
7434 
7435 /*
7436  * Delay for 'n' milliseconds. Don't use the 'jiffies'
7437  * global variable which is incremented once every 5 ms
7438  * from a timer interrupt, because this function may be
7439  * called when interrupts are disabled.
7440  */
7441 static void DvcSleepMilliSecond(ADV_DCNT n)
7442 {
7443 	ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong)n);
7444 	mdelay(n);
7445 }
7446 
7447 /*
7448  * Currently and inline noop but leave as a placeholder.
7449  * Leave DvcEnterCritical() as a noop placeholder.
7450  */
7451 static inline ulong DvcEnterCritical(void)
7452 {
7453 	return 0;
7454 }
7455 
7456 /*
7457  * Critical sections are all protected by the board spinlock.
7458  * Leave DvcLeaveCritical() as a noop placeholder.
7459  */
7460 static inline void DvcLeaveCritical(ulong flags)
7461 {
7462 	return;
7463 }
7464 
7465 /*
7466  * void
7467  * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7468  *
7469  * Calling/Exit State:
7470  *    none
7471  *
7472  * Description:
7473  *     Output an ASC_SCSI_Q structure to the chip
7474  */
7475 static void
7476 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7477 {
7478 	int i;
7479 
7480 	ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
7481 	AscSetChipLramAddr(iop_base, s_addr);
7482 	for (i = 0; i < 2 * words; i += 2) {
7483 		if (i == 4 || i == 20) {
7484 			continue;
7485 		}
7486 		outpw(iop_base + IOP_RAM_DATA,
7487 		      ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
7488 	}
7489 }
7490 
7491 /*
7492  * void
7493  * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7494  *
7495  * Calling/Exit State:
7496  *    none
7497  *
7498  * Description:
7499  *     Input an ASC_QDONE_INFO structure from the chip
7500  */
7501 static void
7502 DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7503 {
7504 	int i;
7505 	ushort word;
7506 
7507 	AscSetChipLramAddr(iop_base, s_addr);
7508 	for (i = 0; i < 2 * words; i += 2) {
7509 		if (i == 10) {
7510 			continue;
7511 		}
7512 		word = inpw(iop_base + IOP_RAM_DATA);
7513 		inbuf[i] = word & 0xff;
7514 		inbuf[i + 1] = (word >> 8) & 0xff;
7515 	}
7516 	ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
7517 }
7518 
7519 /*
7520  * Read a PCI configuration byte.
7521  */
7522 static uchar __init DvcReadPCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset)
7523 {
7524 #ifdef CONFIG_PCI
7525 	uchar byte_data;
7526 	pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
7527 	return byte_data;
7528 #else /* !defined(CONFIG_PCI) */
7529 	return 0;
7530 #endif /* !defined(CONFIG_PCI) */
7531 }
7532 
7533 /*
7534  * Write a PCI configuration byte.
7535  */
7536 static void __init
7537 DvcWritePCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset, uchar byte_data)
7538 {
7539 #ifdef CONFIG_PCI
7540 	pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
7541 #endif /* CONFIG_PCI */
7542 }
7543 
7544 /*
7545  * Return the BIOS address of the adapter at the specified
7546  * I/O port and with the specified bus type.
7547  */
7548 static ushort __init AscGetChipBiosAddress(PortAddr iop_base, ushort bus_type)
7549 {
7550 	ushort cfg_lsw;
7551 	ushort bios_addr;
7552 
7553 	/*
7554 	 * The PCI BIOS is re-located by the motherboard BIOS. Because
7555 	 * of this the driver can not determine where a PCI BIOS is
7556 	 * loaded and executes.
7557 	 */
7558 	if (bus_type & ASC_IS_PCI) {
7559 		return (0);
7560 	}
7561 #ifdef CONFIG_ISA
7562 	if ((bus_type & ASC_IS_EISA) != 0) {
7563 		cfg_lsw = AscGetEisaChipCfg(iop_base);
7564 		cfg_lsw &= 0x000F;
7565 		bios_addr = (ushort)(ASC_BIOS_MIN_ADDR +
7566 				     (cfg_lsw * ASC_BIOS_BANK_SIZE));
7567 		return (bios_addr);
7568 	}			/* if */
7569 #endif /* CONFIG_ISA */
7570 
7571 	cfg_lsw = AscGetChipCfgLsw(iop_base);
7572 
7573 	/*
7574 	 *  ISA PnP uses the top bit as the 32K BIOS flag
7575 	 */
7576 	if (bus_type == ASC_IS_ISAPNP) {
7577 		cfg_lsw &= 0x7FFF;
7578 	}
7579 	/* if */
7580 	bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
7581 			     ASC_BIOS_MIN_ADDR);
7582 	return (bios_addr);
7583 }
7584 
7585 /*
7586  * --- Functions Required by the Adv Library
7587  */
7588 
7589 /*
7590  * DvcGetPhyAddr()
7591  *
7592  * Return the physical address of 'vaddr' and set '*lenp' to the
7593  * number of physically contiguous bytes that follow 'vaddr'.
7594  * 'flag' indicates the type of structure whose physical address
7595  * is being translated.
7596  *
7597  * Note: Because Linux currently doesn't page the kernel and all
7598  * kernel buffers are physically contiguous, leave '*lenp' unchanged.
7599  */
7600 ADV_PADDR
7601 DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
7602 	      uchar *vaddr, ADV_SDCNT *lenp, int flag)
7603 {
7604 	ADV_PADDR paddr;
7605 
7606 	paddr = virt_to_bus(vaddr);
7607 
7608 	ASC_DBG4(4,
7609 		 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
7610 		 (ulong)vaddr, (ulong)lenp, (ulong)*((ulong *)lenp),
7611 		 (ulong)paddr);
7612 
7613 	return paddr;
7614 }
7615 
7616 /*
7617  * Read a PCI configuration byte.
7618  */
7619 static uchar __init DvcAdvReadPCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset)
7620 {
7621 #ifdef CONFIG_PCI
7622 	uchar byte_data;
7623 	pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
7624 	return byte_data;
7625 #else /* CONFIG_PCI */
7626 	return 0;
7627 #endif /* CONFIG_PCI */
7628 }
7629 
7630 /*
7631  * Write a PCI configuration byte.
7632  */
7633 static void __init
7634 DvcAdvWritePCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset, uchar byte_data)
7635 {
7636 #ifdef CONFIG_PCI
7637 	pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
7638 #else /* CONFIG_PCI */
7639 	return;
7640 #endif /* CONFIG_PCI */
7641 }
7642 
7643 /*
7644  * --- Tracing and Debugging Functions
7645  */
7646 
7647 #ifdef ADVANSYS_STATS
7648 #ifdef CONFIG_PROC_FS
7649 /*
7650  * asc_prt_board_stats()
7651  *
7652  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7653  * cf. asc_prt_line().
7654  *
7655  * Return the number of characters copied into 'cp'. No more than
7656  * 'cplen' characters will be copied to 'cp'.
7657  */
7658 static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
7659 {
7660 	int leftlen;
7661 	int totlen;
7662 	int len;
7663 	struct asc_stats *s;
7664 	asc_board_t *boardp;
7665 
7666 	leftlen = cplen;
7667 	totlen = len = 0;
7668 
7669 	boardp = ASC_BOARDP(shost);
7670 	s = &boardp->asc_stats;
7671 
7672 	len = asc_prt_line(cp, leftlen,
7673 			   "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
7674 			   shost->host_no);
7675 	ASC_PRT_NEXT();
7676 
7677 	len = asc_prt_line(cp, leftlen,
7678 			   " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
7679 			   s->queuecommand, s->reset, s->biosparam,
7680 			   s->interrupt);
7681 	ASC_PRT_NEXT();
7682 
7683 	len = asc_prt_line(cp, leftlen,
7684 			   " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
7685 			   s->callback, s->done, s->build_error,
7686 			   s->adv_build_noreq, s->adv_build_nosg);
7687 	ASC_PRT_NEXT();
7688 
7689 	len = asc_prt_line(cp, leftlen,
7690 			   " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
7691 			   s->exe_noerror, s->exe_busy, s->exe_error,
7692 			   s->exe_unknown);
7693 	ASC_PRT_NEXT();
7694 
7695 	/*
7696 	 * Display data transfer statistics.
7697 	 */
7698 	if (s->cont_cnt > 0) {
7699 		len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
7700 		ASC_PRT_NEXT();
7701 
7702 		len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
7703 				   s->cont_xfer / 2,
7704 				   ASC_TENTHS(s->cont_xfer, 2));
7705 		ASC_PRT_NEXT();
7706 
7707 		/* Contiguous transfer average size */
7708 		len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
7709 				   (s->cont_xfer / 2) / s->cont_cnt,
7710 				   ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
7711 		ASC_PRT_NEXT();
7712 	}
7713 
7714 	if (s->sg_cnt > 0) {
7715 
7716 		len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
7717 				   s->sg_cnt, s->sg_elem);
7718 		ASC_PRT_NEXT();
7719 
7720 		len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
7721 				   s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
7722 		ASC_PRT_NEXT();
7723 
7724 		/* Scatter gather transfer statistics */
7725 		len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
7726 				   s->sg_elem / s->sg_cnt,
7727 				   ASC_TENTHS(s->sg_elem, s->sg_cnt));
7728 		ASC_PRT_NEXT();
7729 
7730 		len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
7731 				   (s->sg_xfer / 2) / s->sg_elem,
7732 				   ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
7733 		ASC_PRT_NEXT();
7734 
7735 		len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
7736 				   (s->sg_xfer / 2) / s->sg_cnt,
7737 				   ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
7738 		ASC_PRT_NEXT();
7739 	}
7740 
7741 	/*
7742 	 * Display request queuing statistics.
7743 	 */
7744 	len = asc_prt_line(cp, leftlen,
7745 			   " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
7746 			   HZ);
7747 	ASC_PRT_NEXT();
7748 
7749 	return totlen;
7750 }
7751 
7752 /*
7753  * asc_prt_target_stats()
7754  *
7755  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7756  * cf. asc_prt_line().
7757  *
7758  * This is separated from asc_prt_board_stats because a full set
7759  * of targets will overflow ASC_PRTBUF_SIZE.
7760  *
7761  * Return the number of characters copied into 'cp'. No more than
7762  * 'cplen' characters will be copied to 'cp'.
7763  */
7764 static int
7765 asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen)
7766 {
7767 	int leftlen;
7768 	int totlen;
7769 	int len;
7770 	struct asc_stats *s;
7771 	ushort chip_scsi_id;
7772 	asc_board_t *boardp;
7773 	asc_queue_t *active;
7774 	asc_queue_t *waiting;
7775 
7776 	leftlen = cplen;
7777 	totlen = len = 0;
7778 
7779 	boardp = ASC_BOARDP(shost);
7780 	s = &boardp->asc_stats;
7781 
7782 	active = &ASC_BOARDP(shost)->active;
7783 	waiting = &ASC_BOARDP(shost)->waiting;
7784 
7785 	if (ASC_NARROW_BOARD(boardp)) {
7786 		chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7787 	} else {
7788 		chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7789 	}
7790 
7791 	if ((chip_scsi_id == tgt_id) ||
7792 	    ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
7793 		return 0;
7794 	}
7795 
7796 	do {
7797 		if (active->q_tot_cnt[tgt_id] > 0
7798 		    || waiting->q_tot_cnt[tgt_id] > 0) {
7799 			len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
7800 			ASC_PRT_NEXT();
7801 
7802 			len = asc_prt_line(cp, leftlen,
7803 					   "   active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
7804 					   active->q_cur_cnt[tgt_id],
7805 					   active->q_max_cnt[tgt_id],
7806 					   active->q_tot_cnt[tgt_id],
7807 					   active->q_min_tim[tgt_id],
7808 					   active->q_max_tim[tgt_id],
7809 					   (active->q_tot_cnt[tgt_id] ==
7810 					    0) ? 0 : (active->
7811 						      q_tot_tim[tgt_id] /
7812 						      active->
7813 						      q_tot_cnt[tgt_id]),
7814 					   (active->q_tot_cnt[tgt_id] ==
7815 					    0) ? 0 : ASC_TENTHS(active->
7816 								q_tot_tim
7817 								[tgt_id],
7818 								active->
7819 								q_tot_cnt
7820 								[tgt_id]));
7821 			ASC_PRT_NEXT();
7822 
7823 			len = asc_prt_line(cp, leftlen,
7824 					   "   waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
7825 					   waiting->q_cur_cnt[tgt_id],
7826 					   waiting->q_max_cnt[tgt_id],
7827 					   waiting->q_tot_cnt[tgt_id],
7828 					   waiting->q_min_tim[tgt_id],
7829 					   waiting->q_max_tim[tgt_id],
7830 					   (waiting->q_tot_cnt[tgt_id] ==
7831 					    0) ? 0 : (waiting->
7832 						      q_tot_tim[tgt_id] /
7833 						      waiting->
7834 						      q_tot_cnt[tgt_id]),
7835 					   (waiting->q_tot_cnt[tgt_id] ==
7836 					    0) ? 0 : ASC_TENTHS(waiting->
7837 								q_tot_tim
7838 								[tgt_id],
7839 								waiting->
7840 								q_tot_cnt
7841 								[tgt_id]));
7842 			ASC_PRT_NEXT();
7843 		}
7844 	} while (0);
7845 
7846 	return totlen;
7847 }
7848 #endif /* CONFIG_PROC_FS */
7849 #endif /* ADVANSYS_STATS */
7850 
7851 #ifdef ADVANSYS_DEBUG
7852 /*
7853  * asc_prt_scsi_host()
7854  */
7855 static void asc_prt_scsi_host(struct Scsi_Host *s)
7856 {
7857 	asc_board_t *boardp;
7858 
7859 	boardp = ASC_BOARDP(s);
7860 
7861 	printk("Scsi_Host at addr 0x%lx\n", (ulong)s);
7862 	printk(" host_busy %u, host_no %d, last_reset %d,\n",
7863 	       s->host_busy, s->host_no, (unsigned)s->last_reset);
7864 
7865 	printk(" base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
7866 	       (ulong)s->base, (ulong)s->io_port, s->n_io_port, s->irq);
7867 
7868 	printk(" dma_channel %d, this_id %d, can_queue %d,\n",
7869 	       s->dma_channel, s->this_id, s->can_queue);
7870 
7871 	printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
7872 	       s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
7873 
7874 	if (ASC_NARROW_BOARD(boardp)) {
7875 		asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
7876 		asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
7877 	} else {
7878 		asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
7879 		asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
7880 	}
7881 }
7882 
7883 /*
7884  * asc_prt_scsi_cmnd()
7885  */
7886 static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
7887 {
7888 	printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s);
7889 
7890 	printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
7891 	       (ulong)s->device->host, (ulong)s->device, s->device->id,
7892 	       s->device->lun, s->device->channel);
7893 
7894 	asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
7895 
7896 	printk("sc_data_direction %u, resid %d\n",
7897 	       s->sc_data_direction, s->resid);
7898 
7899 	printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len);
7900 
7901 	printk(" serial_number 0x%x, retries %d, allowed %d\n",
7902 	       (unsigned)s->serial_number, s->retries, s->allowed);
7903 
7904 	printk(" timeout_per_command %d\n", s->timeout_per_command);
7905 
7906 	printk
7907 	    (" scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
7908 	     (ulong)s->scsi_done, (ulong)s->done, (ulong)s->host_scribble,
7909 	     s->result);
7910 
7911 	printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
7912 }
7913 
7914 /*
7915  * asc_prt_asc_dvc_var()
7916  */
7917 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
7918 {
7919 	printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
7920 
7921 	printk
7922 	    (" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n",
7923 	     h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
7924 
7925 	printk
7926 	    (" bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n",
7927 	     h->bus_type, (ulong)h->isr_callback, (ulong)h->exe_callback,
7928 	     (unsigned)h->init_sdtr);
7929 
7930 	printk
7931 	    (" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n",
7932 	     (unsigned)h->sdtr_done, (unsigned)h->use_tagged_qng,
7933 	     (unsigned)h->unit_not_ready, (unsigned)h->chip_no);
7934 
7935 	printk
7936 	    (" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n",
7937 	     (unsigned)h->queue_full_or_busy, (unsigned)h->start_motor,
7938 	     (unsigned)h->scsi_reset_wait);
7939 
7940 	printk
7941 	    (" is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n",
7942 	     (unsigned)h->is_in_int, (unsigned)h->max_total_qng,
7943 	     (unsigned)h->cur_total_qng, (unsigned)h->in_critical_cnt);
7944 
7945 	printk
7946 	    (" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n",
7947 	     (unsigned)h->last_q_shortage, (unsigned)h->init_state,
7948 	     (unsigned)h->no_scam, (unsigned)h->pci_fix_asyn_xfer);
7949 
7950 	printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no);
7951 }
7952 
7953 /*
7954  * asc_prt_asc_dvc_cfg()
7955  */
7956 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
7957 {
7958 	printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
7959 
7960 	printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
7961 	       h->can_tagged_qng, h->cmd_qng_enabled);
7962 	printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
7963 	       h->disc_enable, h->sdtr_enable);
7964 
7965 	printk
7966 	    (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
7967 	     h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
7968 	     h->chip_version);
7969 
7970 	printk
7971 	    (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
7972 	     to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
7973 	     h->mcode_date);
7974 
7975 	printk(" mcode_version %d, overrun_buf 0x%lx\n",
7976 	       h->mcode_version, (ulong)h->overrun_buf);
7977 }
7978 
7979 /*
7980  * asc_prt_asc_scsi_q()
7981  */
7982 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
7983 {
7984 	ASC_SG_HEAD *sgp;
7985 	int i;
7986 
7987 	printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
7988 
7989 	printk
7990 	    (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
7991 	     q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
7992 	     q->q2.tag_code);
7993 
7994 	printk
7995 	    (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7996 	     (ulong)le32_to_cpu(q->q1.data_addr),
7997 	     (ulong)le32_to_cpu(q->q1.data_cnt),
7998 	     (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
7999 
8000 	printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
8001 	       (ulong)q->cdbptr, q->q2.cdb_len,
8002 	       (ulong)q->sg_head, q->q1.sg_queue_cnt);
8003 
8004 	if (q->sg_head) {
8005 		sgp = q->sg_head;
8006 		printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
8007 		printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
8008 		       sgp->queue_cnt);
8009 		for (i = 0; i < sgp->entry_cnt; i++) {
8010 			printk(" [%u]: addr 0x%lx, bytes %lu\n",
8011 			       i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
8012 			       (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
8013 		}
8014 
8015 	}
8016 }
8017 
8018 /*
8019  * asc_prt_asc_qdone_info()
8020  */
8021 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
8022 {
8023 	printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
8024 	printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
8025 	       (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
8026 	       q->d2.tag_code);
8027 	printk
8028 	    (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
8029 	     q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
8030 }
8031 
8032 /*
8033  * asc_prt_adv_dvc_var()
8034  *
8035  * Display an ADV_DVC_VAR structure.
8036  */
8037 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
8038 {
8039 	printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
8040 
8041 	printk("  iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
8042 	       (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
8043 
8044 	printk("  isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
8045 	       (ulong)h->isr_callback, (unsigned)h->sdtr_able,
8046 	       (unsigned)h->wdtr_able);
8047 
8048 	printk("  start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
8049 	       (unsigned)h->start_motor,
8050 	       (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no);
8051 
8052 	printk("  max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
8053 	       (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
8054 	       (ulong)h->carr_freelist);
8055 
8056 	printk("  icq_sp 0x%lx, irq_sp 0x%lx\n",
8057 	       (ulong)h->icq_sp, (ulong)h->irq_sp);
8058 
8059 	printk("  no_scam 0x%x, tagqng_able 0x%x\n",
8060 	       (unsigned)h->no_scam, (unsigned)h->tagqng_able);
8061 
8062 	printk("  chip_scsi_id 0x%x, cfg 0x%lx\n",
8063 	       (unsigned)h->chip_scsi_id, (ulong)h->cfg);
8064 }
8065 
8066 /*
8067  * asc_prt_adv_dvc_cfg()
8068  *
8069  * Display an ADV_DVC_CFG structure.
8070  */
8071 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
8072 {
8073 	printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
8074 
8075 	printk("  disc_enable 0x%x, termination 0x%x\n",
8076 	       h->disc_enable, h->termination);
8077 
8078 	printk("  chip_version 0x%x, mcode_date 0x%x\n",
8079 	       h->chip_version, h->mcode_date);
8080 
8081 	printk("  mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
8082 	       h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
8083 
8084 	printk("  control_flag 0x%x, pci_slot_info 0x%x\n",
8085 	       h->control_flag, h->pci_slot_info);
8086 }
8087 
8088 /*
8089  * asc_prt_adv_scsi_req_q()
8090  *
8091  * Display an ADV_SCSI_REQ_Q structure.
8092  */
8093 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
8094 {
8095 	int sg_blk_cnt;
8096 	struct asc_sg_block *sg_ptr;
8097 
8098 	printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
8099 
8100 	printk("  target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
8101 	       q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
8102 
8103 	printk("  cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
8104 	       q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
8105 
8106 	printk("  data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
8107 	       (ulong)le32_to_cpu(q->data_cnt),
8108 	       (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
8109 
8110 	printk
8111 	    ("  cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
8112 	     q->cdb_len, q->done_status, q->host_status, q->scsi_status);
8113 
8114 	printk("  sg_working_ix 0x%x, target_cmd %u\n",
8115 	       q->sg_working_ix, q->target_cmd);
8116 
8117 	printk("  scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
8118 	       (ulong)le32_to_cpu(q->scsiq_rptr),
8119 	       (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
8120 
8121 	/* Display the request's ADV_SG_BLOCK structures. */
8122 	if (q->sg_list_ptr != NULL) {
8123 		sg_blk_cnt = 0;
8124 		while (1) {
8125 			/*
8126 			 * 'sg_ptr' is a physical address. Convert it to a virtual
8127 			 * address by indexing 'sg_blk_cnt' into the virtual address
8128 			 * array 'sg_list_ptr'.
8129 			 *
8130 			 * XXX - Assumes all SG physical blocks are virtually contiguous.
8131 			 */
8132 			sg_ptr =
8133 			    &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
8134 			asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
8135 			if (sg_ptr->sg_ptr == 0) {
8136 				break;
8137 			}
8138 			sg_blk_cnt++;
8139 		}
8140 	}
8141 }
8142 
8143 /*
8144  * asc_prt_adv_sgblock()
8145  *
8146  * Display an ADV_SG_BLOCK structure.
8147  */
8148 static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
8149 {
8150 	int i;
8151 
8152 	printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
8153 	       (ulong)b, sgblockno);
8154 	printk("  sg_cnt %u, sg_ptr 0x%lx\n",
8155 	       b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
8156 	ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
8157 	if (b->sg_ptr != 0) {
8158 		ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
8159 	}
8160 	for (i = 0; i < b->sg_cnt; i++) {
8161 		printk("  [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
8162 		       i, (ulong)b->sg_list[i].sg_addr,
8163 		       (ulong)b->sg_list[i].sg_count);
8164 	}
8165 }
8166 
8167 /*
8168  * asc_prt_hex()
8169  *
8170  * Print hexadecimal output in 4 byte groupings 32 bytes
8171  * or 8 double-words per line.
8172  */
8173 static void asc_prt_hex(char *f, uchar *s, int l)
8174 {
8175 	int i;
8176 	int j;
8177 	int k;
8178 	int m;
8179 
8180 	printk("%s: (%d bytes)\n", f, l);
8181 
8182 	for (i = 0; i < l; i += 32) {
8183 
8184 		/* Display a maximum of 8 double-words per line. */
8185 		if ((k = (l - i) / 4) >= 8) {
8186 			k = 8;
8187 			m = 0;
8188 		} else {
8189 			m = (l - i) % 4;
8190 		}
8191 
8192 		for (j = 0; j < k; j++) {
8193 			printk(" %2.2X%2.2X%2.2X%2.2X",
8194 			       (unsigned)s[i + (j * 4)],
8195 			       (unsigned)s[i + (j * 4) + 1],
8196 			       (unsigned)s[i + (j * 4) + 2],
8197 			       (unsigned)s[i + (j * 4) + 3]);
8198 		}
8199 
8200 		switch (m) {
8201 		case 0:
8202 		default:
8203 			break;
8204 		case 1:
8205 			printk(" %2.2X", (unsigned)s[i + (j * 4)]);
8206 			break;
8207 		case 2:
8208 			printk(" %2.2X%2.2X",
8209 			       (unsigned)s[i + (j * 4)],
8210 			       (unsigned)s[i + (j * 4) + 1]);
8211 			break;
8212 		case 3:
8213 			printk(" %2.2X%2.2X%2.2X",
8214 			       (unsigned)s[i + (j * 4) + 1],
8215 			       (unsigned)s[i + (j * 4) + 2],
8216 			       (unsigned)s[i + (j * 4) + 3]);
8217 			break;
8218 		}
8219 
8220 		printk("\n");
8221 	}
8222 }
8223 #endif /* ADVANSYS_DEBUG */
8224 
8225 /*
8226  * --- Asc Library Functions
8227  */
8228 
8229 static ushort __init AscGetEisaChipCfg(PortAddr iop_base)
8230 {
8231 	PortAddr eisa_cfg_iop;
8232 
8233 	eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8234 	    (PortAddr) (ASC_EISA_CFG_IOP_MASK);
8235 	return (inpw(eisa_cfg_iop));
8236 }
8237 
8238 static uchar __init AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
8239 {
8240 	ushort cfg_lsw;
8241 
8242 	if (AscGetChipScsiID(iop_base) == new_host_id) {
8243 		return (new_host_id);
8244 	}
8245 	cfg_lsw = AscGetChipCfgLsw(iop_base);
8246 	cfg_lsw &= 0xF8FF;
8247 	cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
8248 	AscSetChipCfgLsw(iop_base, cfg_lsw);
8249 	return (AscGetChipScsiID(iop_base));
8250 }
8251 
8252 static uchar __init AscGetChipScsiCtrl(PortAddr iop_base)
8253 {
8254 	uchar sc;
8255 
8256 	AscSetBank(iop_base, 1);
8257 	sc = inp(iop_base + IOP_REG_SC);
8258 	AscSetBank(iop_base, 0);
8259 	return (sc);
8260 }
8261 
8262 static uchar __init AscGetChipVersion(PortAddr iop_base, ushort bus_type)
8263 {
8264 	if ((bus_type & ASC_IS_EISA) != 0) {
8265 		PortAddr eisa_iop;
8266 		uchar revision;
8267 		eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8268 		    (PortAddr) ASC_EISA_REV_IOP_MASK;
8269 		revision = inp(eisa_iop);
8270 		return ((uchar)((ASC_CHIP_MIN_VER_EISA - 1) + revision));
8271 	}
8272 	return (AscGetChipVerNo(iop_base));
8273 }
8274 
8275 static ushort __init AscGetChipBusType(PortAddr iop_base)
8276 {
8277 	ushort chip_ver;
8278 
8279 	chip_ver = AscGetChipVerNo(iop_base);
8280 	if ((chip_ver >= ASC_CHIP_MIN_VER_VL)
8281 	    && (chip_ver <= ASC_CHIP_MAX_VER_VL)
8282 	    ) {
8283 		if (((iop_base & 0x0C30) == 0x0C30)
8284 		    || ((iop_base & 0x0C50) == 0x0C50)
8285 		    ) {
8286 			return (ASC_IS_EISA);
8287 		}
8288 		return (ASC_IS_VL);
8289 	}
8290 	if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
8291 	    (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
8292 		if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
8293 			return (ASC_IS_ISAPNP);
8294 		}
8295 		return (ASC_IS_ISA);
8296 	} else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
8297 		   (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
8298 		return (ASC_IS_PCI);
8299 	}
8300 	return (0);
8301 }
8302 
8303 static ASC_DCNT
8304 AscLoadMicroCode(PortAddr iop_base,
8305 		 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
8306 {
8307 	ASC_DCNT chksum;
8308 	ushort mcode_word_size;
8309 	ushort mcode_chksum;
8310 
8311 	/* Write the microcode buffer starting at LRAM address 0. */
8312 	mcode_word_size = (ushort)(mcode_size >> 1);
8313 	AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
8314 	AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
8315 
8316 	chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
8317 	ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum);
8318 	mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
8319 						 (ushort)ASC_CODE_SEC_BEG,
8320 						 (ushort)((mcode_size -
8321 							   s_addr - (ushort)
8322 							   ASC_CODE_SEC_BEG) /
8323 							  2));
8324 	ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
8325 		 (ulong)mcode_chksum);
8326 	AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
8327 	AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
8328 	return (chksum);
8329 }
8330 
8331 static int AscFindSignature(PortAddr iop_base)
8332 {
8333 	ushort sig_word;
8334 
8335 	ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
8336 		 iop_base, AscGetChipSignatureByte(iop_base));
8337 	if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
8338 		ASC_DBG2(1,
8339 			 "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
8340 			 iop_base, AscGetChipSignatureWord(iop_base));
8341 		sig_word = AscGetChipSignatureWord(iop_base);
8342 		if ((sig_word == (ushort)ASC_1000_ID0W) ||
8343 		    (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
8344 			return (1);
8345 		}
8346 	}
8347 	return (0);
8348 }
8349 
8350 static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __initdata = {
8351 	0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
8352 	ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
8353 };
8354 
8355 #ifdef CONFIG_ISA
8356 static uchar _isa_pnp_inited __initdata = 0;
8357 
8358 static PortAddr __init AscSearchIOPortAddr(PortAddr iop_beg, ushort bus_type)
8359 {
8360 	if (bus_type & ASC_IS_VL) {
8361 		while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
8362 			if (AscGetChipVersion(iop_beg, bus_type) <=
8363 			    ASC_CHIP_MAX_VER_VL) {
8364 				return (iop_beg);
8365 			}
8366 		}
8367 		return (0);
8368 	}
8369 	if (bus_type & ASC_IS_ISA) {
8370 		if (_isa_pnp_inited == 0) {
8371 			AscSetISAPNPWaitForKey();
8372 			_isa_pnp_inited++;
8373 		}
8374 		while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
8375 			if ((AscGetChipVersion(iop_beg, bus_type) &
8376 			     ASC_CHIP_VER_ISA_BIT) != 0) {
8377 				return (iop_beg);
8378 			}
8379 		}
8380 		return (0);
8381 	}
8382 	if (bus_type & ASC_IS_EISA) {
8383 		if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
8384 			return (iop_beg);
8385 		}
8386 		return (0);
8387 	}
8388 	return (0);
8389 }
8390 
8391 static PortAddr __init AscSearchIOPortAddr11(PortAddr s_addr)
8392 {
8393 	int i;
8394 	PortAddr iop_base;
8395 
8396 	for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
8397 		if (_asc_def_iop_base[i] > s_addr) {
8398 			break;
8399 		}
8400 	}
8401 	for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
8402 		iop_base = _asc_def_iop_base[i];
8403 		if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
8404 			ASC_DBG1(1,
8405 				 "AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n",
8406 				 iop_base);
8407 			continue;
8408 		}
8409 		ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n",
8410 			 iop_base);
8411 		release_region(iop_base, ASC_IOADR_GAP);
8412 		if (AscFindSignature(iop_base)) {
8413 			return (iop_base);
8414 		}
8415 	}
8416 	return (0);
8417 }
8418 
8419 static void __init AscSetISAPNPWaitForKey(void)
8420 {
8421 	outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
8422 	outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
8423 	return;
8424 }
8425 #endif /* CONFIG_ISA */
8426 
8427 static void __init AscToggleIRQAct(PortAddr iop_base)
8428 {
8429 	AscSetChipStatus(iop_base, CIW_IRQ_ACT);
8430 	AscSetChipStatus(iop_base, 0);
8431 	return;
8432 }
8433 
8434 static uchar __init AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
8435 {
8436 	ushort cfg_lsw;
8437 	uchar chip_irq;
8438 
8439 	if ((bus_type & ASC_IS_EISA) != 0) {
8440 		cfg_lsw = AscGetEisaChipCfg(iop_base);
8441 		chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10);
8442 		if ((chip_irq == 13) || (chip_irq > 15)) {
8443 			return (0);
8444 		}
8445 		return (chip_irq);
8446 	}
8447 	if ((bus_type & ASC_IS_VL) != 0) {
8448 		cfg_lsw = AscGetChipCfgLsw(iop_base);
8449 		chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07));
8450 		if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) {
8451 			return (0);
8452 		}
8453 		return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1)));
8454 	}
8455 	cfg_lsw = AscGetChipCfgLsw(iop_base);
8456 	chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03));
8457 	if (chip_irq == 3)
8458 		chip_irq += (uchar)2;
8459 	return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
8460 }
8461 
8462 static uchar __init
8463 AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
8464 {
8465 	ushort cfg_lsw;
8466 
8467 	if ((bus_type & ASC_IS_VL) != 0) {
8468 		if (irq_no != 0) {
8469 			if ((irq_no < ASC_MIN_IRQ_NO)
8470 			    || (irq_no > ASC_MAX_IRQ_NO)) {
8471 				irq_no = 0;
8472 			} else {
8473 				irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1));
8474 			}
8475 		}
8476 		cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3);
8477 		cfg_lsw |= (ushort)0x0010;
8478 		AscSetChipCfgLsw(iop_base, cfg_lsw);
8479 		AscToggleIRQAct(iop_base);
8480 		cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0);
8481 		cfg_lsw |= (ushort)((irq_no & 0x07) << 2);
8482 		AscSetChipCfgLsw(iop_base, cfg_lsw);
8483 		AscToggleIRQAct(iop_base);
8484 		return (AscGetChipIRQ(iop_base, bus_type));
8485 	}
8486 	if ((bus_type & (ASC_IS_ISA)) != 0) {
8487 		if (irq_no == 15)
8488 			irq_no -= (uchar)2;
8489 		irq_no -= (uchar)ASC_MIN_IRQ_NO;
8490 		cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3);
8491 		cfg_lsw |= (ushort)((irq_no & 0x03) << 2);
8492 		AscSetChipCfgLsw(iop_base, cfg_lsw);
8493 		return (AscGetChipIRQ(iop_base, bus_type));
8494 	}
8495 	return (0);
8496 }
8497 
8498 #ifdef CONFIG_ISA
8499 static void __init AscEnableIsaDma(uchar dma_channel)
8500 {
8501 	if (dma_channel < 4) {
8502 		outp(0x000B, (ushort)(0xC0 | dma_channel));
8503 		outp(0x000A, dma_channel);
8504 	} else if (dma_channel < 8) {
8505 		outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
8506 		outp(0x00D4, (ushort)(dma_channel - 4));
8507 	}
8508 	return;
8509 }
8510 #endif /* CONFIG_ISA */
8511 
8512 static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
8513 {
8514 	EXT_MSG ext_msg;
8515 	EXT_MSG out_msg;
8516 	ushort halt_q_addr;
8517 	int sdtr_accept;
8518 	ushort int_halt_code;
8519 	ASC_SCSI_BIT_ID_TYPE scsi_busy;
8520 	ASC_SCSI_BIT_ID_TYPE target_id;
8521 	PortAddr iop_base;
8522 	uchar tag_code;
8523 	uchar q_status;
8524 	uchar halt_qp;
8525 	uchar sdtr_data;
8526 	uchar target_ix;
8527 	uchar q_cntl, tid_no;
8528 	uchar cur_dvc_qng;
8529 	uchar asyn_sdtr;
8530 	uchar scsi_status;
8531 	asc_board_t *boardp;
8532 
8533 	ASC_ASSERT(asc_dvc->drv_ptr != NULL);
8534 	boardp = asc_dvc->drv_ptr;
8535 
8536 	iop_base = asc_dvc->iop_base;
8537 	int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
8538 
8539 	halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
8540 	halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
8541 	target_ix = AscReadLramByte(iop_base,
8542 				    (ushort)(halt_q_addr +
8543 					     (ushort)ASC_SCSIQ_B_TARGET_IX));
8544 	q_cntl =
8545 	    AscReadLramByte(iop_base,
8546 			    (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8547 	tid_no = ASC_TIX_TO_TID(target_ix);
8548 	target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
8549 	if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8550 		asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
8551 	} else {
8552 		asyn_sdtr = 0;
8553 	}
8554 	if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
8555 		if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8556 			AscSetChipSDTR(iop_base, 0, tid_no);
8557 			boardp->sdtr_data[tid_no] = 0;
8558 		}
8559 		AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8560 		return (0);
8561 	} else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
8562 		if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8563 			AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8564 			boardp->sdtr_data[tid_no] = asyn_sdtr;
8565 		}
8566 		AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8567 		return (0);
8568 	} else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
8569 
8570 		AscMemWordCopyPtrFromLram(iop_base,
8571 					  ASCV_MSGIN_BEG,
8572 					  (uchar *)&ext_msg,
8573 					  sizeof(EXT_MSG) >> 1);
8574 
8575 		if (ext_msg.msg_type == MS_EXTEND &&
8576 		    ext_msg.msg_req == MS_SDTR_CODE &&
8577 		    ext_msg.msg_len == MS_SDTR_LEN) {
8578 			sdtr_accept = TRUE;
8579 			if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
8580 
8581 				sdtr_accept = FALSE;
8582 				ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
8583 			}
8584 			if ((ext_msg.xfer_period <
8585 			     asc_dvc->sdtr_period_tbl[asc_dvc->
8586 						      host_init_sdtr_index])
8587 			    || (ext_msg.xfer_period >
8588 				asc_dvc->sdtr_period_tbl[asc_dvc->
8589 							 max_sdtr_index])) {
8590 				sdtr_accept = FALSE;
8591 				ext_msg.xfer_period =
8592 				    asc_dvc->sdtr_period_tbl[asc_dvc->
8593 							     host_init_sdtr_index];
8594 			}
8595 			if (sdtr_accept) {
8596 				sdtr_data =
8597 				    AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
8598 						   ext_msg.req_ack_offset);
8599 				if ((sdtr_data == 0xFF)) {
8600 
8601 					q_cntl |= QC_MSG_OUT;
8602 					asc_dvc->init_sdtr &= ~target_id;
8603 					asc_dvc->sdtr_done &= ~target_id;
8604 					AscSetChipSDTR(iop_base, asyn_sdtr,
8605 						       tid_no);
8606 					boardp->sdtr_data[tid_no] = asyn_sdtr;
8607 				}
8608 			}
8609 			if (ext_msg.req_ack_offset == 0) {
8610 
8611 				q_cntl &= ~QC_MSG_OUT;
8612 				asc_dvc->init_sdtr &= ~target_id;
8613 				asc_dvc->sdtr_done &= ~target_id;
8614 				AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8615 			} else {
8616 				if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
8617 
8618 					q_cntl &= ~QC_MSG_OUT;
8619 					asc_dvc->sdtr_done |= target_id;
8620 					asc_dvc->init_sdtr |= target_id;
8621 					asc_dvc->pci_fix_asyn_xfer &=
8622 					    ~target_id;
8623 					sdtr_data =
8624 					    AscCalSDTRData(asc_dvc,
8625 							   ext_msg.xfer_period,
8626 							   ext_msg.
8627 							   req_ack_offset);
8628 					AscSetChipSDTR(iop_base, sdtr_data,
8629 						       tid_no);
8630 					boardp->sdtr_data[tid_no] = sdtr_data;
8631 				} else {
8632 
8633 					q_cntl |= QC_MSG_OUT;
8634 					AscMsgOutSDTR(asc_dvc,
8635 						      ext_msg.xfer_period,
8636 						      ext_msg.req_ack_offset);
8637 					asc_dvc->pci_fix_asyn_xfer &=
8638 					    ~target_id;
8639 					sdtr_data =
8640 					    AscCalSDTRData(asc_dvc,
8641 							   ext_msg.xfer_period,
8642 							   ext_msg.
8643 							   req_ack_offset);
8644 					AscSetChipSDTR(iop_base, sdtr_data,
8645 						       tid_no);
8646 					boardp->sdtr_data[tid_no] = sdtr_data;
8647 					asc_dvc->sdtr_done |= target_id;
8648 					asc_dvc->init_sdtr |= target_id;
8649 				}
8650 			}
8651 
8652 			AscWriteLramByte(iop_base,
8653 					 (ushort)(halt_q_addr +
8654 						  (ushort)ASC_SCSIQ_B_CNTL),
8655 					 q_cntl);
8656 			AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8657 			return (0);
8658 		} else if (ext_msg.msg_type == MS_EXTEND &&
8659 			   ext_msg.msg_req == MS_WDTR_CODE &&
8660 			   ext_msg.msg_len == MS_WDTR_LEN) {
8661 
8662 			ext_msg.wdtr_width = 0;
8663 			AscMemWordCopyPtrToLram(iop_base,
8664 						ASCV_MSGOUT_BEG,
8665 						(uchar *)&ext_msg,
8666 						sizeof(EXT_MSG) >> 1);
8667 			q_cntl |= QC_MSG_OUT;
8668 			AscWriteLramByte(iop_base,
8669 					 (ushort)(halt_q_addr +
8670 						  (ushort)ASC_SCSIQ_B_CNTL),
8671 					 q_cntl);
8672 			AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8673 			return (0);
8674 		} else {
8675 
8676 			ext_msg.msg_type = MESSAGE_REJECT;
8677 			AscMemWordCopyPtrToLram(iop_base,
8678 						ASCV_MSGOUT_BEG,
8679 						(uchar *)&ext_msg,
8680 						sizeof(EXT_MSG) >> 1);
8681 			q_cntl |= QC_MSG_OUT;
8682 			AscWriteLramByte(iop_base,
8683 					 (ushort)(halt_q_addr +
8684 						  (ushort)ASC_SCSIQ_B_CNTL),
8685 					 q_cntl);
8686 			AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8687 			return (0);
8688 		}
8689 	} else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
8690 
8691 		q_cntl |= QC_REQ_SENSE;
8692 
8693 		if ((asc_dvc->init_sdtr & target_id) != 0) {
8694 
8695 			asc_dvc->sdtr_done &= ~target_id;
8696 
8697 			sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8698 			q_cntl |= QC_MSG_OUT;
8699 			AscMsgOutSDTR(asc_dvc,
8700 				      asc_dvc->
8701 				      sdtr_period_tbl[(sdtr_data >> 4) &
8702 						      (uchar)(asc_dvc->
8703 							      max_sdtr_index -
8704 							      1)],
8705 				      (uchar)(sdtr_data & (uchar)
8706 					      ASC_SYN_MAX_OFFSET));
8707 		}
8708 
8709 		AscWriteLramByte(iop_base,
8710 				 (ushort)(halt_q_addr +
8711 					  (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8712 
8713 		tag_code = AscReadLramByte(iop_base,
8714 					   (ushort)(halt_q_addr + (ushort)
8715 						    ASC_SCSIQ_B_TAG_CODE));
8716 		tag_code &= 0xDC;
8717 		if ((asc_dvc->pci_fix_asyn_xfer & target_id)
8718 		    && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
8719 		    ) {
8720 
8721 			tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
8722 				     | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
8723 
8724 		}
8725 		AscWriteLramByte(iop_base,
8726 				 (ushort)(halt_q_addr +
8727 					  (ushort)ASC_SCSIQ_B_TAG_CODE),
8728 				 tag_code);
8729 
8730 		q_status = AscReadLramByte(iop_base,
8731 					   (ushort)(halt_q_addr + (ushort)
8732 						    ASC_SCSIQ_B_STATUS));
8733 		q_status |= (QS_READY | QS_BUSY);
8734 		AscWriteLramByte(iop_base,
8735 				 (ushort)(halt_q_addr +
8736 					  (ushort)ASC_SCSIQ_B_STATUS),
8737 				 q_status);
8738 
8739 		scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
8740 		scsi_busy &= ~target_id;
8741 		AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8742 
8743 		AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8744 		return (0);
8745 	} else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
8746 
8747 		AscMemWordCopyPtrFromLram(iop_base,
8748 					  ASCV_MSGOUT_BEG,
8749 					  (uchar *)&out_msg,
8750 					  sizeof(EXT_MSG) >> 1);
8751 
8752 		if ((out_msg.msg_type == MS_EXTEND) &&
8753 		    (out_msg.msg_len == MS_SDTR_LEN) &&
8754 		    (out_msg.msg_req == MS_SDTR_CODE)) {
8755 
8756 			asc_dvc->init_sdtr &= ~target_id;
8757 			asc_dvc->sdtr_done &= ~target_id;
8758 			AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8759 			boardp->sdtr_data[tid_no] = asyn_sdtr;
8760 		}
8761 		q_cntl &= ~QC_MSG_OUT;
8762 		AscWriteLramByte(iop_base,
8763 				 (ushort)(halt_q_addr +
8764 					  (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8765 		AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8766 		return (0);
8767 	} else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
8768 
8769 		scsi_status = AscReadLramByte(iop_base,
8770 					      (ushort)((ushort)halt_q_addr +
8771 						       (ushort)
8772 						       ASC_SCSIQ_SCSI_STATUS));
8773 		cur_dvc_qng =
8774 		    AscReadLramByte(iop_base,
8775 				    (ushort)((ushort)ASC_QADR_BEG +
8776 					     (ushort)target_ix));
8777 		if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
8778 
8779 			scsi_busy = AscReadLramByte(iop_base,
8780 						    (ushort)ASCV_SCSIBUSY_B);
8781 			scsi_busy |= target_id;
8782 			AscWriteLramByte(iop_base,
8783 					 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8784 			asc_dvc->queue_full_or_busy |= target_id;
8785 
8786 			if (scsi_status == SAM_STAT_TASK_SET_FULL) {
8787 				if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
8788 					cur_dvc_qng -= 1;
8789 					asc_dvc->max_dvc_qng[tid_no] =
8790 					    cur_dvc_qng;
8791 
8792 					AscWriteLramByte(iop_base,
8793 							 (ushort)((ushort)
8794 								  ASCV_MAX_DVC_QNG_BEG
8795 								  + (ushort)
8796 								  tid_no),
8797 							 cur_dvc_qng);
8798 
8799 					/*
8800 					 * Set the device queue depth to the number of
8801 					 * active requests when the QUEUE FULL condition
8802 					 * was encountered.
8803 					 */
8804 					boardp->queue_full |= target_id;
8805 					boardp->queue_full_cnt[tid_no] =
8806 					    cur_dvc_qng;
8807 				}
8808 			}
8809 		}
8810 		AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8811 		return (0);
8812 	}
8813 #if CC_VERY_LONG_SG_LIST
8814 	else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
8815 		uchar q_no;
8816 		ushort q_addr;
8817 		uchar sg_wk_q_no;
8818 		uchar first_sg_wk_q_no;
8819 		ASC_SCSI_Q *scsiq;	/* Ptr to driver request. */
8820 		ASC_SG_HEAD *sg_head;	/* Ptr to driver SG request. */
8821 		ASC_SG_LIST_Q scsi_sg_q;	/* Structure written to queue. */
8822 		ushort sg_list_dwords;
8823 		ushort sg_entry_cnt;
8824 		uchar next_qp;
8825 		int i;
8826 
8827 		q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
8828 		if (q_no == ASC_QLINK_END) {
8829 			return (0);
8830 		}
8831 
8832 		q_addr = ASC_QNO_TO_QADDR(q_no);
8833 
8834 		/*
8835 		 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
8836 		 * structure pointer using a macro provided by the driver.
8837 		 * The ASC_SCSI_REQ pointer provides a pointer to the
8838 		 * host ASC_SG_HEAD structure.
8839 		 */
8840 		/* Read request's SRB pointer. */
8841 		scsiq = (ASC_SCSI_Q *)
8842 		    ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
8843 								    (ushort)
8844 								    (q_addr +
8845 								     ASC_SCSIQ_D_SRBPTR))));
8846 
8847 		/*
8848 		 * Get request's first and working SG queue.
8849 		 */
8850 		sg_wk_q_no = AscReadLramByte(iop_base,
8851 					     (ushort)(q_addr +
8852 						      ASC_SCSIQ_B_SG_WK_QP));
8853 
8854 		first_sg_wk_q_no = AscReadLramByte(iop_base,
8855 						   (ushort)(q_addr +
8856 							    ASC_SCSIQ_B_FIRST_SG_WK_QP));
8857 
8858 		/*
8859 		 * Reset request's working SG queue back to the
8860 		 * first SG queue.
8861 		 */
8862 		AscWriteLramByte(iop_base,
8863 				 (ushort)(q_addr +
8864 					  (ushort)ASC_SCSIQ_B_SG_WK_QP),
8865 				 first_sg_wk_q_no);
8866 
8867 		sg_head = scsiq->sg_head;
8868 
8869 		/*
8870 		 * Set sg_entry_cnt to the number of SG elements
8871 		 * that will be completed on this interrupt.
8872 		 *
8873 		 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
8874 		 * SG elements. The data_cnt and data_addr fields which
8875 		 * add 1 to the SG element capacity are not used when
8876 		 * restarting SG handling after a halt.
8877 		 */
8878 		if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
8879 			sg_entry_cnt = ASC_MAX_SG_LIST - 1;
8880 
8881 			/*
8882 			 * Keep track of remaining number of SG elements that will
8883 			 * need to be handled on the next interrupt.
8884 			 */
8885 			scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
8886 		} else {
8887 			sg_entry_cnt = scsiq->remain_sg_entry_cnt;
8888 			scsiq->remain_sg_entry_cnt = 0;
8889 		}
8890 
8891 		/*
8892 		 * Copy SG elements into the list of allocated SG queues.
8893 		 *
8894 		 * Last index completed is saved in scsiq->next_sg_index.
8895 		 */
8896 		next_qp = first_sg_wk_q_no;
8897 		q_addr = ASC_QNO_TO_QADDR(next_qp);
8898 		scsi_sg_q.sg_head_qp = q_no;
8899 		scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
8900 		for (i = 0; i < sg_head->queue_cnt; i++) {
8901 			scsi_sg_q.seq_no = i + 1;
8902 			if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
8903 				sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
8904 				sg_entry_cnt -= ASC_SG_LIST_PER_Q;
8905 				/*
8906 				 * After very first SG queue RISC FW uses next
8907 				 * SG queue first element then checks sg_list_cnt
8908 				 * against zero and then decrements, so set
8909 				 * sg_list_cnt 1 less than number of SG elements
8910 				 * in each SG queue.
8911 				 */
8912 				scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
8913 				scsi_sg_q.sg_cur_list_cnt =
8914 				    ASC_SG_LIST_PER_Q - 1;
8915 			} else {
8916 				/*
8917 				 * This is the last SG queue in the list of
8918 				 * allocated SG queues. If there are more
8919 				 * SG elements than will fit in the allocated
8920 				 * queues, then set the QCSG_SG_XFER_MORE flag.
8921 				 */
8922 				if (scsiq->remain_sg_entry_cnt != 0) {
8923 					scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
8924 				} else {
8925 					scsi_sg_q.cntl |= QCSG_SG_XFER_END;
8926 				}
8927 				/* equals sg_entry_cnt * 2 */
8928 				sg_list_dwords = sg_entry_cnt << 1;
8929 				scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
8930 				scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
8931 				sg_entry_cnt = 0;
8932 			}
8933 
8934 			scsi_sg_q.q_no = next_qp;
8935 			AscMemWordCopyPtrToLram(iop_base,
8936 						q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
8937 						(uchar *)&scsi_sg_q,
8938 						sizeof(ASC_SG_LIST_Q) >> 1);
8939 
8940 			AscMemDWordCopyPtrToLram(iop_base,
8941 						 q_addr + ASC_SGQ_LIST_BEG,
8942 						 (uchar *)&sg_head->
8943 						 sg_list[scsiq->next_sg_index],
8944 						 sg_list_dwords);
8945 
8946 			scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
8947 
8948 			/*
8949 			 * If the just completed SG queue contained the
8950 			 * last SG element, then no more SG queues need
8951 			 * to be written.
8952 			 */
8953 			if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
8954 				break;
8955 			}
8956 
8957 			next_qp = AscReadLramByte(iop_base,
8958 						  (ushort)(q_addr +
8959 							   ASC_SCSIQ_B_FWD));
8960 			q_addr = ASC_QNO_TO_QADDR(next_qp);
8961 		}
8962 
8963 		/*
8964 		 * Clear the halt condition so the RISC will be restarted
8965 		 * after the return.
8966 		 */
8967 		AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8968 		return (0);
8969 	}
8970 #endif /* CC_VERY_LONG_SG_LIST */
8971 	return (0);
8972 }
8973 
8974 static uchar
8975 _AscCopyLramScsiDoneQ(PortAddr iop_base,
8976 		      ushort q_addr,
8977 		      ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
8978 {
8979 	ushort _val;
8980 	uchar sg_queue_cnt;
8981 
8982 	DvcGetQinfo(iop_base,
8983 		    q_addr + ASC_SCSIQ_DONE_INFO_BEG,
8984 		    (uchar *)scsiq,
8985 		    (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
8986 
8987 	_val = AscReadLramWord(iop_base,
8988 			       (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
8989 	scsiq->q_status = (uchar)_val;
8990 	scsiq->q_no = (uchar)(_val >> 8);
8991 	_val = AscReadLramWord(iop_base,
8992 			       (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8993 	scsiq->cntl = (uchar)_val;
8994 	sg_queue_cnt = (uchar)(_val >> 8);
8995 	_val = AscReadLramWord(iop_base,
8996 			       (ushort)(q_addr +
8997 					(ushort)ASC_SCSIQ_B_SENSE_LEN));
8998 	scsiq->sense_len = (uchar)_val;
8999 	scsiq->extra_bytes = (uchar)(_val >> 8);
9000 
9001 	/*
9002 	 * Read high word of remain bytes from alternate location.
9003 	 */
9004 	scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
9005 							  (ushort)(q_addr +
9006 								   (ushort)
9007 								   ASC_SCSIQ_W_ALT_DC1)))
9008 			       << 16);
9009 	/*
9010 	 * Read low word of remain bytes from original location.
9011 	 */
9012 	scsiq->remain_bytes += AscReadLramWord(iop_base,
9013 					       (ushort)(q_addr + (ushort)
9014 							ASC_SCSIQ_DW_REMAIN_XFER_CNT));
9015 
9016 	scsiq->remain_bytes &= max_dma_count;
9017 	return (sg_queue_cnt);
9018 }
9019 
9020 static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
9021 {
9022 	uchar next_qp;
9023 	uchar n_q_used;
9024 	uchar sg_list_qp;
9025 	uchar sg_queue_cnt;
9026 	uchar q_cnt;
9027 	uchar done_q_tail;
9028 	uchar tid_no;
9029 	ASC_SCSI_BIT_ID_TYPE scsi_busy;
9030 	ASC_SCSI_BIT_ID_TYPE target_id;
9031 	PortAddr iop_base;
9032 	ushort q_addr;
9033 	ushort sg_q_addr;
9034 	uchar cur_target_qng;
9035 	ASC_QDONE_INFO scsiq_buf;
9036 	ASC_QDONE_INFO *scsiq;
9037 	int false_overrun;
9038 	ASC_ISR_CALLBACK asc_isr_callback;
9039 
9040 	iop_base = asc_dvc->iop_base;
9041 	asc_isr_callback = asc_dvc->isr_callback;
9042 	n_q_used = 1;
9043 	scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
9044 	done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
9045 	q_addr = ASC_QNO_TO_QADDR(done_q_tail);
9046 	next_qp = AscReadLramByte(iop_base,
9047 				  (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
9048 	if (next_qp != ASC_QLINK_END) {
9049 		AscPutVarDoneQTail(iop_base, next_qp);
9050 		q_addr = ASC_QNO_TO_QADDR(next_qp);
9051 		sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
9052 						     asc_dvc->max_dma_count);
9053 		AscWriteLramByte(iop_base,
9054 				 (ushort)(q_addr +
9055 					  (ushort)ASC_SCSIQ_B_STATUS),
9056 				 (uchar)(scsiq->
9057 					 q_status & (uchar)~(QS_READY |
9058 							     QS_ABORTED)));
9059 		tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
9060 		target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
9061 		if ((scsiq->cntl & QC_SG_HEAD) != 0) {
9062 			sg_q_addr = q_addr;
9063 			sg_list_qp = next_qp;
9064 			for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
9065 				sg_list_qp = AscReadLramByte(iop_base,
9066 							     (ushort)(sg_q_addr
9067 								      + (ushort)
9068 								      ASC_SCSIQ_B_FWD));
9069 				sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
9070 				if (sg_list_qp == ASC_QLINK_END) {
9071 					AscSetLibErrorCode(asc_dvc,
9072 							   ASCQ_ERR_SG_Q_LINKS);
9073 					scsiq->d3.done_stat = QD_WITH_ERROR;
9074 					scsiq->d3.host_stat =
9075 					    QHSTA_D_QDONE_SG_LIST_CORRUPTED;
9076 					goto FATAL_ERR_QDONE;
9077 				}
9078 				AscWriteLramByte(iop_base,
9079 						 (ushort)(sg_q_addr + (ushort)
9080 							  ASC_SCSIQ_B_STATUS),
9081 						 QS_FREE);
9082 			}
9083 			n_q_used = sg_queue_cnt + 1;
9084 			AscPutVarDoneQTail(iop_base, sg_list_qp);
9085 		}
9086 		if (asc_dvc->queue_full_or_busy & target_id) {
9087 			cur_target_qng = AscReadLramByte(iop_base,
9088 							 (ushort)((ushort)
9089 								  ASC_QADR_BEG
9090 								  + (ushort)
9091 								  scsiq->d2.
9092 								  target_ix));
9093 			if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
9094 				scsi_busy = AscReadLramByte(iop_base, (ushort)
9095 							    ASCV_SCSIBUSY_B);
9096 				scsi_busy &= ~target_id;
9097 				AscWriteLramByte(iop_base,
9098 						 (ushort)ASCV_SCSIBUSY_B,
9099 						 scsi_busy);
9100 				asc_dvc->queue_full_or_busy &= ~target_id;
9101 			}
9102 		}
9103 		if (asc_dvc->cur_total_qng >= n_q_used) {
9104 			asc_dvc->cur_total_qng -= n_q_used;
9105 			if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
9106 				asc_dvc->cur_dvc_qng[tid_no]--;
9107 			}
9108 		} else {
9109 			AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
9110 			scsiq->d3.done_stat = QD_WITH_ERROR;
9111 			goto FATAL_ERR_QDONE;
9112 		}
9113 		if ((scsiq->d2.srb_ptr == 0UL) ||
9114 		    ((scsiq->q_status & QS_ABORTED) != 0)) {
9115 			return (0x11);
9116 		} else if (scsiq->q_status == QS_DONE) {
9117 			false_overrun = FALSE;
9118 			if (scsiq->extra_bytes != 0) {
9119 				scsiq->remain_bytes +=
9120 				    (ADV_DCNT)scsiq->extra_bytes;
9121 			}
9122 			if (scsiq->d3.done_stat == QD_WITH_ERROR) {
9123 				if (scsiq->d3.host_stat ==
9124 				    QHSTA_M_DATA_OVER_RUN) {
9125 					if ((scsiq->
9126 					     cntl & (QC_DATA_IN | QC_DATA_OUT))
9127 					    == 0) {
9128 						scsiq->d3.done_stat =
9129 						    QD_NO_ERROR;
9130 						scsiq->d3.host_stat =
9131 						    QHSTA_NO_ERROR;
9132 					} else if (false_overrun) {
9133 						scsiq->d3.done_stat =
9134 						    QD_NO_ERROR;
9135 						scsiq->d3.host_stat =
9136 						    QHSTA_NO_ERROR;
9137 					}
9138 				} else if (scsiq->d3.host_stat ==
9139 					   QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
9140 					AscStopChip(iop_base);
9141 					AscSetChipControl(iop_base,
9142 							  (uchar)(CC_SCSI_RESET
9143 								  | CC_HALT));
9144 					DvcDelayNanoSecond(asc_dvc, 60000);
9145 					AscSetChipControl(iop_base, CC_HALT);
9146 					AscSetChipStatus(iop_base,
9147 							 CIW_CLR_SCSI_RESET_INT);
9148 					AscSetChipStatus(iop_base, 0);
9149 					AscSetChipControl(iop_base, 0);
9150 				}
9151 			}
9152 			if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9153 				(*asc_isr_callback) (asc_dvc, scsiq);
9154 			} else {
9155 				if ((AscReadLramByte(iop_base,
9156 						     (ushort)(q_addr + (ushort)
9157 							      ASC_SCSIQ_CDB_BEG))
9158 				     == START_STOP)) {
9159 					asc_dvc->unit_not_ready &= ~target_id;
9160 					if (scsiq->d3.done_stat != QD_NO_ERROR) {
9161 						asc_dvc->start_motor &=
9162 						    ~target_id;
9163 					}
9164 				}
9165 			}
9166 			return (1);
9167 		} else {
9168 			AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
9169  FATAL_ERR_QDONE:
9170 			if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9171 				(*asc_isr_callback) (asc_dvc, scsiq);
9172 			}
9173 			return (0x80);
9174 		}
9175 	}
9176 	return (0);
9177 }
9178 
9179 static int AscISR(ASC_DVC_VAR *asc_dvc)
9180 {
9181 	ASC_CS_TYPE chipstat;
9182 	PortAddr iop_base;
9183 	ushort saved_ram_addr;
9184 	uchar ctrl_reg;
9185 	uchar saved_ctrl_reg;
9186 	int int_pending;
9187 	int status;
9188 	uchar host_flag;
9189 
9190 	iop_base = asc_dvc->iop_base;
9191 	int_pending = FALSE;
9192 
9193 	if (AscIsIntPending(iop_base) == 0) {
9194 		return int_pending;
9195 	}
9196 
9197 	if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
9198 	    || (asc_dvc->isr_callback == 0)
9199 	    ) {
9200 		return (ERR);
9201 	}
9202 	if (asc_dvc->in_critical_cnt != 0) {
9203 		AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
9204 		return (ERR);
9205 	}
9206 	if (asc_dvc->is_in_int) {
9207 		AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
9208 		return (ERR);
9209 	}
9210 	asc_dvc->is_in_int = TRUE;
9211 	ctrl_reg = AscGetChipControl(iop_base);
9212 	saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
9213 				       CC_SINGLE_STEP | CC_DIAG | CC_TEST));
9214 	chipstat = AscGetChipStatus(iop_base);
9215 	if (chipstat & CSW_SCSI_RESET_LATCH) {
9216 		if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
9217 			int i = 10;
9218 			int_pending = TRUE;
9219 			asc_dvc->sdtr_done = 0;
9220 			saved_ctrl_reg &= (uchar)(~CC_HALT);
9221 			while ((AscGetChipStatus(iop_base) &
9222 				CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
9223 				DvcSleepMilliSecond(100);
9224 			}
9225 			AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
9226 			AscSetChipControl(iop_base, CC_HALT);
9227 			AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
9228 			AscSetChipStatus(iop_base, 0);
9229 			chipstat = AscGetChipStatus(iop_base);
9230 		}
9231 	}
9232 	saved_ram_addr = AscGetChipLramAddr(iop_base);
9233 	host_flag = AscReadLramByte(iop_base,
9234 				    ASCV_HOST_FLAG_B) &
9235 	    (uchar)(~ASC_HOST_FLAG_IN_ISR);
9236 	AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
9237 			 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
9238 	if ((chipstat & CSW_INT_PENDING)
9239 	    || (int_pending)
9240 	    ) {
9241 		AscAckInterrupt(iop_base);
9242 		int_pending = TRUE;
9243 		if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
9244 			if (AscIsrChipHalted(asc_dvc) == ERR) {
9245 				goto ISR_REPORT_QDONE_FATAL_ERROR;
9246 			} else {
9247 				saved_ctrl_reg &= (uchar)(~CC_HALT);
9248 			}
9249 		} else {
9250  ISR_REPORT_QDONE_FATAL_ERROR:
9251 			if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
9252 				while (((status =
9253 					 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
9254 				}
9255 			} else {
9256 				do {
9257 					if ((status =
9258 					     AscIsrQDone(asc_dvc)) == 1) {
9259 						break;
9260 					}
9261 				} while (status == 0x11);
9262 			}
9263 			if ((status & 0x80) != 0)
9264 				int_pending = ERR;
9265 		}
9266 	}
9267 	AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
9268 	AscSetChipLramAddr(iop_base, saved_ram_addr);
9269 	AscSetChipControl(iop_base, saved_ctrl_reg);
9270 	asc_dvc->is_in_int = FALSE;
9271 	return (int_pending);
9272 }
9273 
9274 /* Microcode buffer is kept after initialization for error recovery. */
9275 static uchar _asc_mcode_buf[] = {
9276 	0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9277 	0x00, 0x00, 0x00, 0x00,
9278 	0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00,
9279 	0x00, 0x00, 0x00, 0x00,
9280 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9281 	0x00, 0x00, 0x00, 0x00,
9282 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9283 	0x00, 0x00, 0x00, 0x00,
9284 	0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00,
9285 	0x00, 0xFF, 0x00, 0x00,
9286 	0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00,
9287 	0x00, 0x00, 0x00, 0x00,
9288 	0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
9289 	0x00, 0x00, 0x00, 0x00,
9290 	0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88,
9291 	0x00, 0x00, 0x00, 0x00,
9292 	0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73,
9293 	0x03, 0x23, 0x36, 0x40,
9294 	0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
9295 	0xC2, 0x00, 0x92, 0x80,
9296 	0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60,
9297 	0xB6, 0x00, 0x92, 0x80,
9298 	0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00,
9299 	0x92, 0x80, 0x80, 0x62,
9300 	0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
9301 	0xCD, 0x04, 0x4D, 0x00,
9302 	0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01,
9303 	0xE6, 0x84, 0xD2, 0xC1,
9304 	0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97,
9305 	0xC6, 0x81, 0xC2, 0x88,
9306 	0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
9307 	0x84, 0x97, 0x07, 0xA6,
9308 	0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE,
9309 	0xC2, 0x88, 0xCE, 0x00,
9310 	0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01,
9311 	0x80, 0x63, 0x07, 0xA6,
9312 	0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
9313 	0x34, 0x01, 0x00, 0x33,
9314 	0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23,
9315 	0x68, 0x98, 0x4D, 0x04,
9316 	0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23,
9317 	0xF8, 0x88, 0xFB, 0x23,
9318 	0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
9319 	0x00, 0x33, 0x0A, 0x00,
9320 	0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00,
9321 	0xC2, 0x88, 0xCD, 0x04,
9322 	0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81,
9323 	0x06, 0xAB, 0x82, 0x01,
9324 	0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
9325 	0x3C, 0x01, 0x00, 0x05,
9326 	0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01,
9327 	0x15, 0x23, 0xA1, 0x01,
9328 	0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00,
9329 	0x06, 0x61, 0x00, 0xA0,
9330 	0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
9331 	0xC2, 0x88, 0x06, 0x23,
9332 	0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01,
9333 	0x57, 0x60, 0x00, 0xA0,
9334 	0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73,
9335 	0x4B, 0x00, 0x06, 0x61,
9336 	0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
9337 	0x4F, 0x00, 0x84, 0x97,
9338 	0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97,
9339 	0x48, 0x04, 0x84, 0x80,
9340 	0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00,
9341 	0x81, 0x73, 0x06, 0x29,
9342 	0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
9343 	0x04, 0x98, 0xF0, 0x80,
9344 	0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6,
9345 	0x34, 0x02, 0x03, 0xA6,
9346 	0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96,
9347 	0x46, 0x82, 0xFE, 0x95,
9348 	0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
9349 	0x07, 0xA6, 0x5A, 0x02,
9350 	0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95,
9351 	0x48, 0x82, 0x60, 0x96,
9352 	0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84,
9353 	0x04, 0x01, 0x0C, 0xDC,
9354 	0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
9355 	0x6F, 0x00, 0xA5, 0x01,
9356 	0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01,
9357 	0x02, 0xA6, 0xAA, 0x02,
9358 	0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04,
9359 	0x01, 0xA6, 0xB4, 0x02,
9360 	0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
9361 	0x80, 0x63, 0x00, 0x43,
9362 	0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23,
9363 	0x04, 0x61, 0x84, 0x01,
9364 	0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F,
9365 	0x00, 0x00, 0xEA, 0x82,
9366 	0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
9367 	0x00, 0x33, 0x1F, 0x00,
9368 	0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98,
9369 	0xB6, 0x2D, 0x01, 0xA6,
9370 	0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6,
9371 	0x10, 0x03, 0x03, 0xA6,
9372 	0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
9373 	0x7C, 0x95, 0xEE, 0x82,
9374 	0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4,
9375 	0x04, 0x01, 0x2D, 0xC8,
9376 	0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01,
9377 	0x05, 0x05, 0x86, 0x98,
9378 	0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
9379 	0x3C, 0x04, 0x06, 0xA6,
9380 	0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88,
9381 	0x7C, 0x95, 0x32, 0x83,
9382 	0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05,
9383 	0xEB, 0x04, 0x00, 0x33,
9384 	0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
9385 	0xFF, 0xA2, 0x7A, 0x03,
9386 	0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01,
9387 	0x00, 0xA2, 0x9A, 0x03,
9388 	0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00,
9389 	0x01, 0xA6, 0x96, 0x03,
9390 	0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
9391 	0xA4, 0x03, 0x00, 0xA6,
9392 	0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03,
9393 	0x07, 0xA6, 0xB2, 0x03,
9394 	0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88,
9395 	0xA8, 0x98, 0x80, 0x42,
9396 	0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
9397 	0xC0, 0x83, 0x00, 0x33,
9398 	0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23,
9399 	0xA0, 0x01, 0x12, 0x23,
9400 	0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B,
9401 	0x80, 0x67, 0x05, 0x23,
9402 	0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
9403 	0x06, 0xA6, 0x0A, 0x04,
9404 	0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96,
9405 	0xF4, 0x83, 0x20, 0x84,
9406 	0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
9407 	0x83, 0x03, 0x80, 0x63,
9408 	0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
9409 	0x38, 0x04, 0x00, 0x33,
9410 	0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84,
9411 	0x1D, 0x01, 0x06, 0xCC,
9412 	0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62,
9413 	0xA2, 0x0D, 0x80, 0x63,
9414 	0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
9415 	0x80, 0x63, 0xA3, 0x01,
9416 	0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0,
9417 	0x76, 0x04, 0xE0, 0x00,
9418 	0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00,
9419 	0x00, 0x33, 0x1E, 0x00,
9420 	0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
9421 	0x08, 0x23, 0x22, 0xA3,
9422 	0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3,
9423 	0xC4, 0x04, 0x42, 0x23,
9424 	0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23,
9425 	0xF8, 0x88, 0x04, 0x98,
9426 	0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
9427 	0x81, 0x62, 0xE8, 0x81,
9428 	0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98,
9429 	0x00, 0x33, 0x00, 0x81,
9430 	0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23,
9431 	0xF8, 0x88, 0x04, 0x23,
9432 	0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
9433 	0xF4, 0x04, 0x00, 0x33,
9434 	0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01,
9435 	0x04, 0x23, 0xA0, 0x01,
9436 	0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00,
9437 	0x00, 0xA3, 0x22, 0x05,
9438 	0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
9439 	0x46, 0x97, 0xCD, 0x04,
9440 	0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23,
9441 	0x82, 0x01, 0x34, 0x85,
9442 	0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05,
9443 	0x1D, 0x01, 0x04, 0xD6,
9444 	0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
9445 	0x49, 0x00, 0x81, 0x01,
9446 	0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01,
9447 	0x49, 0x04, 0x80, 0x01,
9448 	0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04,
9449 	0x01, 0x23, 0xEA, 0x00,
9450 	0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
9451 	0x07, 0xA4, 0xF8, 0x05,
9452 	0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00,
9453 	0xC2, 0x88, 0x04, 0xA0,
9454 	0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61,
9455 	0x00, 0xA2, 0xA4, 0x05,
9456 	0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
9457 	0x62, 0x97, 0x04, 0x85,
9458 	0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05,
9459 	0xF4, 0x85, 0x03, 0xA0,
9460 	0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63,
9461 	0xCC, 0x86, 0x07, 0xA0,
9462 	0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
9463 	0x80, 0x67, 0x80, 0x63,
9464 	0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23,
9465 	0xF8, 0x88, 0x07, 0x23,
9466 	0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00,
9467 	0x00, 0x63, 0x4A, 0x00,
9468 	0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
9469 	0x07, 0x41, 0x83, 0x03,
9470 	0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88,
9471 	0x1D, 0x01, 0x01, 0xD6,
9472 	0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00,
9473 	0x07, 0xA6, 0x7C, 0x05,
9474 	0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
9475 	0x52, 0x00, 0x06, 0x61,
9476 	0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41,
9477 	0x00, 0x63, 0x1D, 0x01,
9478 	0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23,
9479 	0x07, 0x41, 0x00, 0x63,
9480 	0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
9481 	0xDF, 0x00, 0x06, 0xA6,
9482 	0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33,
9483 	0x00, 0x40, 0xC0, 0x20,
9484 	0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63,
9485 	0x06, 0xA6, 0x94, 0x06,
9486 	0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
9487 	0x40, 0x0E, 0x80, 0x63,
9488 	0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E,
9489 	0x80, 0x63, 0x00, 0x43,
9490 	0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05,
9491 	0x80, 0x67, 0x40, 0x0E,
9492 	0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
9493 	0x07, 0xA6, 0xD6, 0x06,
9494 	0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00,
9495 	0x0A, 0x2B, 0x07, 0xA6,
9496 	0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2,
9497 	0xF4, 0x06, 0xC0, 0x0E,
9498 	0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
9499 	0x81, 0x62, 0x04, 0x01,
9500 	0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6,
9501 	0x8C, 0x06, 0x00, 0x33,
9502 	0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03,
9503 	0x80, 0x63, 0x06, 0xA6,
9504 	0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
9505 	0x00, 0x00, 0x80, 0x67,
9506 	0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05,
9507 	0xBF, 0x23, 0x04, 0x61,
9508 	0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00,
9509 	0x00, 0x01, 0xF2, 0x00,
9510 	0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
9511 	0x80, 0x05, 0x81, 0x05,
9512 	0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00,
9513 	0x70, 0x00, 0x81, 0x01,
9514 	0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04,
9515 	0x70, 0x00, 0x80, 0x01,
9516 	0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
9517 	0xF1, 0x00, 0x70, 0x00,
9518 	0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01,
9519 	0x71, 0x04, 0x70, 0x00,
9520 	0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05,
9521 	0xA3, 0x01, 0xA2, 0x01,
9522 	0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
9523 	0xC4, 0x07, 0x00, 0x33,
9524 	0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8,
9525 	0x48, 0x00, 0xB0, 0x01,
9526 	0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43,
9527 	0x00, 0xA2, 0xE4, 0x07,
9528 	0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
9529 	0x05, 0x05, 0x00, 0x63,
9530 	0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43,
9531 	0x76, 0x08, 0x80, 0x02,
9532 	0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
9533 	0x00, 0x02, 0x00, 0xA0,
9534 	0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
9535 	0x00, 0x63, 0xF3, 0x04,
9536 	0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40,
9537 	0x00, 0xA2, 0x44, 0x08,
9538 	0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1,
9539 	0x24, 0x08, 0x04, 0x98,
9540 	0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
9541 	0x5A, 0x88, 0x02, 0x01,
9542 	0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00,
9543 	0x00, 0xA3, 0x64, 0x08,
9544 	0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63,
9545 	0x06, 0xA6, 0x76, 0x08,
9546 	0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
9547 	0x00, 0x63, 0x38, 0x2B,
9548 	0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98,
9549 	0x05, 0x05, 0xB2, 0x09,
9550 	0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63,
9551 	0x80, 0x32, 0x80, 0x36,
9552 	0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
9553 	0x40, 0x36, 0x40, 0x3A,
9554 	0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08,
9555 	0x5D, 0x00, 0xFE, 0xC3,
9556 	0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73,
9557 	0xFF, 0xFD, 0x80, 0x73,
9558 	0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
9559 	0xA1, 0x23, 0xA1, 0x01,
9560 	0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2,
9561 	0x80, 0x00, 0x03, 0xC2,
9562 	0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23,
9563 	0xA0, 0x01, 0xE6, 0x84,
9564 };
9565 
9566 static ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
9567 static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
9568 
9569 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST  16
9570 static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
9571 	INQUIRY,
9572 	REQUEST_SENSE,
9573 	READ_CAPACITY,
9574 	READ_TOC,
9575 	MODE_SELECT,
9576 	MODE_SENSE,
9577 	MODE_SELECT_10,
9578 	MODE_SENSE_10,
9579 	0xFF,
9580 	0xFF,
9581 	0xFF,
9582 	0xFF,
9583 	0xFF,
9584 	0xFF,
9585 	0xFF,
9586 	0xFF
9587 };
9588 
9589 static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
9590 {
9591 	PortAddr iop_base;
9592 	ulong last_int_level;
9593 	int sta;
9594 	int n_q_required;
9595 	int disable_syn_offset_one_fix;
9596 	int i;
9597 	ASC_PADDR addr;
9598 	ASC_EXE_CALLBACK asc_exe_callback;
9599 	ushort sg_entry_cnt = 0;
9600 	ushort sg_entry_cnt_minus_one = 0;
9601 	uchar target_ix;
9602 	uchar tid_no;
9603 	uchar sdtr_data;
9604 	uchar extra_bytes;
9605 	uchar scsi_cmd;
9606 	uchar disable_cmd;
9607 	ASC_SG_HEAD *sg_head;
9608 	ASC_DCNT data_cnt;
9609 
9610 	iop_base = asc_dvc->iop_base;
9611 	sg_head = scsiq->sg_head;
9612 	asc_exe_callback = asc_dvc->exe_callback;
9613 	if (asc_dvc->err_code != 0)
9614 		return (ERR);
9615 	if (scsiq == (ASC_SCSI_Q *)0L) {
9616 		AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
9617 		return (ERR);
9618 	}
9619 	scsiq->q1.q_no = 0;
9620 	if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
9621 		scsiq->q1.extra_bytes = 0;
9622 	}
9623 	sta = 0;
9624 	target_ix = scsiq->q2.target_ix;
9625 	tid_no = ASC_TIX_TO_TID(target_ix);
9626 	n_q_required = 1;
9627 	if (scsiq->cdbptr[0] == REQUEST_SENSE) {
9628 		if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
9629 			asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
9630 			sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9631 			AscMsgOutSDTR(asc_dvc,
9632 				      asc_dvc->
9633 				      sdtr_period_tbl[(sdtr_data >> 4) &
9634 						      (uchar)(asc_dvc->
9635 							      max_sdtr_index -
9636 							      1)],
9637 				      (uchar)(sdtr_data & (uchar)
9638 					      ASC_SYN_MAX_OFFSET));
9639 			scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
9640 		}
9641 	}
9642 	last_int_level = DvcEnterCritical();
9643 	if (asc_dvc->in_critical_cnt != 0) {
9644 		DvcLeaveCritical(last_int_level);
9645 		AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
9646 		return (ERR);
9647 	}
9648 	asc_dvc->in_critical_cnt++;
9649 	if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9650 		if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
9651 			asc_dvc->in_critical_cnt--;
9652 			DvcLeaveCritical(last_int_level);
9653 			return (ERR);
9654 		}
9655 #if !CC_VERY_LONG_SG_LIST
9656 		if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9657 			asc_dvc->in_critical_cnt--;
9658 			DvcLeaveCritical(last_int_level);
9659 			return (ERR);
9660 		}
9661 #endif /* !CC_VERY_LONG_SG_LIST */
9662 		if (sg_entry_cnt == 1) {
9663 			scsiq->q1.data_addr =
9664 			    (ADV_PADDR)sg_head->sg_list[0].addr;
9665 			scsiq->q1.data_cnt =
9666 			    (ADV_DCNT)sg_head->sg_list[0].bytes;
9667 			scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
9668 		}
9669 		sg_entry_cnt_minus_one = sg_entry_cnt - 1;
9670 	}
9671 	scsi_cmd = scsiq->cdbptr[0];
9672 	disable_syn_offset_one_fix = FALSE;
9673 	if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
9674 	    !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
9675 		if (scsiq->q1.cntl & QC_SG_HEAD) {
9676 			data_cnt = 0;
9677 			for (i = 0; i < sg_entry_cnt; i++) {
9678 				data_cnt +=
9679 				    (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
9680 							  bytes);
9681 			}
9682 		} else {
9683 			data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
9684 		}
9685 		if (data_cnt != 0UL) {
9686 			if (data_cnt < 512UL) {
9687 				disable_syn_offset_one_fix = TRUE;
9688 			} else {
9689 				for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
9690 				     i++) {
9691 					disable_cmd =
9692 					    _syn_offset_one_disable_cmd[i];
9693 					if (disable_cmd == 0xFF) {
9694 						break;
9695 					}
9696 					if (scsi_cmd == disable_cmd) {
9697 						disable_syn_offset_one_fix =
9698 						    TRUE;
9699 						break;
9700 					}
9701 				}
9702 			}
9703 		}
9704 	}
9705 	if (disable_syn_offset_one_fix) {
9706 		scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9707 		scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
9708 				       ASC_TAG_FLAG_DISABLE_DISCONNECT);
9709 	} else {
9710 		scsiq->q2.tag_code &= 0x27;
9711 	}
9712 	if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9713 		if (asc_dvc->bug_fix_cntl) {
9714 			if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9715 				if ((scsi_cmd == READ_6) ||
9716 				    (scsi_cmd == READ_10)) {
9717 					addr =
9718 					    (ADV_PADDR)le32_to_cpu(sg_head->
9719 								   sg_list
9720 								   [sg_entry_cnt_minus_one].
9721 								   addr) +
9722 					    (ADV_DCNT)le32_to_cpu(sg_head->
9723 								  sg_list
9724 								  [sg_entry_cnt_minus_one].
9725 								  bytes);
9726 					extra_bytes =
9727 					    (uchar)((ushort)addr & 0x0003);
9728 					if ((extra_bytes != 0)
9729 					    &&
9730 					    ((scsiq->q2.
9731 					      tag_code &
9732 					      ASC_TAG_FLAG_EXTRA_BYTES)
9733 					     == 0)) {
9734 						scsiq->q2.tag_code |=
9735 						    ASC_TAG_FLAG_EXTRA_BYTES;
9736 						scsiq->q1.extra_bytes =
9737 						    extra_bytes;
9738 						data_cnt =
9739 						    le32_to_cpu(sg_head->
9740 								sg_list
9741 								[sg_entry_cnt_minus_one].
9742 								bytes);
9743 						data_cnt -=
9744 						    (ASC_DCNT) extra_bytes;
9745 						sg_head->
9746 						    sg_list
9747 						    [sg_entry_cnt_minus_one].
9748 						    bytes =
9749 						    cpu_to_le32(data_cnt);
9750 					}
9751 				}
9752 			}
9753 		}
9754 		sg_head->entry_to_copy = sg_head->entry_cnt;
9755 #if CC_VERY_LONG_SG_LIST
9756 		/*
9757 		 * Set the sg_entry_cnt to the maximum possible. The rest of
9758 		 * the SG elements will be copied when the RISC completes the
9759 		 * SG elements that fit and halts.
9760 		 */
9761 		if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9762 			sg_entry_cnt = ASC_MAX_SG_LIST;
9763 		}
9764 #endif /* CC_VERY_LONG_SG_LIST */
9765 		n_q_required = AscSgListToQueue(sg_entry_cnt);
9766 		if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
9767 		     (uint) n_q_required)
9768 		    || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9769 			if ((sta =
9770 			     AscSendScsiQueue(asc_dvc, scsiq,
9771 					      n_q_required)) == 1) {
9772 				asc_dvc->in_critical_cnt--;
9773 				if (asc_exe_callback != 0) {
9774 					(*asc_exe_callback) (asc_dvc, scsiq);
9775 				}
9776 				DvcLeaveCritical(last_int_level);
9777 				return (sta);
9778 			}
9779 		}
9780 	} else {
9781 		if (asc_dvc->bug_fix_cntl) {
9782 			if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9783 				if ((scsi_cmd == READ_6) ||
9784 				    (scsi_cmd == READ_10)) {
9785 					addr =
9786 					    le32_to_cpu(scsiq->q1.data_addr) +
9787 					    le32_to_cpu(scsiq->q1.data_cnt);
9788 					extra_bytes =
9789 					    (uchar)((ushort)addr & 0x0003);
9790 					if ((extra_bytes != 0)
9791 					    &&
9792 					    ((scsiq->q2.
9793 					      tag_code &
9794 					      ASC_TAG_FLAG_EXTRA_BYTES)
9795 					     == 0)) {
9796 						data_cnt =
9797 						    le32_to_cpu(scsiq->q1.
9798 								data_cnt);
9799 						if (((ushort)data_cnt & 0x01FF)
9800 						    == 0) {
9801 							scsiq->q2.tag_code |=
9802 							    ASC_TAG_FLAG_EXTRA_BYTES;
9803 							data_cnt -= (ASC_DCNT)
9804 							    extra_bytes;
9805 							scsiq->q1.data_cnt =
9806 							    cpu_to_le32
9807 							    (data_cnt);
9808 							scsiq->q1.extra_bytes =
9809 							    extra_bytes;
9810 						}
9811 					}
9812 				}
9813 			}
9814 		}
9815 		n_q_required = 1;
9816 		if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
9817 		    ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9818 			if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
9819 						    n_q_required)) == 1) {
9820 				asc_dvc->in_critical_cnt--;
9821 				if (asc_exe_callback != 0) {
9822 					(*asc_exe_callback) (asc_dvc, scsiq);
9823 				}
9824 				DvcLeaveCritical(last_int_level);
9825 				return (sta);
9826 			}
9827 		}
9828 	}
9829 	asc_dvc->in_critical_cnt--;
9830 	DvcLeaveCritical(last_int_level);
9831 	return (sta);
9832 }
9833 
9834 static int
9835 AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
9836 {
9837 	PortAddr iop_base;
9838 	uchar free_q_head;
9839 	uchar next_qp;
9840 	uchar tid_no;
9841 	uchar target_ix;
9842 	int sta;
9843 
9844 	iop_base = asc_dvc->iop_base;
9845 	target_ix = scsiq->q2.target_ix;
9846 	tid_no = ASC_TIX_TO_TID(target_ix);
9847 	sta = 0;
9848 	free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
9849 	if (n_q_required > 1) {
9850 		if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
9851 							 free_q_head, (uchar)
9852 							 (n_q_required)))
9853 		    != (uchar)ASC_QLINK_END) {
9854 			asc_dvc->last_q_shortage = 0;
9855 			scsiq->sg_head->queue_cnt = n_q_required - 1;
9856 			scsiq->q1.q_no = free_q_head;
9857 			if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
9858 							  free_q_head)) == 1) {
9859 				AscPutVarFreeQHead(iop_base, next_qp);
9860 				asc_dvc->cur_total_qng += (uchar)(n_q_required);
9861 				asc_dvc->cur_dvc_qng[tid_no]++;
9862 			}
9863 			return (sta);
9864 		}
9865 	} else if (n_q_required == 1) {
9866 		if ((next_qp = AscAllocFreeQueue(iop_base,
9867 						 free_q_head)) !=
9868 		    ASC_QLINK_END) {
9869 			scsiq->q1.q_no = free_q_head;
9870 			if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
9871 						    free_q_head)) == 1) {
9872 				AscPutVarFreeQHead(iop_base, next_qp);
9873 				asc_dvc->cur_total_qng++;
9874 				asc_dvc->cur_dvc_qng[tid_no]++;
9875 			}
9876 			return (sta);
9877 		}
9878 	}
9879 	return (sta);
9880 }
9881 
9882 static int AscSgListToQueue(int sg_list)
9883 {
9884 	int n_sg_list_qs;
9885 
9886 	n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
9887 	if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
9888 		n_sg_list_qs++;
9889 	return (n_sg_list_qs + 1);
9890 }
9891 
9892 static uint
9893 AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
9894 {
9895 	uint cur_used_qs;
9896 	uint cur_free_qs;
9897 	ASC_SCSI_BIT_ID_TYPE target_id;
9898 	uchar tid_no;
9899 
9900 	target_id = ASC_TIX_TO_TARGET_ID(target_ix);
9901 	tid_no = ASC_TIX_TO_TID(target_ix);
9902 	if ((asc_dvc->unit_not_ready & target_id) ||
9903 	    (asc_dvc->queue_full_or_busy & target_id)) {
9904 		return (0);
9905 	}
9906 	if (n_qs == 1) {
9907 		cur_used_qs = (uint) asc_dvc->cur_total_qng +
9908 		    (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
9909 	} else {
9910 		cur_used_qs = (uint) asc_dvc->cur_total_qng +
9911 		    (uint) ASC_MIN_FREE_Q;
9912 	}
9913 	if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
9914 		cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
9915 		if (asc_dvc->cur_dvc_qng[tid_no] >=
9916 		    asc_dvc->max_dvc_qng[tid_no]) {
9917 			return (0);
9918 		}
9919 		return (cur_free_qs);
9920 	}
9921 	if (n_qs > 1) {
9922 		if ((n_qs > asc_dvc->last_q_shortage)
9923 		    && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
9924 			asc_dvc->last_q_shortage = n_qs;
9925 		}
9926 	}
9927 	return (0);
9928 }
9929 
9930 static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
9931 {
9932 	ushort q_addr;
9933 	uchar tid_no;
9934 	uchar sdtr_data;
9935 	uchar syn_period_ix;
9936 	uchar syn_offset;
9937 	PortAddr iop_base;
9938 
9939 	iop_base = asc_dvc->iop_base;
9940 	if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
9941 	    ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
9942 		tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
9943 		sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9944 		syn_period_ix =
9945 		    (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
9946 		syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
9947 		AscMsgOutSDTR(asc_dvc,
9948 			      asc_dvc->sdtr_period_tbl[syn_period_ix],
9949 			      syn_offset);
9950 		scsiq->q1.cntl |= QC_MSG_OUT;
9951 	}
9952 	q_addr = ASC_QNO_TO_QADDR(q_no);
9953 	if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
9954 		scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9955 	}
9956 	scsiq->q1.status = QS_FREE;
9957 	AscMemWordCopyPtrToLram(iop_base,
9958 				q_addr + ASC_SCSIQ_CDB_BEG,
9959 				(uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
9960 
9961 	DvcPutScsiQ(iop_base,
9962 		    q_addr + ASC_SCSIQ_CPY_BEG,
9963 		    (uchar *)&scsiq->q1.cntl,
9964 		    ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
9965 	AscWriteLramWord(iop_base,
9966 			 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
9967 			 (ushort)(((ushort)scsiq->q1.
9968 				   q_no << 8) | (ushort)QS_READY));
9969 	return (1);
9970 }
9971 
9972 static int
9973 AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
9974 {
9975 	int sta;
9976 	int i;
9977 	ASC_SG_HEAD *sg_head;
9978 	ASC_SG_LIST_Q scsi_sg_q;
9979 	ASC_DCNT saved_data_addr;
9980 	ASC_DCNT saved_data_cnt;
9981 	PortAddr iop_base;
9982 	ushort sg_list_dwords;
9983 	ushort sg_index;
9984 	ushort sg_entry_cnt;
9985 	ushort q_addr;
9986 	uchar next_qp;
9987 
9988 	iop_base = asc_dvc->iop_base;
9989 	sg_head = scsiq->sg_head;
9990 	saved_data_addr = scsiq->q1.data_addr;
9991 	saved_data_cnt = scsiq->q1.data_cnt;
9992 	scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
9993 	scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
9994 #if CC_VERY_LONG_SG_LIST
9995 	/*
9996 	 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
9997 	 * then not all SG elements will fit in the allocated queues.
9998 	 * The rest of the SG elements will be copied when the RISC
9999 	 * completes the SG elements that fit and halts.
10000 	 */
10001 	if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
10002 		/*
10003 		 * Set sg_entry_cnt to be the number of SG elements that
10004 		 * will fit in the allocated SG queues. It is minus 1, because
10005 		 * the first SG element is handled above. ASC_MAX_SG_LIST is
10006 		 * already inflated by 1 to account for this. For example it
10007 		 * may be 50 which is 1 + 7 queues * 7 SG elements.
10008 		 */
10009 		sg_entry_cnt = ASC_MAX_SG_LIST - 1;
10010 
10011 		/*
10012 		 * Keep track of remaining number of SG elements that will
10013 		 * need to be handled from a_isr.c.
10014 		 */
10015 		scsiq->remain_sg_entry_cnt =
10016 		    sg_head->entry_cnt - ASC_MAX_SG_LIST;
10017 	} else {
10018 #endif /* CC_VERY_LONG_SG_LIST */
10019 		/*
10020 		 * Set sg_entry_cnt to be the number of SG elements that
10021 		 * will fit in the allocated SG queues. It is minus 1, because
10022 		 * the first SG element is handled above.
10023 		 */
10024 		sg_entry_cnt = sg_head->entry_cnt - 1;
10025 #if CC_VERY_LONG_SG_LIST
10026 	}
10027 #endif /* CC_VERY_LONG_SG_LIST */
10028 	if (sg_entry_cnt != 0) {
10029 		scsiq->q1.cntl |= QC_SG_HEAD;
10030 		q_addr = ASC_QNO_TO_QADDR(q_no);
10031 		sg_index = 1;
10032 		scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
10033 		scsi_sg_q.sg_head_qp = q_no;
10034 		scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
10035 		for (i = 0; i < sg_head->queue_cnt; i++) {
10036 			scsi_sg_q.seq_no = i + 1;
10037 			if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
10038 				sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
10039 				sg_entry_cnt -= ASC_SG_LIST_PER_Q;
10040 				if (i == 0) {
10041 					scsi_sg_q.sg_list_cnt =
10042 					    ASC_SG_LIST_PER_Q;
10043 					scsi_sg_q.sg_cur_list_cnt =
10044 					    ASC_SG_LIST_PER_Q;
10045 				} else {
10046 					scsi_sg_q.sg_list_cnt =
10047 					    ASC_SG_LIST_PER_Q - 1;
10048 					scsi_sg_q.sg_cur_list_cnt =
10049 					    ASC_SG_LIST_PER_Q - 1;
10050 				}
10051 			} else {
10052 #if CC_VERY_LONG_SG_LIST
10053 				/*
10054 				 * This is the last SG queue in the list of
10055 				 * allocated SG queues. If there are more
10056 				 * SG elements than will fit in the allocated
10057 				 * queues, then set the QCSG_SG_XFER_MORE flag.
10058 				 */
10059 				if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
10060 					scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
10061 				} else {
10062 #endif /* CC_VERY_LONG_SG_LIST */
10063 					scsi_sg_q.cntl |= QCSG_SG_XFER_END;
10064 #if CC_VERY_LONG_SG_LIST
10065 				}
10066 #endif /* CC_VERY_LONG_SG_LIST */
10067 				sg_list_dwords = sg_entry_cnt << 1;
10068 				if (i == 0) {
10069 					scsi_sg_q.sg_list_cnt = sg_entry_cnt;
10070 					scsi_sg_q.sg_cur_list_cnt =
10071 					    sg_entry_cnt;
10072 				} else {
10073 					scsi_sg_q.sg_list_cnt =
10074 					    sg_entry_cnt - 1;
10075 					scsi_sg_q.sg_cur_list_cnt =
10076 					    sg_entry_cnt - 1;
10077 				}
10078 				sg_entry_cnt = 0;
10079 			}
10080 			next_qp = AscReadLramByte(iop_base,
10081 						  (ushort)(q_addr +
10082 							   ASC_SCSIQ_B_FWD));
10083 			scsi_sg_q.q_no = next_qp;
10084 			q_addr = ASC_QNO_TO_QADDR(next_qp);
10085 			AscMemWordCopyPtrToLram(iop_base,
10086 						q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
10087 						(uchar *)&scsi_sg_q,
10088 						sizeof(ASC_SG_LIST_Q) >> 1);
10089 			AscMemDWordCopyPtrToLram(iop_base,
10090 						 q_addr + ASC_SGQ_LIST_BEG,
10091 						 (uchar *)&sg_head->
10092 						 sg_list[sg_index],
10093 						 sg_list_dwords);
10094 			sg_index += ASC_SG_LIST_PER_Q;
10095 			scsiq->next_sg_index = sg_index;
10096 		}
10097 	} else {
10098 		scsiq->q1.cntl &= ~QC_SG_HEAD;
10099 	}
10100 	sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
10101 	scsiq->q1.data_addr = saved_data_addr;
10102 	scsiq->q1.data_cnt = saved_data_cnt;
10103 	return (sta);
10104 }
10105 
10106 static int
10107 AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
10108 {
10109 	int sta = FALSE;
10110 
10111 	if (AscHostReqRiscHalt(iop_base)) {
10112 		sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
10113 		AscStartChip(iop_base);
10114 		return (sta);
10115 	}
10116 	return (sta);
10117 }
10118 
10119 static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
10120 {
10121 	ASC_SCSI_BIT_ID_TYPE org_id;
10122 	int i;
10123 	int sta = TRUE;
10124 
10125 	AscSetBank(iop_base, 1);
10126 	org_id = AscReadChipDvcID(iop_base);
10127 	for (i = 0; i <= ASC_MAX_TID; i++) {
10128 		if (org_id == (0x01 << i))
10129 			break;
10130 	}
10131 	org_id = (ASC_SCSI_BIT_ID_TYPE) i;
10132 	AscWriteChipDvcID(iop_base, id);
10133 	if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
10134 		AscSetBank(iop_base, 0);
10135 		AscSetChipSyn(iop_base, sdtr_data);
10136 		if (AscGetChipSyn(iop_base) != sdtr_data) {
10137 			sta = FALSE;
10138 		}
10139 	} else {
10140 		sta = FALSE;
10141 	}
10142 	AscSetBank(iop_base, 1);
10143 	AscWriteChipDvcID(iop_base, org_id);
10144 	AscSetBank(iop_base, 0);
10145 	return (sta);
10146 }
10147 
10148 static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
10149 {
10150 	uchar i;
10151 	ushort s_addr;
10152 	PortAddr iop_base;
10153 	ushort warn_code;
10154 
10155 	iop_base = asc_dvc->iop_base;
10156 	warn_code = 0;
10157 	AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
10158 			  (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
10159 				    64) >> 1)
10160 	    );
10161 	i = ASC_MIN_ACTIVE_QNO;
10162 	s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
10163 	AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
10164 			 (uchar)(i + 1));
10165 	AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
10166 			 (uchar)(asc_dvc->max_total_qng));
10167 	AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
10168 			 (uchar)i);
10169 	i++;
10170 	s_addr += ASC_QBLK_SIZE;
10171 	for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
10172 		AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
10173 				 (uchar)(i + 1));
10174 		AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
10175 				 (uchar)(i - 1));
10176 		AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
10177 				 (uchar)i);
10178 	}
10179 	AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
10180 			 (uchar)ASC_QLINK_END);
10181 	AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
10182 			 (uchar)(asc_dvc->max_total_qng - 1));
10183 	AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
10184 			 (uchar)asc_dvc->max_total_qng);
10185 	i++;
10186 	s_addr += ASC_QBLK_SIZE;
10187 	for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
10188 	     i++, s_addr += ASC_QBLK_SIZE) {
10189 		AscWriteLramByte(iop_base,
10190 				 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
10191 		AscWriteLramByte(iop_base,
10192 				 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
10193 		AscWriteLramByte(iop_base,
10194 				 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
10195 	}
10196 	return (warn_code);
10197 }
10198 
10199 static ushort AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
10200 {
10201 	PortAddr iop_base;
10202 	int i;
10203 	ushort lram_addr;
10204 
10205 	iop_base = asc_dvc->iop_base;
10206 	AscPutRiscVarFreeQHead(iop_base, 1);
10207 	AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
10208 	AscPutVarFreeQHead(iop_base, 1);
10209 	AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
10210 	AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
10211 			 (uchar)((int)asc_dvc->max_total_qng + 1));
10212 	AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
10213 			 (uchar)((int)asc_dvc->max_total_qng + 2));
10214 	AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
10215 			 asc_dvc->max_total_qng);
10216 	AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
10217 	AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10218 	AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
10219 	AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
10220 	AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
10221 	AscPutQDoneInProgress(iop_base, 0);
10222 	lram_addr = ASC_QADR_BEG;
10223 	for (i = 0; i < 32; i++, lram_addr += 2) {
10224 		AscWriteLramWord(iop_base, lram_addr, 0);
10225 	}
10226 	return (0);
10227 }
10228 
10229 static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
10230 {
10231 	if (asc_dvc->err_code == 0) {
10232 		asc_dvc->err_code = err_code;
10233 		AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
10234 				 err_code);
10235 	}
10236 	return (err_code);
10237 }
10238 
10239 static uchar
10240 AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
10241 {
10242 	EXT_MSG sdtr_buf;
10243 	uchar sdtr_period_index;
10244 	PortAddr iop_base;
10245 
10246 	iop_base = asc_dvc->iop_base;
10247 	sdtr_buf.msg_type = MS_EXTEND;
10248 	sdtr_buf.msg_len = MS_SDTR_LEN;
10249 	sdtr_buf.msg_req = MS_SDTR_CODE;
10250 	sdtr_buf.xfer_period = sdtr_period;
10251 	sdtr_offset &= ASC_SYN_MAX_OFFSET;
10252 	sdtr_buf.req_ack_offset = sdtr_offset;
10253 	if ((sdtr_period_index =
10254 	     AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
10255 	    asc_dvc->max_sdtr_index) {
10256 		AscMemWordCopyPtrToLram(iop_base,
10257 					ASCV_MSGOUT_BEG,
10258 					(uchar *)&sdtr_buf,
10259 					sizeof(EXT_MSG) >> 1);
10260 		return ((sdtr_period_index << 4) | sdtr_offset);
10261 	} else {
10262 
10263 		sdtr_buf.req_ack_offset = 0;
10264 		AscMemWordCopyPtrToLram(iop_base,
10265 					ASCV_MSGOUT_BEG,
10266 					(uchar *)&sdtr_buf,
10267 					sizeof(EXT_MSG) >> 1);
10268 		return (0);
10269 	}
10270 }
10271 
10272 static uchar
10273 AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
10274 {
10275 	uchar byte;
10276 	uchar sdtr_period_ix;
10277 
10278 	sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
10279 	if ((sdtr_period_ix > asc_dvc->max_sdtr_index)
10280 	    ) {
10281 		return (0xFF);
10282 	}
10283 	byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
10284 	return (byte);
10285 }
10286 
10287 static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
10288 {
10289 	AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
10290 	AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
10291 	return;
10292 }
10293 
10294 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
10295 {
10296 	uchar *period_table;
10297 	int max_index;
10298 	int min_index;
10299 	int i;
10300 
10301 	period_table = asc_dvc->sdtr_period_tbl;
10302 	max_index = (int)asc_dvc->max_sdtr_index;
10303 	min_index = (int)asc_dvc->host_init_sdtr_index;
10304 	if ((syn_time <= period_table[max_index])) {
10305 		for (i = min_index; i < (max_index - 1); i++) {
10306 			if (syn_time <= period_table[i]) {
10307 				return ((uchar)i);
10308 			}
10309 		}
10310 		return ((uchar)max_index);
10311 	} else {
10312 		return ((uchar)(max_index + 1));
10313 	}
10314 }
10315 
10316 static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
10317 {
10318 	ushort q_addr;
10319 	uchar next_qp;
10320 	uchar q_status;
10321 
10322 	q_addr = ASC_QNO_TO_QADDR(free_q_head);
10323 	q_status = (uchar)AscReadLramByte(iop_base,
10324 					  (ushort)(q_addr +
10325 						   ASC_SCSIQ_B_STATUS));
10326 	next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
10327 	if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
10328 		return (next_qp);
10329 	}
10330 	return (ASC_QLINK_END);
10331 }
10332 
10333 static uchar
10334 AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
10335 {
10336 	uchar i;
10337 
10338 	for (i = 0; i < n_free_q; i++) {
10339 		if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
10340 		    == ASC_QLINK_END) {
10341 			return (ASC_QLINK_END);
10342 		}
10343 	}
10344 	return (free_q_head);
10345 }
10346 
10347 static int AscHostReqRiscHalt(PortAddr iop_base)
10348 {
10349 	int count = 0;
10350 	int sta = 0;
10351 	uchar saved_stop_code;
10352 
10353 	if (AscIsChipHalted(iop_base))
10354 		return (1);
10355 	saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
10356 	AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
10357 			 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
10358 	do {
10359 		if (AscIsChipHalted(iop_base)) {
10360 			sta = 1;
10361 			break;
10362 		}
10363 		DvcSleepMilliSecond(100);
10364 	} while (count++ < 20);
10365 	AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
10366 	return (sta);
10367 }
10368 
10369 static int AscStopQueueExe(PortAddr iop_base)
10370 {
10371 	int count = 0;
10372 
10373 	if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
10374 		AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
10375 				 ASC_STOP_REQ_RISC_STOP);
10376 		do {
10377 			if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
10378 			    ASC_STOP_ACK_RISC_STOP) {
10379 				return (1);
10380 			}
10381 			DvcSleepMilliSecond(100);
10382 		} while (count++ < 20);
10383 	}
10384 	return (0);
10385 }
10386 
10387 static void DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
10388 {
10389 	udelay(micro_sec);
10390 }
10391 
10392 static void DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
10393 {
10394 	udelay((nano_sec + 999) / 1000);
10395 }
10396 
10397 #ifdef CONFIG_ISA
10398 static ASC_DCNT __init AscGetEisaProductID(PortAddr iop_base)
10399 {
10400 	PortAddr eisa_iop;
10401 	ushort product_id_high, product_id_low;
10402 	ASC_DCNT product_id;
10403 
10404 	eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
10405 	product_id_low = inpw(eisa_iop);
10406 	product_id_high = inpw(eisa_iop + 2);
10407 	product_id = ((ASC_DCNT) product_id_high << 16) |
10408 	    (ASC_DCNT) product_id_low;
10409 	return (product_id);
10410 }
10411 
10412 static PortAddr __init AscSearchIOPortAddrEISA(PortAddr iop_base)
10413 {
10414 	ASC_DCNT eisa_product_id;
10415 
10416 	if (iop_base == 0) {
10417 		iop_base = ASC_EISA_MIN_IOP_ADDR;
10418 	} else {
10419 		if (iop_base == ASC_EISA_MAX_IOP_ADDR)
10420 			return (0);
10421 		if ((iop_base & 0x0050) == 0x0050) {
10422 			iop_base += ASC_EISA_BIG_IOP_GAP;
10423 		} else {
10424 			iop_base += ASC_EISA_SMALL_IOP_GAP;
10425 		}
10426 	}
10427 	while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
10428 		eisa_product_id = AscGetEisaProductID(iop_base);
10429 		if ((eisa_product_id == ASC_EISA_ID_740) ||
10430 		    (eisa_product_id == ASC_EISA_ID_750)) {
10431 			if (AscFindSignature(iop_base)) {
10432 				inpw(iop_base + 4);
10433 				return (iop_base);
10434 			}
10435 		}
10436 		if (iop_base == ASC_EISA_MAX_IOP_ADDR)
10437 			return (0);
10438 		if ((iop_base & 0x0050) == 0x0050) {
10439 			iop_base += ASC_EISA_BIG_IOP_GAP;
10440 		} else {
10441 			iop_base += ASC_EISA_SMALL_IOP_GAP;
10442 		}
10443 	}
10444 	return (0);
10445 }
10446 #endif /* CONFIG_ISA */
10447 
10448 static int AscStartChip(PortAddr iop_base)
10449 {
10450 	AscSetChipControl(iop_base, 0);
10451 	if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
10452 		return (0);
10453 	}
10454 	return (1);
10455 }
10456 
10457 static int AscStopChip(PortAddr iop_base)
10458 {
10459 	uchar cc_val;
10460 
10461 	cc_val =
10462 	    AscGetChipControl(iop_base) &
10463 	    (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
10464 	AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
10465 	AscSetChipIH(iop_base, INS_HALT);
10466 	AscSetChipIH(iop_base, INS_RFLAG_WTM);
10467 	if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
10468 		return (0);
10469 	}
10470 	return (1);
10471 }
10472 
10473 static int AscIsChipHalted(PortAddr iop_base)
10474 {
10475 	if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
10476 		if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
10477 			return (1);
10478 		}
10479 	}
10480 	return (0);
10481 }
10482 
10483 static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
10484 {
10485 	AscSetBank(iop_base, 1);
10486 	AscWriteChipIH(iop_base, ins_code);
10487 	AscSetBank(iop_base, 0);
10488 	return;
10489 }
10490 
10491 static void AscAckInterrupt(PortAddr iop_base)
10492 {
10493 	uchar host_flag;
10494 	uchar risc_flag;
10495 	ushort loop;
10496 
10497 	loop = 0;
10498 	do {
10499 		risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
10500 		if (loop++ > 0x7FFF) {
10501 			break;
10502 		}
10503 	} while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
10504 	host_flag =
10505 	    AscReadLramByte(iop_base,
10506 			    ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
10507 	AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10508 			 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
10509 	AscSetChipStatus(iop_base, CIW_INT_ACK);
10510 	loop = 0;
10511 	while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
10512 		AscSetChipStatus(iop_base, CIW_INT_ACK);
10513 		if (loop++ > 3) {
10514 			break;
10515 		}
10516 	}
10517 	AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10518 	return;
10519 }
10520 
10521 static void AscDisableInterrupt(PortAddr iop_base)
10522 {
10523 	ushort cfg;
10524 
10525 	cfg = AscGetChipCfgLsw(iop_base);
10526 	AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
10527 	return;
10528 }
10529 
10530 static void AscEnableInterrupt(PortAddr iop_base)
10531 {
10532 	ushort cfg;
10533 
10534 	cfg = AscGetChipCfgLsw(iop_base);
10535 	AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
10536 	return;
10537 }
10538 
10539 static void AscSetBank(PortAddr iop_base, uchar bank)
10540 {
10541 	uchar val;
10542 
10543 	val = AscGetChipControl(iop_base) &
10544 	    (~
10545 	     (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
10546 	      CC_CHIP_RESET));
10547 	if (bank == 1) {
10548 		val |= CC_BANK_ONE;
10549 	} else if (bank == 2) {
10550 		val |= CC_DIAG | CC_BANK_ONE;
10551 	} else {
10552 		val &= ~CC_BANK_ONE;
10553 	}
10554 	AscSetChipControl(iop_base, val);
10555 	return;
10556 }
10557 
10558 static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
10559 {
10560 	PortAddr iop_base;
10561 	int i = 10;
10562 
10563 	iop_base = asc_dvc->iop_base;
10564 	while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
10565 	       && (i-- > 0)) {
10566 		DvcSleepMilliSecond(100);
10567 	}
10568 	AscStopChip(iop_base);
10569 	AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
10570 	DvcDelayNanoSecond(asc_dvc, 60000);
10571 	AscSetChipIH(iop_base, INS_RFLAG_WTM);
10572 	AscSetChipIH(iop_base, INS_HALT);
10573 	AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
10574 	AscSetChipControl(iop_base, CC_HALT);
10575 	DvcSleepMilliSecond(200);
10576 	AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10577 	AscSetChipStatus(iop_base, 0);
10578 	return (AscIsChipHalted(iop_base));
10579 }
10580 
10581 static ASC_DCNT __init AscGetMaxDmaCount(ushort bus_type)
10582 {
10583 	if (bus_type & ASC_IS_ISA)
10584 		return (ASC_MAX_ISA_DMA_COUNT);
10585 	else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
10586 		return (ASC_MAX_VL_DMA_COUNT);
10587 	return (ASC_MAX_PCI_DMA_COUNT);
10588 }
10589 
10590 #ifdef CONFIG_ISA
10591 static ushort __init AscGetIsaDmaChannel(PortAddr iop_base)
10592 {
10593 	ushort channel;
10594 
10595 	channel = AscGetChipCfgLsw(iop_base) & 0x0003;
10596 	if (channel == 0x03)
10597 		return (0);
10598 	else if (channel == 0x00)
10599 		return (7);
10600 	return (channel + 4);
10601 }
10602 
10603 static ushort __init AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
10604 {
10605 	ushort cfg_lsw;
10606 	uchar value;
10607 
10608 	if ((dma_channel >= 5) && (dma_channel <= 7)) {
10609 		if (dma_channel == 7)
10610 			value = 0x00;
10611 		else
10612 			value = dma_channel - 4;
10613 		cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
10614 		cfg_lsw |= value;
10615 		AscSetChipCfgLsw(iop_base, cfg_lsw);
10616 		return (AscGetIsaDmaChannel(iop_base));
10617 	}
10618 	return (0);
10619 }
10620 
10621 static uchar __init AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
10622 {
10623 	speed_value &= 0x07;
10624 	AscSetBank(iop_base, 1);
10625 	AscWriteChipDmaSpeed(iop_base, speed_value);
10626 	AscSetBank(iop_base, 0);
10627 	return (AscGetIsaDmaSpeed(iop_base));
10628 }
10629 
10630 static uchar __init AscGetIsaDmaSpeed(PortAddr iop_base)
10631 {
10632 	uchar speed_value;
10633 
10634 	AscSetBank(iop_base, 1);
10635 	speed_value = AscReadChipDmaSpeed(iop_base);
10636 	speed_value &= 0x07;
10637 	AscSetBank(iop_base, 0);
10638 	return (speed_value);
10639 }
10640 #endif /* CONFIG_ISA */
10641 
10642 static ushort __init
10643 AscReadPCIConfigWord(ASC_DVC_VAR *asc_dvc, ushort pci_config_offset)
10644 {
10645 	uchar lsb, msb;
10646 
10647 	lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
10648 	msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
10649 	return ((ushort)((msb << 8) | lsb));
10650 }
10651 
10652 static ushort __init AscInitGetConfig(ASC_DVC_VAR *asc_dvc)
10653 {
10654 	ushort warn_code;
10655 	PortAddr iop_base;
10656 	ushort PCIDeviceID;
10657 	ushort PCIVendorID;
10658 	uchar PCIRevisionID;
10659 	uchar prevCmdRegBits;
10660 
10661 	warn_code = 0;
10662 	iop_base = asc_dvc->iop_base;
10663 	asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
10664 	if (asc_dvc->err_code != 0) {
10665 		return (UW_ERR);
10666 	}
10667 	if (asc_dvc->bus_type == ASC_IS_PCI) {
10668 		PCIVendorID = AscReadPCIConfigWord(asc_dvc,
10669 						   AscPCIConfigVendorIDRegister);
10670 
10671 		PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
10672 						   AscPCIConfigDeviceIDRegister);
10673 
10674 		PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
10675 						     AscPCIConfigRevisionIDRegister);
10676 
10677 		if (PCIVendorID != PCI_VENDOR_ID_ASP) {
10678 			warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10679 		}
10680 		prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
10681 						      AscPCIConfigCommandRegister);
10682 
10683 		if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
10684 		    AscPCICmdRegBits_IOMemBusMaster) {
10685 			DvcWritePCIConfigByte(asc_dvc,
10686 					      AscPCIConfigCommandRegister,
10687 					      (prevCmdRegBits |
10688 					       AscPCICmdRegBits_IOMemBusMaster));
10689 
10690 			if ((DvcReadPCIConfigByte(asc_dvc,
10691 						  AscPCIConfigCommandRegister)
10692 			     & AscPCICmdRegBits_IOMemBusMaster)
10693 			    != AscPCICmdRegBits_IOMemBusMaster) {
10694 				warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10695 			}
10696 		}
10697 		if ((PCIDeviceID == PCI_DEVICE_ID_ASP_1200A) ||
10698 		    (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940)) {
10699 			DvcWritePCIConfigByte(asc_dvc,
10700 					      AscPCIConfigLatencyTimer, 0x00);
10701 			if (DvcReadPCIConfigByte
10702 			    (asc_dvc, AscPCIConfigLatencyTimer)
10703 			    != 0x00) {
10704 				warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10705 			}
10706 		} else if (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940U) {
10707 			if (DvcReadPCIConfigByte(asc_dvc,
10708 						 AscPCIConfigLatencyTimer) <
10709 			    0x20) {
10710 				DvcWritePCIConfigByte(asc_dvc,
10711 						      AscPCIConfigLatencyTimer,
10712 						      0x20);
10713 
10714 				if (DvcReadPCIConfigByte(asc_dvc,
10715 							 AscPCIConfigLatencyTimer)
10716 				    < 0x20) {
10717 					warn_code |=
10718 					    ASC_WARN_SET_PCI_CONFIG_SPACE;
10719 				}
10720 			}
10721 		}
10722 	}
10723 
10724 	if (AscFindSignature(iop_base)) {
10725 		warn_code |= AscInitAscDvcVar(asc_dvc);
10726 		warn_code |= AscInitFromEEP(asc_dvc);
10727 		asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
10728 		if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
10729 			asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
10730 		}
10731 	} else {
10732 		asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10733 	}
10734 	return (warn_code);
10735 }
10736 
10737 static ushort __init AscInitSetConfig(ASC_DVC_VAR *asc_dvc)
10738 {
10739 	ushort warn_code = 0;
10740 
10741 	asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
10742 	if (asc_dvc->err_code != 0)
10743 		return (UW_ERR);
10744 	if (AscFindSignature(asc_dvc->iop_base)) {
10745 		warn_code |= AscInitFromAscDvcVar(asc_dvc);
10746 		asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
10747 	} else {
10748 		asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10749 	}
10750 	return (warn_code);
10751 }
10752 
10753 static ushort __init AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc)
10754 {
10755 	PortAddr iop_base;
10756 	ushort cfg_msw;
10757 	ushort warn_code;
10758 	ushort pci_device_id = 0;
10759 
10760 	iop_base = asc_dvc->iop_base;
10761 #ifdef CONFIG_PCI
10762 	if (asc_dvc->cfg->dev)
10763 		pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device;
10764 #endif
10765 	warn_code = 0;
10766 	cfg_msw = AscGetChipCfgMsw(iop_base);
10767 	if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10768 		cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10769 		warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10770 		AscSetChipCfgMsw(iop_base, cfg_msw);
10771 	}
10772 	if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
10773 	    asc_dvc->cfg->cmd_qng_enabled) {
10774 		asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
10775 		warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10776 	}
10777 	if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10778 		warn_code |= ASC_WARN_AUTO_CONFIG;
10779 	}
10780 	if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
10781 		if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
10782 		    != asc_dvc->irq_no) {
10783 			asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
10784 		}
10785 	}
10786 	if (asc_dvc->bus_type & ASC_IS_PCI) {
10787 		cfg_msw &= 0xFFC0;
10788 		AscSetChipCfgMsw(iop_base, cfg_msw);
10789 		if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
10790 		} else {
10791 			if ((pci_device_id == PCI_DEVICE_ID_ASP_1200A) ||
10792 			    (pci_device_id == PCI_DEVICE_ID_ASP_ABP940)) {
10793 				asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
10794 				asc_dvc->bug_fix_cntl |=
10795 				    ASC_BUG_FIX_ASYN_USE_SYN;
10796 			}
10797 		}
10798 	} else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
10799 		if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
10800 		    == ASC_CHIP_VER_ASYN_BUG) {
10801 			asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
10802 		}
10803 	}
10804 	if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
10805 	    asc_dvc->cfg->chip_scsi_id) {
10806 		asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
10807 	}
10808 #ifdef CONFIG_ISA
10809 	if (asc_dvc->bus_type & ASC_IS_ISA) {
10810 		AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
10811 		AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
10812 	}
10813 #endif /* CONFIG_ISA */
10814 	return (warn_code);
10815 }
10816 
10817 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
10818 {
10819 	ushort warn_code;
10820 	PortAddr iop_base;
10821 
10822 	iop_base = asc_dvc->iop_base;
10823 	warn_code = 0;
10824 	if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
10825 	    !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
10826 		AscResetChipAndScsiBus(asc_dvc);
10827 		DvcSleepMilliSecond((ASC_DCNT)
10828 				    ((ushort)asc_dvc->scsi_reset_wait * 1000));
10829 	}
10830 	asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
10831 	if (asc_dvc->err_code != 0)
10832 		return (UW_ERR);
10833 	if (!AscFindSignature(asc_dvc->iop_base)) {
10834 		asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10835 		return (warn_code);
10836 	}
10837 	AscDisableInterrupt(iop_base);
10838 	warn_code |= AscInitLram(asc_dvc);
10839 	if (asc_dvc->err_code != 0)
10840 		return (UW_ERR);
10841 	ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
10842 		 (ulong)_asc_mcode_chksum);
10843 	if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
10844 			     _asc_mcode_size) != _asc_mcode_chksum) {
10845 		asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
10846 		return (warn_code);
10847 	}
10848 	warn_code |= AscInitMicroCodeVar(asc_dvc);
10849 	asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
10850 	AscEnableInterrupt(iop_base);
10851 	return (warn_code);
10852 }
10853 
10854 static ushort __init AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
10855 {
10856 	int i;
10857 	PortAddr iop_base;
10858 	ushort warn_code;
10859 	uchar chip_version;
10860 
10861 	iop_base = asc_dvc->iop_base;
10862 	warn_code = 0;
10863 	asc_dvc->err_code = 0;
10864 	if ((asc_dvc->bus_type &
10865 	     (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
10866 		asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
10867 	}
10868 	AscSetChipControl(iop_base, CC_HALT);
10869 	AscSetChipStatus(iop_base, 0);
10870 	asc_dvc->bug_fix_cntl = 0;
10871 	asc_dvc->pci_fix_asyn_xfer = 0;
10872 	asc_dvc->pci_fix_asyn_xfer_always = 0;
10873 	/* asc_dvc->init_state initalized in AscInitGetConfig(). */
10874 	asc_dvc->sdtr_done = 0;
10875 	asc_dvc->cur_total_qng = 0;
10876 	asc_dvc->is_in_int = 0;
10877 	asc_dvc->in_critical_cnt = 0;
10878 	asc_dvc->last_q_shortage = 0;
10879 	asc_dvc->use_tagged_qng = 0;
10880 	asc_dvc->no_scam = 0;
10881 	asc_dvc->unit_not_ready = 0;
10882 	asc_dvc->queue_full_or_busy = 0;
10883 	asc_dvc->redo_scam = 0;
10884 	asc_dvc->res2 = 0;
10885 	asc_dvc->host_init_sdtr_index = 0;
10886 	asc_dvc->cfg->can_tagged_qng = 0;
10887 	asc_dvc->cfg->cmd_qng_enabled = 0;
10888 	asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
10889 	asc_dvc->init_sdtr = 0;
10890 	asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
10891 	asc_dvc->scsi_reset_wait = 3;
10892 	asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
10893 	asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
10894 	asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
10895 	asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
10896 	asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
10897 	asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
10898 	asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
10899 	    ASC_LIB_VERSION_MINOR;
10900 	chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
10901 	asc_dvc->cfg->chip_version = chip_version;
10902 	asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
10903 	asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
10904 	asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
10905 	asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
10906 	asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
10907 	asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
10908 	asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
10909 	asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
10910 	asc_dvc->max_sdtr_index = 7;
10911 	if ((asc_dvc->bus_type & ASC_IS_PCI) &&
10912 	    (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
10913 		asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
10914 		asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
10915 		asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
10916 		asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
10917 		asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
10918 		asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
10919 		asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
10920 		asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
10921 		asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
10922 		asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
10923 		asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
10924 		asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
10925 		asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
10926 		asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
10927 		asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
10928 		asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
10929 		asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
10930 		asc_dvc->max_sdtr_index = 15;
10931 		if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
10932 			AscSetExtraControl(iop_base,
10933 					   (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10934 		} else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
10935 			AscSetExtraControl(iop_base,
10936 					   (SEC_ACTIVE_NEGATE |
10937 					    SEC_ENABLE_FILTER));
10938 		}
10939 	}
10940 	if (asc_dvc->bus_type == ASC_IS_PCI) {
10941 		AscSetExtraControl(iop_base,
10942 				   (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10943 	}
10944 
10945 	asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
10946 	if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
10947 		AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
10948 		asc_dvc->bus_type = ASC_IS_ISAPNP;
10949 	}
10950 #ifdef CONFIG_ISA
10951 	if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
10952 		asc_dvc->cfg->isa_dma_channel =
10953 		    (uchar)AscGetIsaDmaChannel(iop_base);
10954 	}
10955 #endif /* CONFIG_ISA */
10956 	for (i = 0; i <= ASC_MAX_TID; i++) {
10957 		asc_dvc->cur_dvc_qng[i] = 0;
10958 		asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
10959 		asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
10960 		asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
10961 		asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
10962 	}
10963 	return (warn_code);
10964 }
10965 
10966 static ushort __init AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
10967 {
10968 	ASCEEP_CONFIG eep_config_buf;
10969 	ASCEEP_CONFIG *eep_config;
10970 	PortAddr iop_base;
10971 	ushort chksum;
10972 	ushort warn_code;
10973 	ushort cfg_msw, cfg_lsw;
10974 	int i;
10975 	int write_eep = 0;
10976 
10977 	iop_base = asc_dvc->iop_base;
10978 	warn_code = 0;
10979 	AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
10980 	AscStopQueueExe(iop_base);
10981 	if ((AscStopChip(iop_base) == FALSE) ||
10982 	    (AscGetChipScsiCtrl(iop_base) != 0)) {
10983 		asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
10984 		AscResetChipAndScsiBus(asc_dvc);
10985 		DvcSleepMilliSecond((ASC_DCNT)
10986 				    ((ushort)asc_dvc->scsi_reset_wait * 1000));
10987 	}
10988 	if (AscIsChipHalted(iop_base) == FALSE) {
10989 		asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10990 		return (warn_code);
10991 	}
10992 	AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10993 	if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10994 		asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10995 		return (warn_code);
10996 	}
10997 	eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
10998 	cfg_msw = AscGetChipCfgMsw(iop_base);
10999 	cfg_lsw = AscGetChipCfgLsw(iop_base);
11000 	if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
11001 		cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
11002 		warn_code |= ASC_WARN_CFG_MSW_RECOVER;
11003 		AscSetChipCfgMsw(iop_base, cfg_msw);
11004 	}
11005 	chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
11006 	ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
11007 	if (chksum == 0) {
11008 		chksum = 0xaa55;
11009 	}
11010 	if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
11011 		warn_code |= ASC_WARN_AUTO_CONFIG;
11012 		if (asc_dvc->cfg->chip_version == 3) {
11013 			if (eep_config->cfg_lsw != cfg_lsw) {
11014 				warn_code |= ASC_WARN_EEPROM_RECOVER;
11015 				eep_config->cfg_lsw =
11016 				    AscGetChipCfgLsw(iop_base);
11017 			}
11018 			if (eep_config->cfg_msw != cfg_msw) {
11019 				warn_code |= ASC_WARN_EEPROM_RECOVER;
11020 				eep_config->cfg_msw =
11021 				    AscGetChipCfgMsw(iop_base);
11022 			}
11023 		}
11024 	}
11025 	eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
11026 	eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
11027 	ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
11028 		 eep_config->chksum);
11029 	if (chksum != eep_config->chksum) {
11030 		if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
11031 		    ASC_CHIP_VER_PCI_ULTRA_3050) {
11032 			ASC_DBG(1,
11033 				"AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
11034 			eep_config->init_sdtr = 0xFF;
11035 			eep_config->disc_enable = 0xFF;
11036 			eep_config->start_motor = 0xFF;
11037 			eep_config->use_cmd_qng = 0;
11038 			eep_config->max_total_qng = 0xF0;
11039 			eep_config->max_tag_qng = 0x20;
11040 			eep_config->cntl = 0xBFFF;
11041 			ASC_EEP_SET_CHIP_ID(eep_config, 7);
11042 			eep_config->no_scam = 0;
11043 			eep_config->adapter_info[0] = 0;
11044 			eep_config->adapter_info[1] = 0;
11045 			eep_config->adapter_info[2] = 0;
11046 			eep_config->adapter_info[3] = 0;
11047 			eep_config->adapter_info[4] = 0;
11048 			/* Indicate EEPROM-less board. */
11049 			eep_config->adapter_info[5] = 0xBB;
11050 		} else {
11051 			ASC_PRINT
11052 			    ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
11053 			write_eep = 1;
11054 			warn_code |= ASC_WARN_EEPROM_CHKSUM;
11055 		}
11056 	}
11057 	asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
11058 	asc_dvc->cfg->disc_enable = eep_config->disc_enable;
11059 	asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
11060 	asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
11061 	asc_dvc->start_motor = eep_config->start_motor;
11062 	asc_dvc->dvc_cntl = eep_config->cntl;
11063 	asc_dvc->no_scam = eep_config->no_scam;
11064 	asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
11065 	asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
11066 	asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
11067 	asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
11068 	asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
11069 	asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
11070 	if (!AscTestExternalLram(asc_dvc)) {
11071 		if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
11072 		     ASC_IS_PCI_ULTRA)) {
11073 			eep_config->max_total_qng =
11074 			    ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
11075 			eep_config->max_tag_qng =
11076 			    ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
11077 		} else {
11078 			eep_config->cfg_msw |= 0x0800;
11079 			cfg_msw |= 0x0800;
11080 			AscSetChipCfgMsw(iop_base, cfg_msw);
11081 			eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
11082 			eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
11083 		}
11084 	} else {
11085 	}
11086 	if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
11087 		eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
11088 	}
11089 	if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
11090 		eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
11091 	}
11092 	if (eep_config->max_tag_qng > eep_config->max_total_qng) {
11093 		eep_config->max_tag_qng = eep_config->max_total_qng;
11094 	}
11095 	if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
11096 		eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
11097 	}
11098 	asc_dvc->max_total_qng = eep_config->max_total_qng;
11099 	if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
11100 	    eep_config->use_cmd_qng) {
11101 		eep_config->disc_enable = eep_config->use_cmd_qng;
11102 		warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
11103 	}
11104 	if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
11105 		asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
11106 	}
11107 	ASC_EEP_SET_CHIP_ID(eep_config,
11108 			    ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
11109 	asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
11110 	if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
11111 	    !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
11112 		asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
11113 	}
11114 
11115 	for (i = 0; i <= ASC_MAX_TID; i++) {
11116 		asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
11117 		asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
11118 		asc_dvc->cfg->sdtr_period_offset[i] =
11119 		    (uchar)(ASC_DEF_SDTR_OFFSET |
11120 			    (asc_dvc->host_init_sdtr_index << 4));
11121 	}
11122 	eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
11123 	if (write_eep) {
11124 		if ((i =
11125 		     AscSetEEPConfig(iop_base, eep_config,
11126 				     asc_dvc->bus_type)) != 0) {
11127 			ASC_PRINT1
11128 			    ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
11129 			     i);
11130 		} else {
11131 			ASC_PRINT
11132 			    ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
11133 		}
11134 	}
11135 	return (warn_code);
11136 }
11137 
11138 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
11139 {
11140 	int i;
11141 	ushort warn_code;
11142 	PortAddr iop_base;
11143 	ASC_PADDR phy_addr;
11144 	ASC_DCNT phy_size;
11145 
11146 	iop_base = asc_dvc->iop_base;
11147 	warn_code = 0;
11148 	for (i = 0; i <= ASC_MAX_TID; i++) {
11149 		AscPutMCodeInitSDTRAtID(iop_base, i,
11150 					asc_dvc->cfg->sdtr_period_offset[i]
11151 		    );
11152 	}
11153 
11154 	AscInitQLinkVar(asc_dvc);
11155 	AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
11156 			 asc_dvc->cfg->disc_enable);
11157 	AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
11158 			 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
11159 
11160 	/* Align overrun buffer on an 8 byte boundary. */
11161 	phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
11162 	phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
11163 	AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
11164 				 (uchar *)&phy_addr, 1);
11165 	phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
11166 	AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
11167 				 (uchar *)&phy_size, 1);
11168 
11169 	asc_dvc->cfg->mcode_date =
11170 	    AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
11171 	asc_dvc->cfg->mcode_version =
11172 	    AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
11173 
11174 	AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
11175 	if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
11176 		asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
11177 		return (warn_code);
11178 	}
11179 	if (AscStartChip(iop_base) != 1) {
11180 		asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
11181 		return (warn_code);
11182 	}
11183 
11184 	return (warn_code);
11185 }
11186 
11187 static int __init AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
11188 {
11189 	PortAddr iop_base;
11190 	ushort q_addr;
11191 	ushort saved_word;
11192 	int sta;
11193 
11194 	iop_base = asc_dvc->iop_base;
11195 	sta = 0;
11196 	q_addr = ASC_QNO_TO_QADDR(241);
11197 	saved_word = AscReadLramWord(iop_base, q_addr);
11198 	AscSetChipLramAddr(iop_base, q_addr);
11199 	AscSetChipLramData(iop_base, 0x55AA);
11200 	DvcSleepMilliSecond(10);
11201 	AscSetChipLramAddr(iop_base, q_addr);
11202 	if (AscGetChipLramData(iop_base) == 0x55AA) {
11203 		sta = 1;
11204 		AscWriteLramWord(iop_base, q_addr, saved_word);
11205 	}
11206 	return (sta);
11207 }
11208 
11209 static int __init AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
11210 {
11211 	uchar read_back;
11212 	int retry;
11213 
11214 	retry = 0;
11215 	while (TRUE) {
11216 		AscSetChipEEPCmd(iop_base, cmd_reg);
11217 		DvcSleepMilliSecond(1);
11218 		read_back = AscGetChipEEPCmd(iop_base);
11219 		if (read_back == cmd_reg) {
11220 			return (1);
11221 		}
11222 		if (retry++ > ASC_EEP_MAX_RETRY) {
11223 			return (0);
11224 		}
11225 	}
11226 }
11227 
11228 static int __init AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
11229 {
11230 	ushort read_back;
11231 	int retry;
11232 
11233 	retry = 0;
11234 	while (TRUE) {
11235 		AscSetChipEEPData(iop_base, data_reg);
11236 		DvcSleepMilliSecond(1);
11237 		read_back = AscGetChipEEPData(iop_base);
11238 		if (read_back == data_reg) {
11239 			return (1);
11240 		}
11241 		if (retry++ > ASC_EEP_MAX_RETRY) {
11242 			return (0);
11243 		}
11244 	}
11245 }
11246 
11247 static void __init AscWaitEEPRead(void)
11248 {
11249 	DvcSleepMilliSecond(1);
11250 	return;
11251 }
11252 
11253 static void __init AscWaitEEPWrite(void)
11254 {
11255 	DvcSleepMilliSecond(20);
11256 	return;
11257 }
11258 
11259 static ushort __init AscReadEEPWord(PortAddr iop_base, uchar addr)
11260 {
11261 	ushort read_wval;
11262 	uchar cmd_reg;
11263 
11264 	AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11265 	AscWaitEEPRead();
11266 	cmd_reg = addr | ASC_EEP_CMD_READ;
11267 	AscWriteEEPCmdReg(iop_base, cmd_reg);
11268 	AscWaitEEPRead();
11269 	read_wval = AscGetChipEEPData(iop_base);
11270 	AscWaitEEPRead();
11271 	return (read_wval);
11272 }
11273 
11274 static ushort __init
11275 AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
11276 {
11277 	ushort read_wval;
11278 
11279 	read_wval = AscReadEEPWord(iop_base, addr);
11280 	if (read_wval != word_val) {
11281 		AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
11282 		AscWaitEEPRead();
11283 		AscWriteEEPDataReg(iop_base, word_val);
11284 		AscWaitEEPRead();
11285 		AscWriteEEPCmdReg(iop_base,
11286 				  (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
11287 		AscWaitEEPWrite();
11288 		AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11289 		AscWaitEEPRead();
11290 		return (AscReadEEPWord(iop_base, addr));
11291 	}
11292 	return (read_wval);
11293 }
11294 
11295 static ushort __init
11296 AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11297 {
11298 	ushort wval;
11299 	ushort sum;
11300 	ushort *wbuf;
11301 	int cfg_beg;
11302 	int cfg_end;
11303 	int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11304 	int s_addr;
11305 
11306 	wbuf = (ushort *)cfg_buf;
11307 	sum = 0;
11308 	/* Read two config words; Byte-swapping done by AscReadEEPWord(). */
11309 	for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11310 		*wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11311 		sum += *wbuf;
11312 	}
11313 	if (bus_type & ASC_IS_VL) {
11314 		cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11315 		cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11316 	} else {
11317 		cfg_beg = ASC_EEP_DVC_CFG_BEG;
11318 		cfg_end = ASC_EEP_MAX_DVC_ADDR;
11319 	}
11320 	for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11321 		wval = AscReadEEPWord(iop_base, (uchar)s_addr);
11322 		if (s_addr <= uchar_end_in_config) {
11323 			/*
11324 			 * Swap all char fields - must unswap bytes already swapped
11325 			 * by AscReadEEPWord().
11326 			 */
11327 			*wbuf = le16_to_cpu(wval);
11328 		} else {
11329 			/* Don't swap word field at the end - cntl field. */
11330 			*wbuf = wval;
11331 		}
11332 		sum += wval;	/* Checksum treats all EEPROM data as words. */
11333 	}
11334 	/*
11335 	 * Read the checksum word which will be compared against 'sum'
11336 	 * by the caller. Word field already swapped.
11337 	 */
11338 	*wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11339 	return (sum);
11340 }
11341 
11342 static int __init
11343 AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11344 {
11345 	int n_error;
11346 	ushort *wbuf;
11347 	ushort word;
11348 	ushort sum;
11349 	int s_addr;
11350 	int cfg_beg;
11351 	int cfg_end;
11352 	int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11353 
11354 	wbuf = (ushort *)cfg_buf;
11355 	n_error = 0;
11356 	sum = 0;
11357 	/* Write two config words; AscWriteEEPWord() will swap bytes. */
11358 	for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11359 		sum += *wbuf;
11360 		if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11361 			n_error++;
11362 		}
11363 	}
11364 	if (bus_type & ASC_IS_VL) {
11365 		cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11366 		cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11367 	} else {
11368 		cfg_beg = ASC_EEP_DVC_CFG_BEG;
11369 		cfg_end = ASC_EEP_MAX_DVC_ADDR;
11370 	}
11371 	for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11372 		if (s_addr <= uchar_end_in_config) {
11373 			/*
11374 			 * This is a char field. Swap char fields before they are
11375 			 * swapped again by AscWriteEEPWord().
11376 			 */
11377 			word = cpu_to_le16(*wbuf);
11378 			if (word !=
11379 			    AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
11380 				n_error++;
11381 			}
11382 		} else {
11383 			/* Don't swap word field at the end - cntl field. */
11384 			if (*wbuf !=
11385 			    AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11386 				n_error++;
11387 			}
11388 		}
11389 		sum += *wbuf;	/* Checksum calculated from word values. */
11390 	}
11391 	/* Write checksum word. It will be swapped by AscWriteEEPWord(). */
11392 	*wbuf = sum;
11393 	if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
11394 		n_error++;
11395 	}
11396 
11397 	/* Read EEPROM back again. */
11398 	wbuf = (ushort *)cfg_buf;
11399 	/*
11400 	 * Read two config words; Byte-swapping done by AscReadEEPWord().
11401 	 */
11402 	for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11403 		if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
11404 			n_error++;
11405 		}
11406 	}
11407 	if (bus_type & ASC_IS_VL) {
11408 		cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11409 		cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11410 	} else {
11411 		cfg_beg = ASC_EEP_DVC_CFG_BEG;
11412 		cfg_end = ASC_EEP_MAX_DVC_ADDR;
11413 	}
11414 	for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11415 		if (s_addr <= uchar_end_in_config) {
11416 			/*
11417 			 * Swap all char fields. Must unswap bytes already swapped
11418 			 * by AscReadEEPWord().
11419 			 */
11420 			word =
11421 			    le16_to_cpu(AscReadEEPWord
11422 					(iop_base, (uchar)s_addr));
11423 		} else {
11424 			/* Don't swap word field at the end - cntl field. */
11425 			word = AscReadEEPWord(iop_base, (uchar)s_addr);
11426 		}
11427 		if (*wbuf != word) {
11428 			n_error++;
11429 		}
11430 	}
11431 	/* Read checksum; Byte swapping not needed. */
11432 	if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
11433 		n_error++;
11434 	}
11435 	return (n_error);
11436 }
11437 
11438 static int __init
11439 AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11440 {
11441 	int retry;
11442 	int n_error;
11443 
11444 	retry = 0;
11445 	while (TRUE) {
11446 		if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
11447 						   bus_type)) == 0) {
11448 			break;
11449 		}
11450 		if (++retry > ASC_EEP_MAX_RETRY) {
11451 			break;
11452 		}
11453 	}
11454 	return (n_error);
11455 }
11456 
11457 static void
11458 AscAsyncFix(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq)
11459 {
11460 	uchar dvc_type;
11461 	ASC_SCSI_BIT_ID_TYPE tid_bits;
11462 
11463 	dvc_type = ASC_INQ_DVC_TYPE(inq);
11464 	tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
11465 
11466 	if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
11467 		if (!(asc_dvc->init_sdtr & tid_bits)) {
11468 			if ((dvc_type == TYPE_ROM) &&
11469 			    (AscCompareString((uchar *)inq->vendor_id,
11470 					      (uchar *)"HP ", 3) == 0)) {
11471 				asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
11472 			}
11473 			asc_dvc->pci_fix_asyn_xfer |= tid_bits;
11474 			if ((dvc_type == TYPE_PROCESSOR) ||
11475 			    (dvc_type == TYPE_SCANNER) ||
11476 			    (dvc_type == TYPE_ROM) || (dvc_type == TYPE_TAPE)) {
11477 				asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
11478 			}
11479 
11480 			if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
11481 				AscSetRunChipSynRegAtID(asc_dvc->iop_base,
11482 							tid_no,
11483 							ASYN_SDTR_DATA_FIX_PCI_REV_AB);
11484 			}
11485 		}
11486 	}
11487 	return;
11488 }
11489 
11490 static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
11491 {
11492 	if ((inq->add_len >= 32) &&
11493 	    (AscCompareString((uchar *)inq->vendor_id,
11494 			      (uchar *)"QUANTUM XP34301", 15) == 0) &&
11495 	    (AscCompareString((uchar *)inq->product_rev_level,
11496 			      (uchar *)"1071", 4) == 0)) {
11497 		return 0;
11498 	}
11499 	return 1;
11500 }
11501 
11502 static void
11503 AscInquiryHandling(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq)
11504 {
11505 	ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
11506 	ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
11507 
11508 	orig_init_sdtr = asc_dvc->init_sdtr;
11509 	orig_use_tagged_qng = asc_dvc->use_tagged_qng;
11510 
11511 	asc_dvc->init_sdtr &= ~tid_bit;
11512 	asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
11513 	asc_dvc->use_tagged_qng &= ~tid_bit;
11514 
11515 	if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) {
11516 		if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) {
11517 			asc_dvc->init_sdtr |= tid_bit;
11518 		}
11519 		if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) &&
11520 		    ASC_INQ_CMD_QUEUE(inq)) {
11521 			if (AscTagQueuingSafe(inq)) {
11522 				asc_dvc->use_tagged_qng |= tid_bit;
11523 				asc_dvc->cfg->can_tagged_qng |= tid_bit;
11524 			}
11525 		}
11526 	}
11527 	if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
11528 		AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
11529 				 asc_dvc->cfg->disc_enable);
11530 		AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
11531 				 asc_dvc->use_tagged_qng);
11532 		AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
11533 				 asc_dvc->cfg->can_tagged_qng);
11534 
11535 		asc_dvc->max_dvc_qng[tid_no] =
11536 		    asc_dvc->cfg->max_tag_qng[tid_no];
11537 		AscWriteLramByte(asc_dvc->iop_base,
11538 				 (ushort)(ASCV_MAX_DVC_QNG_BEG + tid_no),
11539 				 asc_dvc->max_dvc_qng[tid_no]);
11540 	}
11541 	if (orig_init_sdtr != asc_dvc->init_sdtr) {
11542 		AscAsyncFix(asc_dvc, tid_no, inq);
11543 	}
11544 	return;
11545 }
11546 
11547 static int AscCompareString(uchar *str1, uchar *str2, int len)
11548 {
11549 	int i;
11550 	int diff;
11551 
11552 	for (i = 0; i < len; i++) {
11553 		diff = (int)(str1[i] - str2[i]);
11554 		if (diff != 0)
11555 			return (diff);
11556 	}
11557 	return (0);
11558 }
11559 
11560 static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
11561 {
11562 	uchar byte_data;
11563 	ushort word_data;
11564 
11565 	if (isodd_word(addr)) {
11566 		AscSetChipLramAddr(iop_base, addr - 1);
11567 		word_data = AscGetChipLramData(iop_base);
11568 		byte_data = (uchar)((word_data >> 8) & 0xFF);
11569 	} else {
11570 		AscSetChipLramAddr(iop_base, addr);
11571 		word_data = AscGetChipLramData(iop_base);
11572 		byte_data = (uchar)(word_data & 0xFF);
11573 	}
11574 	return (byte_data);
11575 }
11576 
11577 static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
11578 {
11579 	ushort word_data;
11580 
11581 	AscSetChipLramAddr(iop_base, addr);
11582 	word_data = AscGetChipLramData(iop_base);
11583 	return (word_data);
11584 }
11585 
11586 #if CC_VERY_LONG_SG_LIST
11587 static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
11588 {
11589 	ushort val_low, val_high;
11590 	ASC_DCNT dword_data;
11591 
11592 	AscSetChipLramAddr(iop_base, addr);
11593 	val_low = AscGetChipLramData(iop_base);
11594 	val_high = AscGetChipLramData(iop_base);
11595 	dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
11596 	return (dword_data);
11597 }
11598 #endif /* CC_VERY_LONG_SG_LIST */
11599 
11600 static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
11601 {
11602 	AscSetChipLramAddr(iop_base, addr);
11603 	AscSetChipLramData(iop_base, word_val);
11604 	return;
11605 }
11606 
11607 static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
11608 {
11609 	ushort word_data;
11610 
11611 	if (isodd_word(addr)) {
11612 		addr--;
11613 		word_data = AscReadLramWord(iop_base, addr);
11614 		word_data &= 0x00FF;
11615 		word_data |= (((ushort)byte_val << 8) & 0xFF00);
11616 	} else {
11617 		word_data = AscReadLramWord(iop_base, addr);
11618 		word_data &= 0xFF00;
11619 		word_data |= ((ushort)byte_val & 0x00FF);
11620 	}
11621 	AscWriteLramWord(iop_base, addr, word_data);
11622 	return;
11623 }
11624 
11625 /*
11626  * Copy 2 bytes to LRAM.
11627  *
11628  * The source data is assumed to be in little-endian order in memory
11629  * and is maintained in little-endian order when written to LRAM.
11630  */
11631 static void
11632 AscMemWordCopyPtrToLram(PortAddr iop_base,
11633 			ushort s_addr, uchar *s_buffer, int words)
11634 {
11635 	int i;
11636 
11637 	AscSetChipLramAddr(iop_base, s_addr);
11638 	for (i = 0; i < 2 * words; i += 2) {
11639 		/*
11640 		 * On a little-endian system the second argument below
11641 		 * produces a little-endian ushort which is written to
11642 		 * LRAM in little-endian order. On a big-endian system
11643 		 * the second argument produces a big-endian ushort which
11644 		 * is "transparently" byte-swapped by outpw() and written
11645 		 * in little-endian order to LRAM.
11646 		 */
11647 		outpw(iop_base + IOP_RAM_DATA,
11648 		      ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
11649 	}
11650 	return;
11651 }
11652 
11653 /*
11654  * Copy 4 bytes to LRAM.
11655  *
11656  * The source data is assumed to be in little-endian order in memory
11657  * and is maintained in little-endian order when writen to LRAM.
11658  */
11659 static void
11660 AscMemDWordCopyPtrToLram(PortAddr iop_base,
11661 			 ushort s_addr, uchar *s_buffer, int dwords)
11662 {
11663 	int i;
11664 
11665 	AscSetChipLramAddr(iop_base, s_addr);
11666 	for (i = 0; i < 4 * dwords; i += 4) {
11667 		outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);	/* LSW */
11668 		outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]);	/* MSW */
11669 	}
11670 	return;
11671 }
11672 
11673 /*
11674  * Copy 2 bytes from LRAM.
11675  *
11676  * The source data is assumed to be in little-endian order in LRAM
11677  * and is maintained in little-endian order when written to memory.
11678  */
11679 static void
11680 AscMemWordCopyPtrFromLram(PortAddr iop_base,
11681 			  ushort s_addr, uchar *d_buffer, int words)
11682 {
11683 	int i;
11684 	ushort word;
11685 
11686 	AscSetChipLramAddr(iop_base, s_addr);
11687 	for (i = 0; i < 2 * words; i += 2) {
11688 		word = inpw(iop_base + IOP_RAM_DATA);
11689 		d_buffer[i] = word & 0xff;
11690 		d_buffer[i + 1] = (word >> 8) & 0xff;
11691 	}
11692 	return;
11693 }
11694 
11695 static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
11696 {
11697 	ASC_DCNT sum;
11698 	int i;
11699 
11700 	sum = 0L;
11701 	for (i = 0; i < words; i++, s_addr += 2) {
11702 		sum += AscReadLramWord(iop_base, s_addr);
11703 	}
11704 	return (sum);
11705 }
11706 
11707 static void
11708 AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
11709 {
11710 	int i;
11711 
11712 	AscSetChipLramAddr(iop_base, s_addr);
11713 	for (i = 0; i < words; i++) {
11714 		AscSetChipLramData(iop_base, set_wval);
11715 	}
11716 	return;
11717 }
11718 
11719 /*
11720  * --- Adv Library Functions
11721  */
11722 
11723 /* a_mcode.h */
11724 
11725 /* Microcode buffer is kept after initialization for error recovery. */
11726 static unsigned char _adv_asc3550_buf[] = {
11727 	0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
11728 	0x01, 0x00, 0x48, 0xe4,
11729 	0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff,
11730 	0x28, 0x0e, 0x9e, 0xe7,
11731 	0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7,
11732 	0x55, 0xf0, 0x01, 0xf6,
11733 	0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
11734 	0x00, 0xec, 0x85, 0xf0,
11735 	0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0,
11736 	0x86, 0xf0, 0xb4, 0x00,
11737 	0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00,
11738 	0xaa, 0x18, 0x02, 0x80,
11739 	0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
11740 	0x00, 0x57, 0x01, 0xea,
11741 	0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80,
11742 	0x03, 0xe6, 0xb6, 0x00,
11743 	0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12,
11744 	0x02, 0x4a, 0xb9, 0x54,
11745 	0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
11746 	0x3e, 0x00, 0x80, 0x00,
11747 	0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
11748 	0x74, 0x01, 0x76, 0x01,
11749 	0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13,
11750 	0x4c, 0x1c, 0xbb, 0x55,
11751 	0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
11752 	0x03, 0xf7, 0x06, 0xf7,
11753 	0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08,
11754 	0x30, 0x13, 0x64, 0x15,
11755 	0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c,
11756 	0x04, 0xea, 0x5d, 0xf0,
11757 	0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
11758 	0xcc, 0x00, 0x20, 0x01,
11759 	0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13,
11760 	0x40, 0x13, 0x30, 0x1c,
11761 	0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
11762 	0x59, 0xf0, 0xa7, 0xf0,
11763 	0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
11764 	0xa4, 0x00, 0xb5, 0x00,
11765 	0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a,
11766 	0x14, 0x0e, 0x02, 0x10,
11767 	0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13,
11768 	0x10, 0x15, 0x14, 0x15,
11769 	0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
11770 	0x91, 0x44, 0x0a, 0x45,
11771 	0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58,
11772 	0x83, 0x59, 0x05, 0xe6,
11773 	0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8,
11774 	0x02, 0xfa, 0x03, 0xfa,
11775 	0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
11776 	0x9e, 0x00, 0xa8, 0x00,
11777 	0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01,
11778 	0x7a, 0x01, 0xc0, 0x01,
11779 	0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08,
11780 	0x69, 0x08, 0xba, 0x08,
11781 	0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
11782 	0xf1, 0x10, 0x06, 0x12,
11783 	0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14,
11784 	0x8a, 0x15, 0xc6, 0x17,
11785 	0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
11786 	0x0e, 0x47, 0x48, 0x47,
11787 	0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
11788 	0x14, 0x56, 0x77, 0x57,
11789 	0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c,
11790 	0xf0, 0x29, 0x02, 0xfe,
11791 	0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf,
11792 	0xfe, 0x80, 0x01, 0xff,
11793 	0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
11794 	0x00, 0xfe, 0x57, 0x24,
11795 	0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09,
11796 	0x00, 0x00, 0xff, 0x08,
11797 	0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
11798 	0xff, 0xff, 0xff, 0x0f,
11799 	0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
11800 	0xfe, 0x04, 0xf7, 0xcf,
11801 	0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67,
11802 	0x0b, 0x3c, 0x2a, 0xfe,
11803 	0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0,
11804 	0xfe, 0xf0, 0x01, 0xfe,
11805 	0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
11806 	0x02, 0xfe, 0xd4, 0x0c,
11807 	0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
11808 	0x1c, 0x05, 0xfe, 0xa6,
11809 	0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48,
11810 	0xf0, 0xfe, 0x86, 0x02,
11811 	0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
11812 	0xfe, 0x46, 0xf0, 0xfe,
11813 	0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
11814 	0x44, 0x02, 0xfe, 0x44,
11815 	0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b,
11816 	0xa0, 0x17, 0x06, 0x18,
11817 	0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
11818 	0x1e, 0x1c, 0xfe, 0xe9,
11819 	0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7,
11820 	0x0a, 0x6b, 0x01, 0x9e,
11821 	0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b,
11822 	0x01, 0x82, 0xfe, 0xbd,
11823 	0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
11824 	0x58, 0x1c, 0x17, 0x06,
11825 	0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21,
11826 	0xfe, 0x94, 0x02, 0xfe,
11827 	0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97,
11828 	0x01, 0xfe, 0x54, 0x0f,
11829 	0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
11830 	0x69, 0x10, 0x17, 0x06,
11831 	0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05,
11832 	0xf6, 0xc7, 0x01, 0xfe,
11833 	0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6,
11834 	0x02, 0x29, 0x0a, 0x40,
11835 	0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
11836 	0x58, 0x0a, 0x99, 0x01,
11837 	0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29,
11838 	0x2a, 0x46, 0xfe, 0x02,
11839 	0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc,
11840 	0x01, 0xfe, 0x07, 0x4b,
11841 	0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
11842 	0xfe, 0x56, 0x03, 0xfe,
11843 	0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10,
11844 	0xfe, 0x9f, 0xf0, 0xfe,
11845 	0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48,
11846 	0x1c, 0xeb, 0x09, 0x04,
11847 	0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
11848 	0x01, 0x0e, 0xac, 0x75,
11849 	0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2,
11850 	0xfe, 0x82, 0xf0, 0xfe,
11851 	0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25,
11852 	0x32, 0x1f, 0xfe, 0xb4,
11853 	0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
11854 	0x0a, 0xf0, 0xfe, 0x7a,
11855 	0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c,
11856 	0x01, 0x33, 0x8f, 0xfe,
11857 	0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8,
11858 	0xf7, 0xfe, 0x48, 0x1c,
11859 	0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
11860 	0x0a, 0xca, 0x01, 0x0e,
11861 	0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14,
11862 	0x2c, 0x01, 0x33, 0x8f,
11863 	0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65,
11864 	0xfe, 0x3c, 0x04, 0x1f,
11865 	0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
11866 	0x12, 0x2b, 0xff, 0x02,
11867 	0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f,
11868 	0x22, 0x30, 0x2e, 0xd5,
11869 	0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c,
11870 	0xfe, 0x4c, 0x54, 0x64,
11871 	0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
11872 	0xfe, 0x2a, 0x13, 0x2f,
11873 	0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
11874 	0xd3, 0xfa, 0xef, 0x86,
11875 	0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04,
11876 	0x1d, 0xfe, 0x1c, 0x12,
11877 	0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
11878 	0x70, 0x0c, 0x02, 0x22,
11879 	0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92,
11880 	0x01, 0x33, 0x02, 0x29,
11881 	0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87,
11882 	0x80, 0xfe, 0x31, 0xe4,
11883 	0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
11884 	0xfe, 0x70, 0x12, 0x49,
11885 	0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe,
11886 	0x80, 0x05, 0xfe, 0x31,
11887 	0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00,
11888 	0x28, 0xfe, 0x42, 0x12,
11889 	0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
11890 	0x11, 0xfe, 0xe3, 0x00,
11891 	0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
11892 	0x64, 0x05, 0x83, 0x24,
11893 	0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe,
11894 	0x09, 0x48, 0x01, 0x08,
11895 	0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
11896 	0x86, 0x24, 0x06, 0x12,
11897 	0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47,
11898 	0x01, 0xa7, 0x14, 0x92,
11899 	0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c,
11900 	0x02, 0x22, 0x05, 0xfe,
11901 	0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
11902 	0x47, 0x01, 0xa7, 0x26,
11903 	0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f,
11904 	0x01, 0xfe, 0xaa, 0x14,
11905 	0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00,
11906 	0x05, 0x50, 0xb4, 0x0c,
11907 	0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
11908 	0x13, 0x01, 0xfe, 0x14,
11909 	0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c,
11910 	0xff, 0x02, 0x00, 0x57,
11911 	0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe,
11912 	0x72, 0x06, 0x49, 0x04,
11913 	0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
11914 	0x06, 0x11, 0x9a, 0x01,
11915 	0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06,
11916 	0x01, 0xa7, 0xec, 0x72,
11917 	0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32,
11918 	0xfe, 0x0a, 0xf0, 0xfe,
11919 	0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
11920 	0x8d, 0x81, 0x02, 0x22,
11921 	0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00,
11922 	0x01, 0x08, 0x15, 0x00,
11923 	0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15,
11924 	0x00, 0x02, 0xfe, 0x32,
11925 	0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
11926 	0xfe, 0x1b, 0x00, 0x01,
11927 	0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
11928 	0x08, 0x15, 0x06, 0x01,
11929 	0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe,
11930 	0x9a, 0x81, 0x4b, 0x1d,
11931 	0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
11932 	0x45, 0xfe, 0x32, 0x12,
11933 	0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0,
11934 	0xfe, 0x32, 0x07, 0x8d,
11935 	0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a,
11936 	0x06, 0x15, 0x19, 0x02,
11937 	0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
11938 	0x90, 0x77, 0xfe, 0xca,
11939 	0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07,
11940 	0x10, 0xfe, 0x0e, 0x12,
11941 	0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe,
11942 	0x83, 0xe7, 0xc4, 0xa1,
11943 	0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
11944 	0x40, 0x12, 0x58, 0x01,
11945 	0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6,
11946 	0x51, 0x83, 0xfb, 0xfe,
11947 	0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90,
11948 	0xfe, 0x40, 0x50, 0xfe,
11949 	0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
11950 	0xfe, 0x2a, 0x12, 0xfe,
11951 	0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f,
11952 	0x85, 0x01, 0xa8, 0xfe,
11953 	0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56,
11954 	0x18, 0x57, 0xfb, 0xfe,
11955 	0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
11956 	0x0c, 0x39, 0x18, 0x3a,
11957 	0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e,
11958 	0x11, 0x65, 0xfe, 0x48,
11959 	0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73,
11960 	0xdd, 0xb8, 0xfe, 0x80,
11961 	0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
11962 	0xfe, 0x7a, 0x08, 0x8d,
11963 	0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9,
11964 	0x10, 0x61, 0x04, 0x06,
11965 	0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68,
11966 	0x12, 0xfe, 0x2e, 0x1c,
11967 	0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
11968 	0x52, 0x12, 0xfe, 0x2c,
11969 	0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe,
11970 	0x08, 0xfe, 0x8a, 0x10,
11971 	0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe,
11972 	0x24, 0x0a, 0xab, 0xfe,
11973 	0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
11974 	0x1c, 0x12, 0xb5, 0xfe,
11975 	0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb,
11976 	0x1c, 0x06, 0x16, 0x9d,
11977 	0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b,
11978 	0x14, 0x92, 0x01, 0x33,
11979 	0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
11980 	0xfe, 0x74, 0x18, 0x1c,
11981 	0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b,
11982 	0x01, 0xe6, 0x1e, 0x27,
11983 	0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a,
11984 	0x09, 0x04, 0x6a, 0xfe,
11985 	0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
11986 	0xfe, 0x83, 0x80, 0xfe,
11987 	0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63,
11988 	0x27, 0xfe, 0x40, 0x59,
11989 	0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18,
11990 	0x7c, 0xbe, 0x54, 0xbf,
11991 	0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
11992 	0x79, 0x56, 0x68, 0x57,
11993 	0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5,
11994 	0xa2, 0x23, 0x0c, 0x7b,
11995 	0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19,
11996 	0x16, 0xd7, 0x79, 0x39,
11997 	0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
11998 	0xfe, 0x10, 0x58, 0xfe,
11999 	0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04,
12000 	0x19, 0x16, 0xd7, 0x09,
12001 	0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f,
12002 	0xfe, 0x10, 0x90, 0xfe,
12003 	0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
12004 	0x11, 0x9b, 0x09, 0x04,
12005 	0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08,
12006 	0xfe, 0x0c, 0x58, 0xfe,
12007 	0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04,
12008 	0x0b, 0xfe, 0x1a, 0x12,
12009 	0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
12010 	0x14, 0x7a, 0x01, 0x33,
12011 	0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39,
12012 	0xfe, 0xed, 0x19, 0xbf,
12013 	0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff,
12014 	0x34, 0xfe, 0x74, 0x10,
12015 	0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
12016 	0x84, 0x05, 0xcb, 0x1c,
12017 	0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1,
12018 	0xf0, 0xfe, 0xc4, 0x0a,
12019 	0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe,
12020 	0xce, 0xf0, 0xfe, 0xca,
12021 	0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
12022 	0x22, 0x00, 0x02, 0x5a,
12023 	0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a,
12024 	0xfe, 0xd0, 0xf0, 0xfe,
12025 	0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f,
12026 	0x4c, 0xfe, 0x10, 0x10,
12027 	0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
12028 	0x2a, 0x13, 0xfe, 0x4e,
12029 	0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1,
12030 	0x16, 0x32, 0x2a, 0x73,
12031 	0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25,
12032 	0x32, 0x8c, 0xfe, 0x48,
12033 	0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
12034 	0xdb, 0x10, 0x11, 0xfe,
12035 	0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0,
12036 	0x22, 0x30, 0x2e, 0xd8,
12037 	0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1,
12038 	0x45, 0x0f, 0xfe, 0x42,
12039 	0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
12040 	0x09, 0x04, 0x0b, 0xfe,
12041 	0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28,
12042 	0x00, 0x21, 0xfe, 0xa6,
12043 	0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00,
12044 	0xfe, 0xe2, 0x10, 0x01,
12045 	0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
12046 	0x01, 0x6f, 0x02, 0x29,
12047 	0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10,
12048 	0x01, 0x86, 0x3e, 0x0b,
12049 	0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3,
12050 	0x3e, 0x0b, 0x0f, 0xfe,
12051 	0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
12052 	0xe8, 0x59, 0x11, 0x2d,
12053 	0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09,
12054 	0x04, 0x0b, 0x84, 0x3e,
12055 	0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12,
12056 	0x09, 0x04, 0x1b, 0xfe,
12057 	0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
12058 	0x1c, 0x1c, 0xfe, 0x9d,
12059 	0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f,
12060 	0xfe, 0x15, 0x00, 0xfe,
12061 	0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10,
12062 	0x0f, 0xfe, 0x47, 0x00,
12063 	0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
12064 	0xab, 0x70, 0x05, 0x6b,
12065 	0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe,
12066 	0x1c, 0x42, 0x59, 0x01,
12067 	0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31,
12068 	0x00, 0x37, 0x97, 0x01,
12069 	0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
12070 	0x1d, 0xfe, 0xce, 0x45,
12071 	0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75,
12072 	0x57, 0x05, 0x51, 0xfe,
12073 	0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48,
12074 	0x46, 0x09, 0x04, 0x1d,
12075 	0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
12076 	0x99, 0x01, 0x0e, 0xfe,
12077 	0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51,
12078 	0xfe, 0xee, 0x14, 0xee,
12079 	0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad,
12080 	0x13, 0x02, 0x29, 0x1e,
12081 	0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
12082 	0xce, 0x1e, 0x2d, 0x47,
12083 	0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06,
12084 	0x12, 0x4d, 0x01, 0xfe,
12085 	0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe,
12086 	0xf0, 0x0d, 0xfe, 0x02,
12087 	0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
12088 	0xf6, 0xfe, 0x34, 0x01,
12089 	0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13,
12090 	0xaf, 0xfe, 0x02, 0xea,
12091 	0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c,
12092 	0x05, 0xfe, 0x38, 0x01,
12093 	0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
12094 	0x0c, 0xfe, 0x62, 0x01,
12095 	0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06,
12096 	0x03, 0x23, 0x03, 0x1e,
12097 	0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe,
12098 	0x71, 0x13, 0xfe, 0x24,
12099 	0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
12100 	0xdc, 0xfe, 0x73, 0x57,
12101 	0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe,
12102 	0x80, 0x5d, 0x03, 0xfe,
12103 	0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6,
12104 	0x75, 0x03, 0x09, 0x04,
12105 	0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
12106 	0xfe, 0x1e, 0x80, 0xe1,
12107 	0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e,
12108 	0x90, 0xa3, 0xfe, 0x3c,
12109 	0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82,
12110 	0x16, 0x2f, 0x07, 0x2d,
12111 	0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
12112 	0xe8, 0x11, 0xfe, 0xe9,
12113 	0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe,
12114 	0x1e, 0x1c, 0xfe, 0x14,
12115 	0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01,
12116 	0x09, 0x04, 0x4f, 0xfe,
12117 	0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
12118 	0x40, 0x12, 0x20, 0x63,
12119 	0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08,
12120 	0x1c, 0x05, 0xfe, 0xac,
12121 	0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05,
12122 	0xfe, 0xb0, 0x00, 0xfe,
12123 	0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
12124 	0x24, 0x69, 0x12, 0xc9,
12125 	0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe,
12126 	0x90, 0x4d, 0xfe, 0x91,
12127 	0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c,
12128 	0xfe, 0x90, 0x4d, 0xfe,
12129 	0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
12130 	0x46, 0x1e, 0x20, 0xed,
12131 	0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea,
12132 	0x70, 0xfe, 0x14, 0x1c,
12133 	0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee,
12134 	0xfe, 0x07, 0xe6, 0x1d,
12135 	0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
12136 	0xfa, 0xef, 0xfe, 0x42,
12137 	0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0,
12138 	0xfe, 0x36, 0x12, 0xf0,
12139 	0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
12140 	0x3d, 0x75, 0x07, 0x10,
12141 	0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
12142 	0x10, 0x07, 0x7e, 0x45,
12143 	0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74,
12144 	0xfe, 0x01, 0xec, 0x97,
12145 	0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76,
12146 	0x27, 0x01, 0xda, 0xfe,
12147 	0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
12148 	0xfe, 0x48, 0x12, 0x07,
12149 	0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16,
12150 	0xfe, 0x3e, 0x11, 0x07,
12151 	0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8,
12152 	0x11, 0x07, 0x19, 0xfe,
12153 	0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
12154 	0x01, 0x08, 0x8c, 0x43,
12155 	0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11,
12156 	0x7e, 0x02, 0x29, 0x2b,
12157 	0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe,
12158 	0xfc, 0x10, 0x09, 0x04,
12159 	0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
12160 	0xc6, 0x10, 0x1e, 0x58,
12161 	0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c,
12162 	0x54, 0x18, 0x55, 0x23,
12163 	0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01,
12164 	0xa5, 0xc0, 0x38, 0xc1,
12165 	0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
12166 	0x05, 0xfa, 0x4e, 0xfe,
12167 	0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56,
12168 	0x0c, 0x56, 0x18, 0x57,
12169 	0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe,
12170 	0x00, 0x56, 0xfe, 0xa1,
12171 	0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
12172 	0x58, 0xfe, 0x1f, 0x40,
12173 	0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56,
12174 	0x31, 0x57, 0xfe, 0x44,
12175 	0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe,
12176 	0x8a, 0x50, 0x05, 0x39,
12177 	0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
12178 	0x12, 0xcd, 0x02, 0x5b,
12179 	0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44,
12180 	0x2f, 0x07, 0x9b, 0x21,
12181 	0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79,
12182 	0x39, 0x68, 0x3a, 0xfe,
12183 	0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
12184 	0x51, 0xfe, 0x8e, 0x51,
12185 	0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b,
12186 	0x01, 0x08, 0x25, 0x32,
12187 	0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b,
12188 	0x3b, 0x02, 0x44, 0x01,
12189 	0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
12190 	0x01, 0x08, 0x1f, 0xa2,
12191 	0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c,
12192 	0x00, 0x28, 0x84, 0x49,
12193 	0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06,
12194 	0x78, 0x3d, 0xfe, 0xda,
12195 	0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
12196 	0x05, 0xc6, 0x28, 0x84,
12197 	0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8,
12198 	0x14, 0xfe, 0x03, 0x17,
12199 	0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01,
12200 	0xfe, 0xaa, 0x14, 0x02,
12201 	0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
12202 	0x21, 0x44, 0x01, 0xfe,
12203 	0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87,
12204 	0xfe, 0x4a, 0xf4, 0x0b,
12205 	0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a,
12206 	0x85, 0x02, 0x5b, 0x05,
12207 	0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
12208 	0xd8, 0x14, 0x02, 0x5c,
12209 	0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1,
12210 	0x01, 0x08, 0x23, 0x72,
12211 	0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca,
12212 	0x12, 0x5e, 0x2b, 0x01,
12213 	0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
12214 	0x1c, 0xfe, 0xff, 0x7f,
12215 	0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00,
12216 	0x57, 0x48, 0x8b, 0x1c,
12217 	0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02,
12218 	0x00, 0x57, 0x48, 0x8b,
12219 	0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
12220 	0x03, 0x0a, 0x50, 0x01,
12221 	0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00,
12222 	0x54, 0xfe, 0x00, 0xf4,
12223 	0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe,
12224 	0x03, 0x7c, 0x63, 0x27,
12225 	0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
12226 	0xfe, 0x82, 0x4a, 0xfe,
12227 	0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe,
12228 	0x42, 0x48, 0x5f, 0x60,
12229 	0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08,
12230 	0x1f, 0xfe, 0xa2, 0x14,
12231 	0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
12232 	0xcc, 0x12, 0x49, 0x04,
12233 	0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe,
12234 	0xe8, 0x13, 0x3b, 0x13,
12235 	0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55,
12236 	0xa1, 0xff, 0x02, 0x83,
12237 	0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
12238 	0x13, 0x06, 0xfe, 0x56,
12239 	0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe,
12240 	0x64, 0x00, 0x17, 0x93,
12241 	0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe,
12242 	0xc8, 0x00, 0x8e, 0xe4,
12243 	0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
12244 	0x01, 0xba, 0xfe, 0x4e,
12245 	0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0,
12246 	0xfe, 0x60, 0x14, 0xfe,
12247 	0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01,
12248 	0xfe, 0x22, 0x13, 0x1c,
12249 	0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
12250 	0xfe, 0x9c, 0x14, 0xb7,
12251 	0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba,
12252 	0xfe, 0x9c, 0x14, 0xb7,
12253 	0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06,
12254 	0xfe, 0xb4, 0x56, 0xfe,
12255 	0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
12256 	0xe5, 0x15, 0x0b, 0x01,
12257 	0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89,
12258 	0x49, 0x01, 0x08, 0x03,
12259 	0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6,
12260 	0x15, 0x06, 0x01, 0x08,
12261 	0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
12262 	0x4a, 0x01, 0x08, 0x03,
12263 	0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc,
12264 	0xfe, 0x49, 0xf4, 0x00,
12265 	0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01,
12266 	0x08, 0x2f, 0x07, 0xfe,
12267 	0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
12268 	0x01, 0x43, 0x1e, 0xcd,
12269 	0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e,
12270 	0xed, 0x88, 0x07, 0x10,
12271 	0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a,
12272 	0x80, 0x01, 0x0e, 0x88,
12273 	0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
12274 	0x88, 0x03, 0x0a, 0x42,
12275 	0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e,
12276 	0xfe, 0x80, 0x80, 0xf2,
12277 	0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51,
12278 	0x01, 0x82, 0x03, 0x17,
12279 	0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
12280 	0xfe, 0x24, 0x1c, 0xfe,
12281 	0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0,
12282 	0x91, 0x1d, 0x66, 0xfe,
12283 	0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe,
12284 	0xda, 0x10, 0x17, 0x10,
12285 	0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
12286 	0x05, 0xfe, 0x66, 0x01,
12287 	0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06,
12288 	0xfe, 0x3c, 0x50, 0x66,
12289 	0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe,
12290 	0x40, 0x16, 0xfe, 0xb6,
12291 	0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
12292 	0x10, 0x71, 0xfe, 0x83,
12293 	0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90,
12294 	0xfe, 0x62, 0x16, 0xfe,
12295 	0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19,
12296 	0xfe, 0x98, 0xe7, 0x00,
12297 	0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
12298 	0xfe, 0x30, 0xbc, 0xfe,
12299 	0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
12300 	0xc5, 0x90, 0xfe, 0x9a,
12301 	0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe,
12302 	0x42, 0x10, 0xfe, 0x02,
12303 	0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
12304 	0xfe, 0x1d, 0xf7, 0x4f,
12305 	0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f,
12306 	0x47, 0xfe, 0x83, 0x58,
12307 	0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11,
12308 	0xfe, 0xdd, 0x00, 0x63,
12309 	0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
12310 	0x06, 0x37, 0x95, 0xa9,
12311 	0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e,
12312 	0x18, 0x1c, 0x1a, 0x5d,
12313 	0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe,
12314 	0xe1, 0x10, 0x78, 0x2c,
12315 	0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
12316 	0x13, 0x3c, 0x8a, 0x0a,
12317 	0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
12318 	0xe3, 0xfe, 0x00, 0xcc,
12319 	0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01,
12320 	0x0e, 0xf2, 0x01, 0x6f,
12321 	0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
12322 	0xf6, 0xfe, 0xd6, 0xf0,
12323 	0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe,
12324 	0x15, 0x00, 0x59, 0x76,
12325 	0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35,
12326 	0x11, 0x2d, 0x01, 0x6f,
12327 	0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
12328 	0xc8, 0xfe, 0x48, 0x55,
12329 	0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a,
12330 	0x99, 0x01, 0x0e, 0xf0,
12331 	0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73,
12332 	0x75, 0x03, 0x0a, 0x42,
12333 	0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
12334 	0x0e, 0x73, 0x75, 0x03,
12335 	0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00,
12336 	0xfe, 0x3a, 0x45, 0x5b,
12337 	0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00,
12338 	0xfe, 0x02, 0xe6, 0x1b,
12339 	0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
12340 	0xfe, 0x94, 0x00, 0xfe,
12341 	0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02,
12342 	0xe6, 0x2c, 0xfe, 0x4e,
12343 	0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69,
12344 	0x03, 0x07, 0x7a, 0xfe,
12345 	0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
12346 	0x07, 0x1b, 0xfe, 0x5a,
12347 	0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d,
12348 	0x24, 0x2c, 0xdc, 0x07,
12349 	0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d,
12350 	0x9f, 0xad, 0x03, 0x14,
12351 	0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
12352 	0x03, 0x25, 0xfe, 0xca,
12353 	0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a,
12354 	0x00, 0x00,
12355 };
12356 
12357 static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf);	/* 0x13AD */
12358 static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL;	/* Expanded little-endian checksum. */
12359 
12360 /* Microcode buffer is kept after initialization for error recovery. */
12361 static unsigned char _adv_asc38C0800_buf[] = {
12362 	0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
12363 	0x01, 0x00, 0x48, 0xe4,
12364 	0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff,
12365 	0x1c, 0x0f, 0x00, 0xf6,
12366 	0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6,
12367 	0x09, 0xe7, 0x55, 0xf0,
12368 	0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
12369 	0x18, 0xf4, 0x08, 0x00,
12370 	0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6,
12371 	0x86, 0xf0, 0xb1, 0xf0,
12372 	0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c,
12373 	0x3c, 0x00, 0xbb, 0x00,
12374 	0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
12375 	0xba, 0x13, 0x18, 0x40,
12376 	0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01,
12377 	0x6e, 0x01, 0x74, 0x01,
12378 	0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00,
12379 	0xc0, 0x00, 0x01, 0x01,
12380 	0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
12381 	0x08, 0x12, 0x02, 0x4a,
12382 	0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4,
12383 	0x5d, 0xf0, 0x02, 0xfa,
12384 	0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01,
12385 	0x68, 0x01, 0x6a, 0x01,
12386 	0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
12387 	0x06, 0x13, 0x4c, 0x1c,
12388 	0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00,
12389 	0x0f, 0x00, 0x47, 0x00,
12390 	0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c,
12391 	0x4e, 0x1c, 0x10, 0x44,
12392 	0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
12393 	0x05, 0x00, 0x34, 0x00,
12394 	0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b,
12395 	0x42, 0x0c, 0x12, 0x0f,
12396 	0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48,
12397 	0x00, 0x4e, 0x42, 0x54,
12398 	0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
12399 	0x59, 0xf0, 0xb8, 0xf0,
12400 	0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00,
12401 	0x19, 0x00, 0x33, 0x00,
12402 	0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00,
12403 	0xe7, 0x00, 0xe2, 0x03,
12404 	0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
12405 	0x12, 0x13, 0x24, 0x14,
12406 	0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c,
12407 	0x36, 0x1c, 0x08, 0x44,
12408 	0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54,
12409 	0x3a, 0x55, 0x83, 0x55,
12410 	0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
12411 	0x0c, 0xf0, 0x04, 0xf8,
12412 	0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00,
12413 	0xa8, 0x00, 0xaa, 0x00,
12414 	0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01,
12415 	0xc4, 0x01, 0xc6, 0x01,
12416 	0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
12417 	0x68, 0x08, 0x69, 0x08,
12418 	0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10,
12419 	0xed, 0x10, 0xf1, 0x10,
12420 	0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13,
12421 	0x1e, 0x13, 0x46, 0x14,
12422 	0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
12423 	0xca, 0x18, 0xe6, 0x19,
12424 	0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c,
12425 	0xf0, 0x2b, 0x02, 0xfe,
12426 	0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6,
12427 	0xfe, 0x84, 0x01, 0xff,
12428 	0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
12429 	0x00, 0xfe, 0x57, 0x24,
12430 	0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09,
12431 	0x00, 0x00, 0xff, 0x08,
12432 	0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
12433 	0xff, 0xff, 0xff, 0x11,
12434 	0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
12435 	0xfe, 0x04, 0xf7, 0xd6,
12436 	0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99,
12437 	0x0a, 0x42, 0x2c, 0xfe,
12438 	0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0,
12439 	0xfe, 0xf4, 0x01, 0xfe,
12440 	0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
12441 	0x02, 0xfe, 0xc8, 0x0d,
12442 	0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
12443 	0x1c, 0x03, 0xfe, 0xa6,
12444 	0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48,
12445 	0xf0, 0xfe, 0x8a, 0x02,
12446 	0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
12447 	0xfe, 0x46, 0xf0, 0xfe,
12448 	0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
12449 	0x48, 0x02, 0xfe, 0x44,
12450 	0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a,
12451 	0xaa, 0x18, 0x06, 0x14,
12452 	0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
12453 	0x1e, 0x1c, 0xfe, 0xe9,
12454 	0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce,
12455 	0x09, 0x70, 0x01, 0xa8,
12456 	0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70,
12457 	0x01, 0x87, 0xfe, 0xbd,
12458 	0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
12459 	0x58, 0x1c, 0x18, 0x06,
12460 	0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23,
12461 	0xfe, 0x98, 0x02, 0xfe,
12462 	0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2,
12463 	0x01, 0xfe, 0x48, 0x10,
12464 	0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
12465 	0x69, 0x10, 0x18, 0x06,
12466 	0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05,
12467 	0xf6, 0xce, 0x01, 0xfe,
12468 	0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe,
12469 	0x82, 0x16, 0x02, 0x2b,
12470 	0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
12471 	0xfe, 0x41, 0x58, 0x09,
12472 	0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe,
12473 	0x82, 0x16, 0x02, 0x2b,
12474 	0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43,
12475 	0xfe, 0x77, 0x57, 0xfe,
12476 	0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
12477 	0xfe, 0x40, 0x1c, 0x1c,
12478 	0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48,
12479 	0x03, 0xfe, 0x11, 0xf0,
12480 	0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10,
12481 	0xfe, 0x11, 0x00, 0x02,
12482 	0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
12483 	0x21, 0x22, 0xa3, 0xb7,
12484 	0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16,
12485 	0x12, 0xd1, 0x1c, 0xd9,
12486 	0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12,
12487 	0xfe, 0xe4, 0x00, 0x27,
12488 	0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
12489 	0x06, 0xf0, 0xfe, 0xc8,
12490 	0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03,
12491 	0x70, 0x28, 0x17, 0xfe,
12492 	0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8,
12493 	0xf9, 0x2c, 0x99, 0x19,
12494 	0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
12495 	0x74, 0x01, 0xaf, 0x8c,
12496 	0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e,
12497 	0x8d, 0x51, 0x64, 0x79,
12498 	0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b,
12499 	0xfe, 0x6a, 0x02, 0x02,
12500 	0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
12501 	0xfe, 0x3c, 0x04, 0x3b,
12502 	0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02,
12503 	0x00, 0x10, 0x01, 0x0b,
12504 	0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde,
12505 	0xfe, 0x4c, 0x44, 0xfe,
12506 	0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
12507 	0xda, 0x4f, 0x79, 0x2a,
12508 	0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b,
12509 	0xfe, 0x2a, 0x13, 0x32,
12510 	0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c,
12511 	0x54, 0x6b, 0xda, 0xfe,
12512 	0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
12513 	0x08, 0x13, 0x32, 0x07,
12514 	0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d,
12515 	0x08, 0x05, 0x06, 0x4d,
12516 	0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24,
12517 	0x2d, 0x12, 0xfe, 0xe6,
12518 	0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
12519 	0x02, 0x2b, 0xfe, 0x42,
12520 	0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
12521 	0xfe, 0x87, 0x80, 0xfe,
12522 	0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80,
12523 	0x07, 0x19, 0xfe, 0x7c,
12524 	0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
12525 	0x17, 0xfe, 0x90, 0x05,
12526 	0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe,
12527 	0xa0, 0x00, 0x28, 0xfe,
12528 	0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c,
12529 	0x34, 0xfe, 0x89, 0x48,
12530 	0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
12531 	0x12, 0xfe, 0xe3, 0x00,
12532 	0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
12533 	0x70, 0x05, 0x88, 0x25,
12534 	0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe,
12535 	0x09, 0x48, 0xff, 0x02,
12536 	0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
12537 	0x08, 0x53, 0x05, 0xcb,
12538 	0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08,
12539 	0x05, 0x1b, 0xfe, 0x22,
12540 	0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe,
12541 	0x0d, 0x00, 0x01, 0x36,
12542 	0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
12543 	0x03, 0x5c, 0x28, 0xfe,
12544 	0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53,
12545 	0x05, 0x1f, 0xfe, 0x02,
12546 	0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5,
12547 	0x01, 0x4b, 0x12, 0xfe,
12548 	0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
12549 	0x12, 0x03, 0x45, 0x28,
12550 	0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe,
12551 	0x43, 0x48, 0xc4, 0xcc,
12552 	0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4,
12553 	0x6e, 0x41, 0x01, 0xb2,
12554 	0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
12555 	0xfe, 0xcc, 0x15, 0x1d,
12556 	0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03,
12557 	0x45, 0xc1, 0x0c, 0x45,
12558 	0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe,
12559 	0xe2, 0x00, 0x27, 0xdb,
12560 	0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
12561 	0xfe, 0x06, 0xf0, 0xfe,
12562 	0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12,
12563 	0x16, 0x19, 0x01, 0x0b,
12564 	0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
12565 	0xfe, 0x99, 0xa4, 0x01,
12566 	0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
12567 	0x12, 0x08, 0x05, 0x1a,
12568 	0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
12569 	0x0b, 0x16, 0x00, 0x01,
12570 	0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02,
12571 	0xe2, 0x6c, 0x58, 0xbe,
12572 	0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
12573 	0xfe, 0x09, 0x6f, 0xba,
12574 	0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27,
12575 	0xfe, 0x54, 0x07, 0x1c,
12576 	0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c,
12577 	0x07, 0x02, 0x24, 0x01,
12578 	0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
12579 	0x2c, 0x90, 0xfe, 0xae,
12580 	0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a,
12581 	0x37, 0x22, 0x20, 0x07,
12582 	0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a,
12583 	0xfe, 0x06, 0x10, 0xfe,
12584 	0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
12585 	0x37, 0x01, 0xb3, 0xb8,
12586 	0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a,
12587 	0x50, 0xfe, 0x44, 0x51,
12588 	0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e,
12589 	0x14, 0x5f, 0xfe, 0x0c,
12590 	0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
12591 	0x14, 0x3e, 0xfe, 0x4a,
12592 	0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
12593 	0x90, 0x0c, 0x60, 0x14,
12594 	0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62,
12595 	0xfe, 0x44, 0x90, 0xfe,
12596 	0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
12597 	0x0c, 0x5e, 0x14, 0x5f,
12598 	0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e,
12599 	0x14, 0x3c, 0x21, 0x0c,
12600 	0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11,
12601 	0x27, 0xdd, 0xfe, 0x9e,
12602 	0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
12603 	0x9a, 0x08, 0xc6, 0xfe,
12604 	0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08,
12605 	0x95, 0x86, 0x02, 0x24,
12606 	0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05,
12607 	0x06, 0xfe, 0x10, 0x12,
12608 	0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
12609 	0x1c, 0x02, 0xfe, 0x18,
12610 	0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe,
12611 	0x2c, 0x1c, 0xfe, 0xaa,
12612 	0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe,
12613 	0xde, 0x09, 0xfe, 0xb7,
12614 	0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
12615 	0xfe, 0xf1, 0x18, 0xfe,
12616 	0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe,
12617 	0x14, 0x59, 0xfe, 0x95,
12618 	0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0,
12619 	0xfe, 0xf0, 0x08, 0xb5,
12620 	0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
12621 	0x0b, 0xb6, 0xfe, 0xbf,
12622 	0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c,
12623 	0x12, 0xc2, 0xfe, 0xd2,
12624 	0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e,
12625 	0x06, 0x17, 0x85, 0xc5,
12626 	0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
12627 	0x9d, 0x01, 0x36, 0x10,
12628 	0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe,
12629 	0x98, 0x80, 0xfe, 0x19,
12630 	0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18,
12631 	0xfe, 0x44, 0x54, 0xbe,
12632 	0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
12633 	0x02, 0x4a, 0x08, 0x05,
12634 	0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e,
12635 	0x9c, 0x3c, 0xfe, 0x6c,
12636 	0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f,
12637 	0x3b, 0x40, 0x03, 0x49,
12638 	0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
12639 	0x8f, 0xfe, 0xe3, 0x54,
12640 	0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe,
12641 	0xda, 0x09, 0xfe, 0x8b,
12642 	0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa,
12643 	0x0a, 0x3a, 0x49, 0x3b,
12644 	0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
12645 	0xad, 0xfe, 0x01, 0x59,
12646 	0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a,
12647 	0x49, 0x8f, 0xfe, 0xe3,
12648 	0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02,
12649 	0x4a, 0x3a, 0x49, 0x3b,
12650 	0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
12651 	0x02, 0x4a, 0x08, 0x05,
12652 	0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62,
12653 	0xb7, 0xfe, 0x03, 0xa1,
12654 	0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
12655 	0xfe, 0x86, 0x91, 0x6a,
12656 	0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
12657 	0x61, 0x0c, 0x7f, 0x14,
12658 	0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62,
12659 	0x9b, 0x2e, 0x9c, 0x3c,
12660 	0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05,
12661 	0xfa, 0x3c, 0x01, 0xef,
12662 	0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
12663 	0xe4, 0x08, 0x05, 0x1f,
12664 	0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37,
12665 	0x03, 0x5e, 0x29, 0x5f,
12666 	0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe,
12667 	0xf4, 0x09, 0x08, 0x05,
12668 	0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
12669 	0x81, 0x50, 0xfe, 0x10,
12670 	0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe,
12671 	0x08, 0x09, 0x12, 0xa6,
12672 	0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe,
12673 	0x08, 0x09, 0xfe, 0x0c,
12674 	0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
12675 	0x08, 0x05, 0x0a, 0xfe,
12676 	0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1,
12677 	0xf0, 0xe2, 0x15, 0x7e,
12678 	0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19,
12679 	0x57, 0x3d, 0xfe, 0xed,
12680 	0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
12681 	0x00, 0xff, 0x35, 0xfe,
12682 	0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18,
12683 	0x1e, 0x19, 0x8a, 0x03,
12684 	0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65,
12685 	0xfe, 0xd1, 0xf0, 0xfe,
12686 	0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
12687 	0x10, 0xfe, 0xce, 0xf0,
12688 	0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b,
12689 	0x10, 0xfe, 0x22, 0x00,
12690 	0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00,
12691 	0x02, 0x65, 0xfe, 0xd0,
12692 	0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
12693 	0x0b, 0x10, 0x58, 0xfe,
12694 	0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe,
12695 	0x12, 0x00, 0x2c, 0x0f,
12696 	0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14,
12697 	0x0c, 0xbc, 0x17, 0x34,
12698 	0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
12699 	0x0c, 0x1c, 0x34, 0x94,
12700 	0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01,
12701 	0x4b, 0xfe, 0xdb, 0x10,
12702 	0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe,
12703 	0x89, 0xf0, 0x24, 0x33,
12704 	0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
12705 	0x33, 0x31, 0xdf, 0xbc,
12706 	0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49,
12707 	0x17, 0xfe, 0x2c, 0x0d,
12708 	0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54,
12709 	0x12, 0x55, 0xfe, 0x28,
12710 	0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
12711 	0x44, 0xfe, 0x28, 0x00,
12712 	0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26,
12713 	0x0f, 0x64, 0x12, 0x2f,
12714 	0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44,
12715 	0x0a, 0xfe, 0xb4, 0x10,
12716 	0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
12717 	0xfe, 0x34, 0x46, 0xac,
12718 	0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a,
12719 	0x37, 0x01, 0xf5, 0x01,
12720 	0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02,
12721 	0xfe, 0x2e, 0x03, 0x08,
12722 	0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
12723 	0x1a, 0xfe, 0x58, 0x12,
12724 	0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
12725 	0xfe, 0x50, 0x0d, 0xfe,
12726 	0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37,
12727 	0xfe, 0xa9, 0x10, 0x10,
12728 	0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
12729 	0xfe, 0x13, 0x00, 0xfe,
12730 	0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe,
12731 	0x24, 0x00, 0x8c, 0xb5,
12732 	0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a,
12733 	0xfe, 0x9d, 0x41, 0xfe,
12734 	0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
12735 	0xb4, 0x15, 0xfe, 0x31,
12736 	0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06,
12737 	0xec, 0xd0, 0xfc, 0x44,
12738 	0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47,
12739 	0x4b, 0x91, 0xfe, 0x75,
12740 	0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
12741 	0x0e, 0xfe, 0x44, 0x48,
12742 	0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41,
12743 	0xfe, 0x41, 0x58, 0x09,
12744 	0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe,
12745 	0x2e, 0x03, 0x09, 0x5d,
12746 	0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
12747 	0xce, 0x47, 0xfe, 0xad,
12748 	0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13,
12749 	0x59, 0x13, 0x9f, 0x13,
12750 	0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe,
12751 	0xe0, 0x0e, 0x0f, 0x06,
12752 	0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
12753 	0x3a, 0x01, 0x56, 0xfe,
12754 	0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec,
12755 	0x20, 0x4f, 0xfe, 0x05,
12756 	0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe,
12757 	0x48, 0xf4, 0x0d, 0xfe,
12758 	0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
12759 	0x15, 0x1a, 0x39, 0xa0,
12760 	0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff,
12761 	0x0c, 0xfe, 0x60, 0x01,
12762 	0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25,
12763 	0x06, 0x13, 0x2f, 0x12,
12764 	0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
12765 	0x22, 0x9f, 0xb7, 0x13,
12766 	0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39,
12767 	0xa0, 0xb4, 0xfe, 0xd9,
12768 	0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04,
12769 	0xc3, 0xfe, 0x03, 0xdc,
12770 	0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
12771 	0xfe, 0x00, 0xcc, 0x04,
12772 	0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13,
12773 	0xfe, 0x1c, 0x80, 0x07,
12774 	0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae,
12775 	0xfe, 0x0c, 0x90, 0xfe,
12776 	0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
12777 	0x0a, 0xfe, 0x3c, 0x50,
12778 	0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4,
12779 	0x16, 0x08, 0x05, 0x1b,
12780 	0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58,
12781 	0xfe, 0x2c, 0x13, 0x01,
12782 	0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
12783 	0x0c, 0xfe, 0x64, 0x01,
12784 	0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03,
12785 	0x80, 0x8d, 0xfe, 0x01,
12786 	0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64,
12787 	0x22, 0x20, 0xfb, 0x79,
12788 	0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
12789 	0x03, 0xfe, 0xae, 0x00,
12790 
12791 	0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe,
12792 	0xb2, 0x00, 0xfe, 0x09,
12793 	0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c,
12794 	0x45, 0x0f, 0x46, 0x52,
12795 	0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
12796 	0x0f, 0x44, 0x11, 0x0f,
12797 	0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4,
12798 	0x25, 0x11, 0x13, 0x20,
12799 	0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14,
12800 	0x56, 0xfe, 0xd6, 0xf0,
12801 	0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
12802 	0x18, 0x1c, 0x04, 0x42,
12803 	0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe,
12804 	0xf5, 0x13, 0x04, 0x01,
12805 	0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
12806 	0x13, 0x32, 0x07, 0x2f,
12807 	0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
12808 	0x41, 0x48, 0xfe, 0x45,
12809 	0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78,
12810 	0x07, 0x11, 0xac, 0x09,
12811 	0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07,
12812 	0x82, 0x4e, 0xfe, 0x14,
12813 	0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
12814 	0xfe, 0x01, 0xec, 0xa2,
12815 	0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79,
12816 	0x2a, 0x01, 0xe3, 0xfe,
12817 	0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a,
12818 	0xfe, 0x48, 0x12, 0x07,
12819 	0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
12820 	0xfe, 0x32, 0x12, 0x07,
12821 	0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07,
12822 	0x1f, 0xfe, 0x12, 0x12,
12823 	0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b,
12824 	0x94, 0x4b, 0x04, 0x2d,
12825 	0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
12826 	0x32, 0x07, 0xa6, 0xfe,
12827 	0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05,
12828 	0x5a, 0xfe, 0x72, 0x12,
12829 	0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62,
12830 	0xfe, 0x26, 0x13, 0x03,
12831 	0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
12832 	0x0c, 0x7f, 0x0c, 0x80,
12833 	0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c,
12834 	0x3c, 0xfe, 0x04, 0x55,
12835 	0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe,
12836 	0x91, 0x10, 0x03, 0x3f,
12837 	0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
12838 	0x88, 0x9b, 0x2e, 0x9c,
12839 	0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
12840 	0x56, 0x0c, 0x5e, 0x14,
12841 	0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40,
12842 	0x03, 0x60, 0x29, 0x61,
12843 	0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
12844 	0x50, 0xfe, 0xc6, 0x50,
12845 	0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d,
12846 	0x29, 0x3e, 0xfe, 0x40,
12847 	0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72,
12848 	0x2d, 0x01, 0x0b, 0x1d,
12849 	0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
12850 	0x72, 0x01, 0xaf, 0x1e,
12851 	0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe,
12852 	0x0a, 0x55, 0x35, 0xfe,
12853 	0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51,
12854 	0x02, 0x72, 0xfe, 0x19,
12855 	0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
12856 	0x1d, 0xe8, 0x33, 0x31,
12857 	0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01,
12858 	0x0b, 0x1c, 0x34, 0x1d,
12859 	0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8,
12860 	0x33, 0x31, 0xfe, 0xe8,
12861 	0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
12862 	0x05, 0x1f, 0x35, 0xa9,
12863 	0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda,
12864 	0x14, 0x01, 0xaf, 0x8c,
12865 	0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a,
12866 	0x03, 0x45, 0x28, 0x35,
12867 	0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
12868 	0x03, 0x5c, 0xc1, 0x0c,
12869 	0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02,
12870 	0x89, 0x01, 0x0b, 0x1c,
12871 	0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1,
12872 	0xfe, 0x42, 0x58, 0xf1,
12873 	0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
12874 	0xf4, 0x06, 0xea, 0x32,
12875 	0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d,
12876 	0x01, 0x0b, 0x26, 0x89,
12877 	0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13,
12878 	0x26, 0xfe, 0xd4, 0x13,
12879 	0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
12880 	0x13, 0x1c, 0xfe, 0xd0,
12881 	0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10,
12882 	0x0f, 0x71, 0xff, 0x02,
12883 	0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe,
12884 	0x00, 0x5c, 0x04, 0x0f,
12885 	0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
12886 	0xfe, 0x00, 0x5c, 0x04,
12887 	0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff,
12888 	0x02, 0x00, 0x57, 0x52,
12889 	0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01,
12890 	0x87, 0x04, 0xfe, 0x03,
12891 	0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
12892 	0xfe, 0x00, 0x7d, 0xfe,
12893 	0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e,
12894 	0x14, 0x5f, 0x57, 0x3f,
12895 	0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83,
12896 	0x5a, 0x8d, 0x04, 0x01,
12897 	0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
12898 	0xfe, 0x96, 0x15, 0x33,
12899 	0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8,
12900 	0x0a, 0xfe, 0xc1, 0x59,
12901 	0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13,
12902 	0x21, 0x69, 0x1a, 0xee,
12903 	0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
12904 	0x30, 0xfe, 0x78, 0x10,
12905 	0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae,
12906 	0x98, 0xfe, 0x30, 0x00,
12907 	0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed,
12908 	0x98, 0xfe, 0x64, 0x00,
12909 	0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
12910 	0x10, 0x69, 0x06, 0xfe,
12911 	0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00,
12912 	0x18, 0x59, 0x0f, 0x06,
12913 	0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe,
12914 	0x43, 0xf4, 0x9f, 0xfe,
12915 	0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
12916 	0x9e, 0xfe, 0xf3, 0x10,
12917 	0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00,
12918 	0x17, 0xfe, 0x4d, 0xe4,
12919 	0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00,
12920 	0x17, 0xfe, 0x4d, 0xe4,
12921 	0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
12922 	0xf4, 0x00, 0xe9, 0x91,
12923 	0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a,
12924 	0x04, 0x16, 0x06, 0x01,
12925 	0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01,
12926 	0x0b, 0x26, 0xf3, 0x76,
12927 	0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
12928 	0x16, 0x19, 0x01, 0x0b,
12929 	0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01,
12930 	0x0b, 0x26, 0xb1, 0x76,
12931 	0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06,
12932 	0xfe, 0x48, 0x13, 0xb8,
12933 	0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
12934 	0xec, 0xfe, 0x27, 0x01,
12935 	0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32,
12936 	0x07, 0xfe, 0xe3, 0x00,
12937 	0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b,
12938 	0x22, 0xd4, 0x07, 0x06,
12939 	0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
12940 	0x07, 0x11, 0xae, 0x09,
12941 	0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01,
12942 	0x0e, 0x8e, 0xfe, 0x80,
12943 	0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04,
12944 	0x09, 0x48, 0x01, 0x0e,
12945 	0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
12946 	0x80, 0xfe, 0x80, 0x4c,
12947 	0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c,
12948 	0x09, 0x5d, 0x01, 0x87,
12949 	0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe,
12950 	0x19, 0xde, 0xfe, 0x24,
12951 	0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
12952 	0x17, 0xad, 0x9a, 0x1b,
12953 	0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde,
12954 	0x16, 0xfe, 0xda, 0x10,
12955 	0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe,
12956 	0x18, 0x58, 0x03, 0xfe,
12957 	0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
12958 	0xf4, 0x06, 0xfe, 0x3c,
12959 	0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f,
12960 	0x97, 0xfe, 0x38, 0x17,
12961 	0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c,
12962 	0x10, 0x18, 0x11, 0x75,
12963 	0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
12964 	0x2e, 0x97, 0xfe, 0x5a,
12965 	0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19,
12966 	0xfe, 0x98, 0xe7, 0x00,
12967 	0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75,
12968 	0xfe, 0x30, 0xbc, 0xfe,
12969 	0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
12970 	0xcb, 0x97, 0xfe, 0x92,
12971 	0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe,
12972 	0x42, 0x10, 0xfe, 0x02,
12973 	0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe,
12974 	0x03, 0xa1, 0xfe, 0x1d,
12975 	0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
12976 	0x9a, 0x5b, 0x41, 0xfe,
12977 	0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7,
12978 	0x11, 0x12, 0xfe, 0xdd,
12979 	0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8,
12980 	0x17, 0x15, 0x06, 0x39,
12981 	0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
12982 	0xfe, 0x7e, 0x18, 0x1e,
12983 	0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef,
12984 	0x12, 0xfe, 0xe1, 0x10,
12985 	0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42,
12986 	0x13, 0x42, 0x92, 0x09,
12987 	0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
12988 	0xf0, 0xfe, 0x00, 0xcc,
12989 	0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01,
12990 	0x0e, 0xfe, 0x80, 0x4c,
12991 	0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe,
12992 	0x24, 0x12, 0xfe, 0x14,
12993 	0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
12994 	0xe7, 0x0a, 0x10, 0xfe,
12995 	0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92,
12996 	0x08, 0x54, 0x1b, 0x37,
12997 	0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba,
12998 	0x90, 0x3a, 0xce, 0x3b,
12999 	0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
13000 	0x13, 0xa3, 0x04, 0x09,
13001 	0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49,
13002 	0x44, 0x17, 0xfe, 0xe8,
13003 	0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09,
13004 	0x5d, 0x01, 0xa8, 0x09,
13005 	0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
13006 	0x1c, 0x19, 0x03, 0xfe,
13007 	0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9,
13008 	0x6b, 0xfe, 0x2e, 0x19,
13009 	0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4,
13010 	0xfe, 0x0b, 0x00, 0x6b,
13011 	0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
13012 	0x08, 0x10, 0x03, 0xfe,
13013 	0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff,
13014 	0x04, 0x68, 0x54, 0xe7,
13015 	0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe,
13016 	0x1a, 0xf4, 0xfe, 0x00,
13017 	0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
13018 	0x04, 0x07, 0x7e, 0xfe,
13019 	0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
13020 	0x07, 0x1a, 0xfe, 0x5a,
13021 	0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66,
13022 	0x25, 0x6d, 0xe5, 0x07,
13023 	0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
13024 	0xa9, 0xb8, 0x04, 0x15,
13025 	0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe,
13026 	0x40, 0x5c, 0x04, 0x1c,
13027 	0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b,
13028 	0xf7, 0xfe, 0x82, 0xf0,
13029 	0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
13030 };
13031 
13032 static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf);	/* 0x14E1 */
13033 static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL;	/* Expanded little-endian checksum. */
13034 
13035 /* Microcode buffer is kept after initialization for error recovery. */
13036 static unsigned char _adv_asc38C1600_buf[] = {
13037 	0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
13038 	0x18, 0xe4, 0x01, 0x00,
13039 	0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00,
13040 	0x07, 0x17, 0xc0, 0x5f,
13041 	0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7,
13042 	0x85, 0xf0, 0x86, 0xf0,
13043 	0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
13044 	0x98, 0x57, 0x01, 0xe6,
13045 	0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d,
13046 	0x38, 0x54, 0x32, 0xf0,
13047 	0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4,
13048 	0x00, 0xe6, 0xb1, 0xf0,
13049 	0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
13050 	0x06, 0x13, 0x0c, 0x1c,
13051 	0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12,
13052 	0xb9, 0x54, 0x00, 0x80,
13053 	0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56,
13054 	0x03, 0xe6, 0x01, 0xea,
13055 	0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
13056 	0x04, 0x13, 0xbb, 0x55,
13057 	0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00,
13058 	0xbb, 0x00, 0xc0, 0x00,
13059 	0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12,
13060 	0x4c, 0x1c, 0x4e, 0x1c,
13061 	0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
13062 	0x24, 0x01, 0x3c, 0x01,
13063 	0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01,
13064 	0x78, 0x01, 0x7c, 0x01,
13065 	0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c,
13066 	0x6e, 0x1e, 0x02, 0x48,
13067 	0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
13068 	0x03, 0xfc, 0x06, 0x00,
13069 	0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a,
13070 	0x30, 0x1c, 0x38, 0x1c,
13071 	0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea,
13072 	0x5d, 0xf0, 0xa7, 0xf0,
13073 	0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
13074 	0x33, 0x00, 0x34, 0x00,
13075 	0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01,
13076 	0x79, 0x01, 0x3c, 0x09,
13077 	0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13,
13078 	0x40, 0x16, 0x50, 0x16,
13079 	0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
13080 	0x05, 0xf0, 0x09, 0xf0,
13081 	0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00,
13082 	0x9c, 0x00, 0xa4, 0x00,
13083 	0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08,
13084 	0xe9, 0x09, 0x5c, 0x0c,
13085 	0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
13086 	0x42, 0x1d, 0x08, 0x44,
13087 	0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54,
13088 	0x83, 0x55, 0x83, 0x59,
13089 	0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0,
13090 	0x4b, 0xf4, 0x04, 0xf8,
13091 	0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
13092 	0xa8, 0x00, 0xaa, 0x00,
13093 	0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01,
13094 	0x7a, 0x01, 0x82, 0x01,
13095 	0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07,
13096 	0x68, 0x08, 0x10, 0x0d,
13097 	0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
13098 	0xf3, 0x10, 0x06, 0x12,
13099 	0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c,
13100 	0xf0, 0x35, 0x05, 0xfe,
13101 	0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8,
13102 	0xfe, 0x88, 0x01, 0xff,
13103 	0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
13104 	0x00, 0xfe, 0x57, 0x24,
13105 	0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09,
13106 	0x00, 0x00, 0xff, 0x08,
13107 	0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
13108 	0xff, 0xff, 0xff, 0x13,
13109 	0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
13110 	0xfe, 0x04, 0xf7, 0xe8,
13111 	0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d,
13112 	0x0d, 0x51, 0x37, 0xfe,
13113 	0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0,
13114 	0xfe, 0xf8, 0x01, 0xfe,
13115 	0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
13116 	0x05, 0xfe, 0x08, 0x0f,
13117 	0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe,
13118 	0x28, 0x1c, 0x03, 0xfe,
13119 	0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe,
13120 	0x48, 0xf0, 0xfe, 0x90,
13121 	0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
13122 	0x02, 0xfe, 0x46, 0xf0,
13123 	0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0,
13124 	0xfe, 0x4e, 0x02, 0xfe,
13125 	0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c,
13126 	0x0d, 0xa2, 0x1c, 0x07,
13127 	0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
13128 	0x1c, 0xf5, 0xfe, 0x1e,
13129 	0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc,
13130 	0xde, 0x0a, 0x81, 0x01,
13131 	0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a,
13132 	0x81, 0x01, 0x5c, 0xfe,
13133 	0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
13134 	0xfe, 0x58, 0x1c, 0x1c,
13135 	0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02,
13136 	0x2b, 0xfe, 0x9e, 0x02,
13137 	0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30,
13138 	0x00, 0x47, 0xb8, 0x01,
13139 	0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
13140 	0x1a, 0x31, 0xfe, 0x69,
13141 	0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe,
13142 	0x1e, 0x1e, 0x20, 0x2c,
13143 	0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a,
13144 	0x44, 0x15, 0x56, 0x51,
13145 	0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
13146 	0x01, 0x18, 0x09, 0x00,
13147 	0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01,
13148 	0x18, 0xfe, 0xc8, 0x54,
13149 	0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60,
13150 	0xfe, 0x02, 0xe8, 0x30,
13151 	0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
13152 	0xfe, 0xe4, 0x01, 0xfe,
13153 	0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe,
13154 	0x26, 0xf0, 0xfe, 0x66,
13155 	0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe,
13156 	0xef, 0x10, 0xfe, 0x9f,
13157 	0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
13158 	0x70, 0x37, 0xfe, 0x48,
13159 	0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26,
13160 	0x21, 0xb9, 0xc7, 0x20,
13161 	0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15,
13162 	0xe1, 0x2a, 0xeb, 0xfe,
13163 	0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
13164 	0x15, 0xfe, 0xe4, 0x00,
13165 	0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41,
13166 	0xfe, 0x06, 0xf0, 0xfe,
13167 	0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29,
13168 	0x03, 0x81, 0x1e, 0x1b,
13169 	0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
13170 	0xea, 0xfe, 0x46, 0x1c,
13171 	0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
13172 	0xfe, 0x48, 0x1c, 0x75,
13173 	0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a,
13174 	0xe1, 0x01, 0x18, 0x77,
13175 	0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
13176 	0x8f, 0xfe, 0x70, 0x02,
13177 	0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04,
13178 	0x16, 0xfe, 0x4a, 0x04,
13179 	0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff,
13180 	0x02, 0x00, 0x10, 0x01,
13181 	0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
13182 	0xee, 0xfe, 0x4c, 0x44,
13183 	0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54,
13184 	0x7b, 0xec, 0x60, 0x8d,
13185 	0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01,
13186 	0x0c, 0x06, 0x28, 0xfe,
13187 	0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
13188 	0x13, 0x34, 0xfe, 0x4c,
13189 	0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54,
13190 	0x13, 0x01, 0x0c, 0x06,
13191 	0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06,
13192 	0x28, 0xf9, 0x1f, 0x7f,
13193 	0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
13194 	0xfe, 0xa4, 0x0e, 0x05,
13195 	0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe,
13196 	0x9c, 0x93, 0x3a, 0x0b,
13197 	0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b,
13198 	0x7d, 0x1d, 0xfe, 0x46,
13199 	0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
13200 	0xfe, 0x87, 0x83, 0xfe,
13201 	0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98,
13202 	0x13, 0x0f, 0xfe, 0x20,
13203 	0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84,
13204 	0x12, 0x01, 0x38, 0x06,
13205 	0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
13206 	0x05, 0xd0, 0x54, 0x01,
13207 	0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe,
13208 	0x50, 0x12, 0x5e, 0xff,
13209 	0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02,
13210 	0x00, 0x10, 0x2f, 0xfe,
13211 	0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
13212 	0x38, 0xfe, 0x4a, 0xf0,
13213 	0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe,
13214 	0x21, 0x00, 0xf1, 0x2e,
13215 	0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00,
13216 	0x10, 0x2f, 0xfe, 0xd0,
13217 	0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
13218 	0x1c, 0x00, 0x4d, 0x01,
13219 	0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06,
13220 	0x28, 0xfe, 0x24, 0x12,
13221 	0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe,
13222 	0x0d, 0x00, 0x01, 0x42,
13223 	0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
13224 	0x03, 0xb6, 0x1e, 0xfe,
13225 	0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17,
13226 	0xfe, 0x72, 0x06, 0x0a,
13227 	0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56,
13228 	0x19, 0x16, 0xfe, 0x68,
13229 	0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
13230 	0x03, 0x9a, 0x1e, 0xfe,
13231 	0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12,
13232 	0x48, 0xfe, 0x92, 0x06,
13233 	0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13,
13234 	0x58, 0xff, 0x02, 0x00,
13235 	0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
13236 	0xfe, 0xea, 0x06, 0x01,
13237 	0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16,
13238 	0xfe, 0xe0, 0x06, 0x15,
13239 	0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07,
13240 	0x01, 0x84, 0xfe, 0xae,
13241 	0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
13242 	0x1e, 0xfe, 0x1a, 0x12,
13243 	0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
13244 	0x43, 0x48, 0x62, 0x80,
13245 	0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24,
13246 	0x36, 0xfe, 0x02, 0xf6,
13247 	0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
13248 	0xd0, 0x0d, 0x17, 0xfe,
13249 	0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20,
13250 	0x9e, 0x15, 0x82, 0x01,
13251 	0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58,
13252 	0x57, 0x10, 0xe6, 0x05,
13253 	0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
13254 	0xfe, 0x9c, 0x32, 0x5f,
13255 	0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c,
13256 	0xfe, 0x0a, 0xf0, 0xfe,
13257 	0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08,
13258 	0xaf, 0xa0, 0x05, 0x29,
13259 	0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
13260 	0x00, 0x01, 0x08, 0x14,
13261 	0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08,
13262 	0x14, 0x00, 0x05, 0xfe,
13263 	0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06,
13264 	0x12, 0xfe, 0x30, 0x13,
13265 	0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
13266 	0x01, 0x08, 0x14, 0x00,
13267 	0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a,
13268 	0x78, 0x4f, 0x0f, 0xfe,
13269 	0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d,
13270 	0x28, 0x48, 0xfe, 0x6c,
13271 	0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
13272 	0x12, 0x53, 0x63, 0x4e,
13273 	0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe,
13274 	0x6c, 0x08, 0xaf, 0xa0,
13275 	0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24,
13276 	0x05, 0xed, 0xfe, 0x9c,
13277 	0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
13278 	0x1e, 0xfe, 0x99, 0x58,
13279 	0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a,
13280 	0x22, 0x6b, 0x01, 0x0c,
13281 	0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e,
13282 	0x1e, 0x47, 0x2c, 0x7a,
13283 	0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
13284 	0x01, 0x0c, 0x61, 0x65,
13285 	0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a,
13286 	0x16, 0xfe, 0x08, 0x50,
13287 	0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10,
13288 	0x01, 0xfe, 0xce, 0x1e,
13289 	0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
13290 	0x01, 0xfe, 0xfe, 0x1e,
13291 	0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a,
13292 	0x10, 0x01, 0x0c, 0x06,
13293 	0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e,
13294 	0x10, 0x6a, 0x22, 0x6b,
13295 	0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
13296 	0xfe, 0x9f, 0x83, 0x33,
13297 	0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93,
13298 	0x3a, 0x0b, 0xfe, 0xc6,
13299 	0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d,
13300 	0x01, 0xfe, 0xce, 0x1e,
13301 	0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
13302 	0x04, 0xfe, 0xc0, 0x93,
13303 	0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e,
13304 	0x10, 0x4b, 0x22, 0x4c,
13305 	0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe,
13306 	0x4e, 0x11, 0x2f, 0xfe,
13307 	0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
13308 	0x3c, 0x37, 0x88, 0xf5,
13309 	0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a,
13310 	0xd3, 0xfe, 0x42, 0x0a,
13311 	0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0,
13312 	0x05, 0x29, 0x01, 0x41,
13313 	0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
13314 	0xfe, 0x14, 0x12, 0x01,
13315 	0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe,
13316 	0x2e, 0x1c, 0x05, 0xfe,
13317 	0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41,
13318 	0xfe, 0x2c, 0x1c, 0xfe,
13319 	0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
13320 	0x92, 0x10, 0xc4, 0xf6,
13321 	0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe,
13322 	0xe7, 0x10, 0xfe, 0x2b,
13323 	0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12,
13324 	0xac, 0xfe, 0xd2, 0xf0,
13325 	0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
13326 	0x1b, 0xbf, 0xd4, 0x5b,
13327 	0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75,
13328 	0x5e, 0x32, 0x1f, 0x7f,
13329 	0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98,
13330 	0x05, 0x70, 0xfe, 0x74,
13331 	0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
13332 	0x0f, 0x4d, 0x01, 0xfe,
13333 	0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06,
13334 	0x0d, 0x2b, 0xfe, 0xe2,
13335 	0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24,
13336 	0xfe, 0x88, 0x13, 0x21,
13337 	0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
13338 	0x83, 0x83, 0xfe, 0xc9,
13339 	0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04,
13340 	0x91, 0x04, 0xfe, 0x84,
13341 	0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93,
13342 	0xfe, 0xcb, 0x57, 0x0b,
13343 	0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
13344 	0x6a, 0x3b, 0x6b, 0x10,
13345 	0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30,
13346 	0x20, 0x6e, 0xdb, 0x64,
13347 	0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55,
13348 	0xfe, 0x04, 0xfa, 0x64,
13349 	0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
13350 	0x10, 0x98, 0x91, 0x6c,
13351 	0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91,
13352 	0x4b, 0x7e, 0x4c, 0x01,
13353 	0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10,
13354 	0x58, 0xfe, 0x91, 0x58,
13355 	0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
13356 	0x1b, 0x40, 0x01, 0x0c,
13357 	0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f,
13358 	0xfe, 0x10, 0x90, 0x04,
13359 	0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93,
13360 	0x79, 0x0b, 0x0e, 0xfe,
13361 	0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
13362 	0x01, 0x0c, 0x06, 0x0d,
13363 	0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe,
13364 	0x0c, 0x58, 0xfe, 0x8d,
13365 	0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99,
13366 	0x83, 0x33, 0x0b, 0x0e,
13367 	0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
13368 	0x19, 0xfe, 0x19, 0x41,
13369 	0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42,
13370 	0x19, 0xfe, 0x44, 0x00,
13371 	0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda,
13372 	0x4c, 0xfe, 0x0c, 0x51,
13373 	0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
13374 	0x76, 0x10, 0xac, 0xfe,
13375 	0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03,
13376 	0xe3, 0x23, 0x07, 0xfe,
13377 	0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe,
13378 	0xcc, 0x0c, 0x1f, 0x92,
13379 	0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
13380 	0x0c, 0xfe, 0x3e, 0x10,
13381 	0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70,
13382 	0xfe, 0xcb, 0xf0, 0xfe,
13383 	0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe,
13384 	0xf4, 0x0c, 0x19, 0x94,
13385 	0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
13386 	0xfe, 0xcc, 0xf0, 0xef,
13387 	0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe,
13388 	0x4e, 0x11, 0x2f, 0xfe,
13389 	0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b,
13390 	0x3c, 0x37, 0x88, 0xf5,
13391 	0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
13392 	0x2f, 0xfe, 0x3e, 0x0d,
13393 	0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f,
13394 	0xd2, 0x9f, 0xd3, 0x9f,
13395 	0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4,
13396 	0xc5, 0x75, 0xd7, 0x99,
13397 	0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
13398 	0x9c, 0x2f, 0xfe, 0x8c,
13399 	0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe,
13400 	0x42, 0x00, 0x05, 0x70,
13401 	0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06,
13402 	0x0d, 0xfe, 0x44, 0x13,
13403 	0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
13404 	0xfe, 0xda, 0x0e, 0x0a,
13405 	0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa,
13406 	0x10, 0x01, 0xfe, 0xf4,
13407 	0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40,
13408 	0x15, 0x56, 0x01, 0x85,
13409 	0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
13410 	0xcc, 0x10, 0x01, 0xa7,
13411 	0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04,
13412 	0xfe, 0x99, 0x83, 0xfe,
13413 	0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe,
13414 	0x43, 0x00, 0xfe, 0xa2,
13415 	0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
13416 	0x00, 0x1d, 0x40, 0x15,
13417 	0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05,
13418 	0xfe, 0x3a, 0x03, 0x01,
13419 	0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01,
13420 	0x76, 0x06, 0x12, 0xfe,
13421 	0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
13422 	0xfe, 0x9d, 0xf0, 0xfe,
13423 	0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01,
13424 	0x0c, 0x61, 0x12, 0x44,
13425 	0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f,
13426 	0xfe, 0x2e, 0x10, 0x19,
13427 	0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
13428 	0xfe, 0x41, 0x00, 0xa2,
13429 	0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b,
13430 	0xea, 0x4f, 0xfe, 0x04,
13431 	0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05,
13432 	0x35, 0xfe, 0x12, 0x1c,
13433 	0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
13434 	0xfe, 0xd4, 0x11, 0x05,
13435 	0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe,
13436 	0xce, 0x45, 0x31, 0x51,
13437 	0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03,
13438 	0x67, 0xfe, 0x98, 0x56,
13439 	0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
13440 	0x0c, 0x06, 0x28, 0xfe,
13441 	0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba,
13442 	0xfe, 0xfa, 0x14, 0xfe,
13443 	0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67,
13444 	0xfe, 0xe0, 0x14, 0xfe,
13445 	0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
13446 	0xfe, 0xad, 0x13, 0x05,
13447 	0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20,
13448 	0xe7, 0xfe, 0x08, 0x1c,
13449 	0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe,
13450 	0x48, 0x55, 0xa5, 0x3b,
13451 	0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
13452 	0xf0, 0x1a, 0x03, 0xfe,
13453 	0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02,
13454 	0xec, 0xe7, 0x53, 0x00,
13455 	0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
13456 	0x01, 0xfe, 0x62, 0x1b,
13457 	0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
13458 	0xea, 0xe7, 0x53, 0x92,
13459 	0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03,
13460 	0xfe, 0x38, 0x01, 0x23,
13461 	0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62,
13462 	0x01, 0x01, 0xfe, 0x1e,
13463 	0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
13464 	0x26, 0x02, 0x21, 0x96,
13465 	0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5,
13466 	0xc3, 0xfe, 0xe1, 0x10,
13467 	0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf,
13468 	0xfe, 0x03, 0xdc, 0xfe,
13469 	0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
13470 	0x00, 0xcc, 0x02, 0xfe,
13471 	0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13,
13472 	0x0f, 0xfe, 0x1c, 0x80,
13473 	0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13,
13474 	0x0f, 0xfe, 0x1e, 0x80,
13475 	0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
13476 	0x1d, 0x80, 0x04, 0xfe,
13477 	0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee,
13478 	0x1e, 0xac, 0xfe, 0x14,
13479 	0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e,
13480 	0x1f, 0xfe, 0x30, 0xf4,
13481 	0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
13482 	0x56, 0xfb, 0x01, 0xfe,
13483 	0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01,
13484 	0xfe, 0x00, 0x1d, 0x15,
13485 	0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe,
13486 	0x22, 0x1b, 0xfe, 0x1e,
13487 	0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
13488 	0x96, 0x90, 0x04, 0xfe,
13489 	0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66,
13490 	0x01, 0x01, 0x0c, 0x06,
13491 	0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b,
13492 	0x0e, 0x77, 0xfe, 0x01,
13493 	0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
13494 	0x21, 0x2c, 0xfe, 0x00,
13495 	0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe,
13496 	0x06, 0x58, 0x03, 0xfe,
13497 	0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58,
13498 	0x03, 0xfe, 0xb2, 0x00,
13499 	0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
13500 	0x66, 0x10, 0x55, 0x10,
13501 	0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91,
13502 	0x54, 0x2b, 0xfe, 0x88,
13503 	0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe,
13504 	0x91, 0x54, 0x2b, 0xfe,
13505 	0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
13506 	0x00, 0x40, 0x8d, 0x2c,
13507 	0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe,
13508 	0x12, 0x1c, 0x75, 0xfe,
13509 	0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c,
13510 	0x14, 0xfe, 0x0e, 0x47,
13511 	0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
13512 	0xa7, 0x90, 0x34, 0x60,
13513 	0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80,
13514 	0x09, 0x56, 0xfe, 0x34,
13515 	0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48,
13516 	0xfe, 0x45, 0x48, 0x01,
13517 	0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
13518 	0x09, 0x1a, 0xa5, 0x0a,
13519 	0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4,
13520 	0xfe, 0x14, 0x56, 0xfe,
13521 	0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01,
13522 	0xec, 0xb8, 0xfe, 0x9e,
13523 	0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
13524 	0xf4, 0xfe, 0xdd, 0x10,
13525 	0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48,
13526 	0x12, 0x09, 0x0d, 0xfe,
13527 	0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4,
13528 	0x13, 0x09, 0xfe, 0x23,
13529 	0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
13530 	0x24, 0xfe, 0x12, 0x12,
13531 	0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08,
13532 	0xae, 0x41, 0x02, 0x32,
13533 	0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05,
13534 	0x35, 0x32, 0x01, 0x43,
13535 	0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
13536 	0x13, 0x01, 0x0c, 0x06,
13537 	0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe,
13538 	0xe5, 0x55, 0xb0, 0xfe,
13539 	0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e,
13540 	0xfe, 0xb6, 0x0e, 0x10,
13541 	0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
13542 	0x88, 0x20, 0x6e, 0x01,
13543 	0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5,
13544 	0x55, 0xfe, 0x04, 0xfa,
13545 	0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d,
13546 	0xfe, 0x40, 0x56, 0xfe,
13547 	0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
13548 	0x44, 0x55, 0xfe, 0xe5,
13549 	0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10,
13550 	0x68, 0x22, 0x69, 0x01,
13551 	0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b,
13552 	0x6b, 0xfe, 0x2c, 0x50,
13553 	0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
13554 	0x50, 0x03, 0x68, 0x3b,
13555 	0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe,
13556 	0x40, 0x50, 0xfe, 0xc2,
13557 	0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08,
13558 	0x16, 0x3d, 0x27, 0x25,
13559 	0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
13560 	0xa6, 0x23, 0x3f, 0x1b,
13561 	0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c,
13562 	0xfe, 0x0a, 0x55, 0x31,
13563 	0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e,
13564 	0x51, 0x05, 0x72, 0x01,
13565 	0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
13566 	0x2a, 0x3c, 0x16, 0xc0,
13567 	0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b,
13568 	0xfe, 0x66, 0x15, 0x05,
13569 	0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d,
13570 	0x2b, 0x3d, 0x01, 0x08,
13571 	0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
13572 	0xb6, 0x1e, 0x83, 0x01,
13573 	0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46,
13574 	0x07, 0x90, 0x3f, 0x01,
13575 	0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13,
13576 	0x01, 0x43, 0x09, 0x82,
13577 	0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
13578 	0x05, 0x72, 0xfe, 0xc0,
13579 	0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e,
13580 	0x32, 0x01, 0x08, 0x17,
13581 	0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16,
13582 	0x3d, 0x27, 0x25, 0xbd,
13583 	0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
13584 	0xe8, 0x14, 0x01, 0xa6,
13585 	0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe,
13586 	0x0e, 0x12, 0x01, 0x43,
13587 	0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32,
13588 	0x01, 0x08, 0x17, 0x73,
13589 	0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
13590 	0x27, 0x25, 0xbd, 0x09,
13591 	0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe,
13592 	0xb6, 0x14, 0x86, 0xa8,
13593 	0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09,
13594 	0x82, 0x4e, 0x05, 0x72,
13595 	0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
13596 	0xfe, 0xc0, 0x19, 0x05,
13597 	0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f,
13598 	0xcc, 0x01, 0x08, 0x26,
13599 	0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe,
13600 	0xcc, 0x15, 0x5e, 0x32,
13601 	0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
13602 	0xad, 0x23, 0xfe, 0xff,
13603 	0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02,
13604 	0x00, 0x57, 0x52, 0xad,
13605 	0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff,
13606 	0x02, 0x00, 0x57, 0x52,
13607 	0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
13608 	0x02, 0x13, 0x58, 0xff,
13609 	0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01,
13610 	0x5c, 0x0a, 0x55, 0x01,
13611 	0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a,
13612 	0xff, 0x03, 0x00, 0x54,
13613 	0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
13614 	0x7c, 0x3a, 0x0b, 0x0e,
13615 	0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19,
13616 	0xfe, 0x1a, 0xf7, 0x00,
13617 	0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c,
13618 	0xda, 0x6d, 0x02, 0xfe,
13619 	0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
13620 	0x02, 0x01, 0xc6, 0xfe,
13621 	0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27,
13622 	0x25, 0xbe, 0x01, 0x08,
13623 	0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59,
13624 	0x03, 0x9a, 0x1e, 0xfe,
13625 	0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
13626 	0x48, 0xfe, 0x08, 0x17,
13627 	0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26,
13628 	0x17, 0x4d, 0x13, 0x07,
13629 	0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1,
13630 	0xff, 0x02, 0x83, 0x55,
13631 	0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
13632 	0x17, 0x1c, 0x63, 0x13,
13633 	0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64,
13634 	0x00, 0xb0, 0xfe, 0x80,
13635 	0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10,
13636 	0x53, 0x07, 0xfe, 0x60,
13637 	0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
13638 	0x00, 0x1c, 0x95, 0x13,
13639 	0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3,
13640 	0xfe, 0x43, 0xf4, 0x96,
13641 	0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43,
13642 	0xf4, 0x94, 0xf6, 0x8b,
13643 	0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
13644 	0xda, 0x17, 0x62, 0x49,
13645 	0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80,
13646 	0x71, 0x50, 0x26, 0xfe,
13647 	0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3,
13648 	0x58, 0x02, 0x50, 0x13,
13649 	0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
13650 	0x25, 0xbe, 0xfe, 0x03,
13651 	0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9,
13652 	0x0a, 0x01, 0x08, 0x16,
13653 	0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01,
13654 	0x01, 0x08, 0x16, 0xa9,
13655 	0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
13656 	0x08, 0x16, 0xa9, 0x27,
13657 	0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83,
13658 	0x01, 0x38, 0x06, 0x24,
13659 	0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1,
13660 	0x78, 0x03, 0x9a, 0x1e,
13661 	0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
13662 	0xfe, 0x40, 0x5a, 0x23,
13663 	0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c,
13664 	0x80, 0x48, 0xfe, 0xaa,
13665 	0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01,
13666 	0xfe, 0xac, 0x1d, 0xfe,
13667 	0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
13668 	0x43, 0x48, 0x2d, 0x93,
13669 	0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4,
13670 	0x36, 0xfe, 0x34, 0xf4,
13671 	0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe,
13672 	0x28, 0x10, 0xfe, 0xc0,
13673 	0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
13674 	0x18, 0x45, 0xfe, 0x1c,
13675 	0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c,
13676 	0x19, 0xfe, 0x04, 0xf4,
13677 	0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d,
13678 	0x21, 0xfe, 0x7f, 0x01,
13679 	0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
13680 	0x7e, 0x01, 0xfe, 0xc8,
13681 	0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa,
13682 	0x21, 0xfe, 0x81, 0x01,
13683 	0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50,
13684 	0x13, 0x0d, 0x02, 0x14,
13685 	0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
13686 	0xfe, 0x82, 0x19, 0x14,
13687 	0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01,
13688 	0x08, 0x02, 0x14, 0x07,
13689 	0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07,
13690 	0x01, 0x08, 0x17, 0xc1,
13691 	0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
13692 	0x08, 0x02, 0x50, 0x02,
13693 	0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74,
13694 	0x14, 0x12, 0x01, 0x08,
13695 	0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01,
13696 	0x08, 0x17, 0x74, 0xfe,
13697 	0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
13698 	0x74, 0x5f, 0xcc, 0x01,
13699 	0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4,
13700 	0xfe, 0x49, 0xf4, 0x00,
13701 	0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff,
13702 	0x02, 0x00, 0x10, 0x2f,
13703 	0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
13704 	0x16, 0xfe, 0x64, 0x1a,
13705 	0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c,
13706 	0x61, 0x07, 0x44, 0x02,
13707 	0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12,
13708 	0x13, 0x0a, 0x9d, 0x01,
13709 	0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
13710 	0xfe, 0x80, 0xe7, 0x1a,
13711 	0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02,
13712 	0x0a, 0x5a, 0x01, 0x18,
13713 	0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe,
13714 	0x7e, 0x1e, 0xfe, 0x80,
13715 	0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
13716 	0xfe, 0x80, 0x4c, 0x0a,
13717 	0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf,
13718 	0xfe, 0x19, 0xde, 0xfe,
13719 	0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe,
13720 	0x2a, 0x1c, 0xfa, 0xb3,
13721 	0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
13722 	0xf4, 0x1a, 0xfe, 0xfa,
13723 	0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24,
13724 	0xfe, 0x18, 0x58, 0x03,
13725 	0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f,
13726 	0xfe, 0x30, 0xf4, 0x07,
13727 	0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
13728 	0xf7, 0x24, 0xb1, 0xfe,
13729 	0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b,
13730 	0xfe, 0xba, 0x10, 0x1c,
13731 	0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
13732 	0x1d, 0xf7, 0x54, 0xb1,
13733 	0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
13734 	0xaf, 0x19, 0xfe, 0x98,
13735 	0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c,
13736 	0x1a, 0x87, 0x8b, 0x0f,
13737 	0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58,
13738 	0xfe, 0x32, 0x90, 0x04,
13739 	0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
13740 	0x7c, 0x12, 0xfe, 0x0f,
13741 	0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14,
13742 	0x31, 0x02, 0xc9, 0x2b,
13743 	0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe,
13744 	0x6a, 0xfe, 0x19, 0xfe,
13745 	0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
13746 	0x1b, 0xfe, 0x36, 0x14,
13747 	0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19,
13748 	0xfe, 0x80, 0xe7, 0x1a,
13749 	0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a,
13750 	0x30, 0xfe, 0x12, 0x45,
13751 	0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
13752 	0x39, 0xf0, 0x75, 0x26,
13753 	0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03,
13754 	0xe3, 0x23, 0x07, 0xfe,
13755 	0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09,
13756 	0x56, 0xfe, 0x3c, 0x13,
13757 	0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
13758 	0x01, 0x18, 0xcb, 0xfe,
13759 	0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16,
13760 	0xfe, 0x00, 0xcc, 0xcb,
13761 	0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18,
13762 	0xfe, 0x80, 0x4c, 0x01,
13763 	0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
13764 	0x12, 0xfe, 0x14, 0x56,
13765 	0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7,
13766 	0x0d, 0x19, 0xfe, 0x15,
13767 	0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06,
13768 	0x83, 0xfe, 0x18, 0x80,
13769 	0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
13770 	0x90, 0xfe, 0xba, 0x90,
13771 	0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02,
13772 	0x21, 0xb9, 0x88, 0x20,
13773 	0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01,
13774 	0x18, 0xfe, 0x49, 0x44,
13775 	0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
13776 	0x1a, 0xa4, 0x0a, 0x67,
13777 	0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4,
13778 	0x1d, 0x7b, 0xfe, 0x52,
13779 	0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe,
13780 	0x4e, 0xe4, 0xdd, 0x7b,
13781 	0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
13782 	0xfe, 0x4e, 0xe4, 0xfe,
13783 	0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24,
13784 	0xfe, 0x08, 0x10, 0x03,
13785 	0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04,
13786 	0x68, 0x54, 0xfe, 0xf1,
13787 	0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
13788 	0xfe, 0x1a, 0xf4, 0xfe,
13789 	0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02,
13790 	0x09, 0x92, 0xfe, 0x5a,
13791 	0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe,
13792 	0x5a, 0xf0, 0xfe, 0xc8,
13793 	0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
13794 	0x1a, 0x10, 0x09, 0x0d,
13795 	0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02,
13796 	0x1f, 0x93, 0x01, 0x42,
13797 	0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e,
13798 	0xfe, 0x14, 0xf0, 0x08,
13799 	0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
13800 	0xfe, 0x82, 0xf0, 0xfe,
13801 	0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e,
13802 	0x02, 0x0f, 0xfe, 0x18,
13803 	0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02,
13804 	0x80, 0x04, 0xfe, 0x82,
13805 	0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
13806 	0x83, 0x33, 0x0b, 0x0e,
13807 	0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e,
13808 	0x02, 0x0f, 0xfe, 0x04,
13809 	0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80,
13810 	0x80, 0x04, 0xfe, 0x80,
13811 	0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
13812 	0xfe, 0x99, 0x83, 0xfe,
13813 	0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86,
13814 	0x83, 0xfe, 0xce, 0x47,
13815 	0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a,
13816 	0x0b, 0x0e, 0x02, 0x0f,
13817 	0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13818 	0xfe, 0x08, 0x90, 0x04,
13819 	0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04,
13820 	0xfe, 0x8a, 0x93, 0x79,
13821 	0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a,
13822 	0x0b, 0x0e, 0x02, 0x0f,
13823 	0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13824 	0xfe, 0x3c, 0x90, 0x04,
13825 	0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80,
13826 	0x04, 0xfe, 0x83, 0x83,
13827 	0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
13828 };
13829 
13830 static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf);	/* 0x1673 */
13831 static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL;	/* Expanded little-endian checksum. */
13832 
13833 /* a_init.c */
13834 /*
13835  * EEPROM Configuration.
13836  *
13837  * All drivers should use this structure to set the default EEPROM
13838  * configuration. The BIOS now uses this structure when it is built.
13839  * Additional structure information can be found in a_condor.h where
13840  * the structure is defined.
13841  *
13842  * The *_Field_IsChar structs are needed to correct for endianness.
13843  * These values are read from the board 16 bits at a time directly
13844  * into the structs. Because some fields are char, the values will be
13845  * in the wrong order. The *_Field_IsChar tells when to flip the
13846  * bytes. Data read and written to PCI memory is automatically swapped
13847  * on big-endian platforms so char fields read as words are actually being
13848  * unswapped on big-endian platforms.
13849  */
13850 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __initdata = {
13851 	ADV_EEPROM_BIOS_ENABLE,	/* cfg_lsw */
13852 	0x0000,			/* cfg_msw */
13853 	0xFFFF,			/* disc_enable */
13854 	0xFFFF,			/* wdtr_able */
13855 	0xFFFF,			/* sdtr_able */
13856 	0xFFFF,			/* start_motor */
13857 	0xFFFF,			/* tagqng_able */
13858 	0xFFFF,			/* bios_scan */
13859 	0,			/* scam_tolerant */
13860 	7,			/* adapter_scsi_id */
13861 	0,			/* bios_boot_delay */
13862 	3,			/* scsi_reset_delay */
13863 	0,			/* bios_id_lun */
13864 	0,			/* termination */
13865 	0,			/* reserved1 */
13866 	0xFFE7,			/* bios_ctrl */
13867 	0xFFFF,			/* ultra_able */
13868 	0,			/* reserved2 */
13869 	ASC_DEF_MAX_HOST_QNG,	/* max_host_qng */
13870 	ASC_DEF_MAX_DVC_QNG,	/* max_dvc_qng */
13871 	0,			/* dvc_cntl */
13872 	0,			/* bug_fix */
13873 	0,			/* serial_number_word1 */
13874 	0,			/* serial_number_word2 */
13875 	0,			/* serial_number_word3 */
13876 	0,			/* check_sum */
13877 	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13878 	,			/* oem_name[16] */
13879 	0,			/* dvc_err_code */
13880 	0,			/* adv_err_code */
13881 	0,			/* adv_err_addr */
13882 	0,			/* saved_dvc_err_code */
13883 	0,			/* saved_adv_err_code */
13884 	0,			/* saved_adv_err_addr */
13885 	0			/* num_of_err */
13886 };
13887 
13888 static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __initdata = {
13889 	0,			/* cfg_lsw */
13890 	0,			/* cfg_msw */
13891 	0,			/* -disc_enable */
13892 	0,			/* wdtr_able */
13893 	0,			/* sdtr_able */
13894 	0,			/* start_motor */
13895 	0,			/* tagqng_able */
13896 	0,			/* bios_scan */
13897 	0,			/* scam_tolerant */
13898 	1,			/* adapter_scsi_id */
13899 	1,			/* bios_boot_delay */
13900 	1,			/* scsi_reset_delay */
13901 	1,			/* bios_id_lun */
13902 	1,			/* termination */
13903 	1,			/* reserved1 */
13904 	0,			/* bios_ctrl */
13905 	0,			/* ultra_able */
13906 	0,			/* reserved2 */
13907 	1,			/* max_host_qng */
13908 	1,			/* max_dvc_qng */
13909 	0,			/* dvc_cntl */
13910 	0,			/* bug_fix */
13911 	0,			/* serial_number_word1 */
13912 	0,			/* serial_number_word2 */
13913 	0,			/* serial_number_word3 */
13914 	0,			/* check_sum */
13915 	{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13916 	,			/* oem_name[16] */
13917 	0,			/* dvc_err_code */
13918 	0,			/* adv_err_code */
13919 	0,			/* adv_err_addr */
13920 	0,			/* saved_dvc_err_code */
13921 	0,			/* saved_adv_err_code */
13922 	0,			/* saved_adv_err_addr */
13923 	0			/* num_of_err */
13924 };
13925 
13926 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __initdata = {
13927 	ADV_EEPROM_BIOS_ENABLE,	/* 00 cfg_lsw */
13928 	0x0000,			/* 01 cfg_msw */
13929 	0xFFFF,			/* 02 disc_enable */
13930 	0xFFFF,			/* 03 wdtr_able */
13931 	0x4444,			/* 04 sdtr_speed1 */
13932 	0xFFFF,			/* 05 start_motor */
13933 	0xFFFF,			/* 06 tagqng_able */
13934 	0xFFFF,			/* 07 bios_scan */
13935 	0,			/* 08 scam_tolerant */
13936 	7,			/* 09 adapter_scsi_id */
13937 	0,			/*    bios_boot_delay */
13938 	3,			/* 10 scsi_reset_delay */
13939 	0,			/*    bios_id_lun */
13940 	0,			/* 11 termination_se */
13941 	0,			/*    termination_lvd */
13942 	0xFFE7,			/* 12 bios_ctrl */
13943 	0x4444,			/* 13 sdtr_speed2 */
13944 	0x4444,			/* 14 sdtr_speed3 */
13945 	ASC_DEF_MAX_HOST_QNG,	/* 15 max_host_qng */
13946 	ASC_DEF_MAX_DVC_QNG,	/*    max_dvc_qng */
13947 	0,			/* 16 dvc_cntl */
13948 	0x4444,			/* 17 sdtr_speed4 */
13949 	0,			/* 18 serial_number_word1 */
13950 	0,			/* 19 serial_number_word2 */
13951 	0,			/* 20 serial_number_word3 */
13952 	0,			/* 21 check_sum */
13953 	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13954 	,			/* 22-29 oem_name[16] */
13955 	0,			/* 30 dvc_err_code */
13956 	0,			/* 31 adv_err_code */
13957 	0,			/* 32 adv_err_addr */
13958 	0,			/* 33 saved_dvc_err_code */
13959 	0,			/* 34 saved_adv_err_code */
13960 	0,			/* 35 saved_adv_err_addr */
13961 	0,			/* 36 reserved */
13962 	0,			/* 37 reserved */
13963 	0,			/* 38 reserved */
13964 	0,			/* 39 reserved */
13965 	0,			/* 40 reserved */
13966 	0,			/* 41 reserved */
13967 	0,			/* 42 reserved */
13968 	0,			/* 43 reserved */
13969 	0,			/* 44 reserved */
13970 	0,			/* 45 reserved */
13971 	0,			/* 46 reserved */
13972 	0,			/* 47 reserved */
13973 	0,			/* 48 reserved */
13974 	0,			/* 49 reserved */
13975 	0,			/* 50 reserved */
13976 	0,			/* 51 reserved */
13977 	0,			/* 52 reserved */
13978 	0,			/* 53 reserved */
13979 	0,			/* 54 reserved */
13980 	0,			/* 55 reserved */
13981 	0,			/* 56 cisptr_lsw */
13982 	0,			/* 57 cisprt_msw */
13983 	PCI_VENDOR_ID_ASP,	/* 58 subsysvid */
13984 	PCI_DEVICE_ID_38C0800_REV1,	/* 59 subsysid */
13985 	0,			/* 60 reserved */
13986 	0,			/* 61 reserved */
13987 	0,			/* 62 reserved */
13988 	0			/* 63 reserved */
13989 };
13990 
13991 static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __initdata = {
13992 	0,			/* 00 cfg_lsw */
13993 	0,			/* 01 cfg_msw */
13994 	0,			/* 02 disc_enable */
13995 	0,			/* 03 wdtr_able */
13996 	0,			/* 04 sdtr_speed1 */
13997 	0,			/* 05 start_motor */
13998 	0,			/* 06 tagqng_able */
13999 	0,			/* 07 bios_scan */
14000 	0,			/* 08 scam_tolerant */
14001 	1,			/* 09 adapter_scsi_id */
14002 	1,			/*    bios_boot_delay */
14003 	1,			/* 10 scsi_reset_delay */
14004 	1,			/*    bios_id_lun */
14005 	1,			/* 11 termination_se */
14006 	1,			/*    termination_lvd */
14007 	0,			/* 12 bios_ctrl */
14008 	0,			/* 13 sdtr_speed2 */
14009 	0,			/* 14 sdtr_speed3 */
14010 	1,			/* 15 max_host_qng */
14011 	1,			/*    max_dvc_qng */
14012 	0,			/* 16 dvc_cntl */
14013 	0,			/* 17 sdtr_speed4 */
14014 	0,			/* 18 serial_number_word1 */
14015 	0,			/* 19 serial_number_word2 */
14016 	0,			/* 20 serial_number_word3 */
14017 	0,			/* 21 check_sum */
14018 	{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
14019 	,			/* 22-29 oem_name[16] */
14020 	0,			/* 30 dvc_err_code */
14021 	0,			/* 31 adv_err_code */
14022 	0,			/* 32 adv_err_addr */
14023 	0,			/* 33 saved_dvc_err_code */
14024 	0,			/* 34 saved_adv_err_code */
14025 	0,			/* 35 saved_adv_err_addr */
14026 	0,			/* 36 reserved */
14027 	0,			/* 37 reserved */
14028 	0,			/* 38 reserved */
14029 	0,			/* 39 reserved */
14030 	0,			/* 40 reserved */
14031 	0,			/* 41 reserved */
14032 	0,			/* 42 reserved */
14033 	0,			/* 43 reserved */
14034 	0,			/* 44 reserved */
14035 	0,			/* 45 reserved */
14036 	0,			/* 46 reserved */
14037 	0,			/* 47 reserved */
14038 	0,			/* 48 reserved */
14039 	0,			/* 49 reserved */
14040 	0,			/* 50 reserved */
14041 	0,			/* 51 reserved */
14042 	0,			/* 52 reserved */
14043 	0,			/* 53 reserved */
14044 	0,			/* 54 reserved */
14045 	0,			/* 55 reserved */
14046 	0,			/* 56 cisptr_lsw */
14047 	0,			/* 57 cisprt_msw */
14048 	0,			/* 58 subsysvid */
14049 	0,			/* 59 subsysid */
14050 	0,			/* 60 reserved */
14051 	0,			/* 61 reserved */
14052 	0,			/* 62 reserved */
14053 	0			/* 63 reserved */
14054 };
14055 
14056 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __initdata = {
14057 	ADV_EEPROM_BIOS_ENABLE,	/* 00 cfg_lsw */
14058 	0x0000,			/* 01 cfg_msw */
14059 	0xFFFF,			/* 02 disc_enable */
14060 	0xFFFF,			/* 03 wdtr_able */
14061 	0x5555,			/* 04 sdtr_speed1 */
14062 	0xFFFF,			/* 05 start_motor */
14063 	0xFFFF,			/* 06 tagqng_able */
14064 	0xFFFF,			/* 07 bios_scan */
14065 	0,			/* 08 scam_tolerant */
14066 	7,			/* 09 adapter_scsi_id */
14067 	0,			/*    bios_boot_delay */
14068 	3,			/* 10 scsi_reset_delay */
14069 	0,			/*    bios_id_lun */
14070 	0,			/* 11 termination_se */
14071 	0,			/*    termination_lvd */
14072 	0xFFE7,			/* 12 bios_ctrl */
14073 	0x5555,			/* 13 sdtr_speed2 */
14074 	0x5555,			/* 14 sdtr_speed3 */
14075 	ASC_DEF_MAX_HOST_QNG,	/* 15 max_host_qng */
14076 	ASC_DEF_MAX_DVC_QNG,	/*    max_dvc_qng */
14077 	0,			/* 16 dvc_cntl */
14078 	0x5555,			/* 17 sdtr_speed4 */
14079 	0,			/* 18 serial_number_word1 */
14080 	0,			/* 19 serial_number_word2 */
14081 	0,			/* 20 serial_number_word3 */
14082 	0,			/* 21 check_sum */
14083 	{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
14084 	,			/* 22-29 oem_name[16] */
14085 	0,			/* 30 dvc_err_code */
14086 	0,			/* 31 adv_err_code */
14087 	0,			/* 32 adv_err_addr */
14088 	0,			/* 33 saved_dvc_err_code */
14089 	0,			/* 34 saved_adv_err_code */
14090 	0,			/* 35 saved_adv_err_addr */
14091 	0,			/* 36 reserved */
14092 	0,			/* 37 reserved */
14093 	0,			/* 38 reserved */
14094 	0,			/* 39 reserved */
14095 	0,			/* 40 reserved */
14096 	0,			/* 41 reserved */
14097 	0,			/* 42 reserved */
14098 	0,			/* 43 reserved */
14099 	0,			/* 44 reserved */
14100 	0,			/* 45 reserved */
14101 	0,			/* 46 reserved */
14102 	0,			/* 47 reserved */
14103 	0,			/* 48 reserved */
14104 	0,			/* 49 reserved */
14105 	0,			/* 50 reserved */
14106 	0,			/* 51 reserved */
14107 	0,			/* 52 reserved */
14108 	0,			/* 53 reserved */
14109 	0,			/* 54 reserved */
14110 	0,			/* 55 reserved */
14111 	0,			/* 56 cisptr_lsw */
14112 	0,			/* 57 cisprt_msw */
14113 	PCI_VENDOR_ID_ASP,	/* 58 subsysvid */
14114 	PCI_DEVICE_ID_38C1600_REV1,	/* 59 subsysid */
14115 	0,			/* 60 reserved */
14116 	0,			/* 61 reserved */
14117 	0,			/* 62 reserved */
14118 	0			/* 63 reserved */
14119 };
14120 
14121 static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __initdata = {
14122 	0,			/* 00 cfg_lsw */
14123 	0,			/* 01 cfg_msw */
14124 	0,			/* 02 disc_enable */
14125 	0,			/* 03 wdtr_able */
14126 	0,			/* 04 sdtr_speed1 */
14127 	0,			/* 05 start_motor */
14128 	0,			/* 06 tagqng_able */
14129 	0,			/* 07 bios_scan */
14130 	0,			/* 08 scam_tolerant */
14131 	1,			/* 09 adapter_scsi_id */
14132 	1,			/*    bios_boot_delay */
14133 	1,			/* 10 scsi_reset_delay */
14134 	1,			/*    bios_id_lun */
14135 	1,			/* 11 termination_se */
14136 	1,			/*    termination_lvd */
14137 	0,			/* 12 bios_ctrl */
14138 	0,			/* 13 sdtr_speed2 */
14139 	0,			/* 14 sdtr_speed3 */
14140 	1,			/* 15 max_host_qng */
14141 	1,			/*    max_dvc_qng */
14142 	0,			/* 16 dvc_cntl */
14143 	0,			/* 17 sdtr_speed4 */
14144 	0,			/* 18 serial_number_word1 */
14145 	0,			/* 19 serial_number_word2 */
14146 	0,			/* 20 serial_number_word3 */
14147 	0,			/* 21 check_sum */
14148 	{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
14149 	,			/* 22-29 oem_name[16] */
14150 	0,			/* 30 dvc_err_code */
14151 	0,			/* 31 adv_err_code */
14152 	0,			/* 32 adv_err_addr */
14153 	0,			/* 33 saved_dvc_err_code */
14154 	0,			/* 34 saved_adv_err_code */
14155 	0,			/* 35 saved_adv_err_addr */
14156 	0,			/* 36 reserved */
14157 	0,			/* 37 reserved */
14158 	0,			/* 38 reserved */
14159 	0,			/* 39 reserved */
14160 	0,			/* 40 reserved */
14161 	0,			/* 41 reserved */
14162 	0,			/* 42 reserved */
14163 	0,			/* 43 reserved */
14164 	0,			/* 44 reserved */
14165 	0,			/* 45 reserved */
14166 	0,			/* 46 reserved */
14167 	0,			/* 47 reserved */
14168 	0,			/* 48 reserved */
14169 	0,			/* 49 reserved */
14170 	0,			/* 50 reserved */
14171 	0,			/* 51 reserved */
14172 	0,			/* 52 reserved */
14173 	0,			/* 53 reserved */
14174 	0,			/* 54 reserved */
14175 	0,			/* 55 reserved */
14176 	0,			/* 56 cisptr_lsw */
14177 	0,			/* 57 cisprt_msw */
14178 	0,			/* 58 subsysvid */
14179 	0,			/* 59 subsysid */
14180 	0,			/* 60 reserved */
14181 	0,			/* 61 reserved */
14182 	0,			/* 62 reserved */
14183 	0			/* 63 reserved */
14184 };
14185 
14186 /*
14187  * Initialize the ADV_DVC_VAR structure.
14188  *
14189  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14190  *
14191  * For a non-fatal error return a warning code. If there are no warnings
14192  * then 0 is returned.
14193  */
14194 static int __init AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
14195 {
14196 	ushort warn_code;
14197 	AdvPortAddr iop_base;
14198 	uchar pci_cmd_reg;
14199 	int status;
14200 
14201 	warn_code = 0;
14202 	asc_dvc->err_code = 0;
14203 	iop_base = asc_dvc->iop_base;
14204 
14205 	/*
14206 	 * PCI Command Register
14207 	 *
14208 	 * Note: AscPCICmdRegBits_BusMastering definition (0x0007) includes
14209 	 * I/O Space Control, Memory Space Control and Bus Master Control bits.
14210 	 */
14211 
14212 	if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
14213 						    AscPCIConfigCommandRegister))
14214 	     & AscPCICmdRegBits_BusMastering)
14215 	    != AscPCICmdRegBits_BusMastering) {
14216 		pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
14217 
14218 		DvcAdvWritePCIConfigByte(asc_dvc,
14219 					 AscPCIConfigCommandRegister,
14220 					 pci_cmd_reg);
14221 
14222 		if (((DvcAdvReadPCIConfigByte
14223 		      (asc_dvc, AscPCIConfigCommandRegister))
14224 		     & AscPCICmdRegBits_BusMastering)
14225 		    != AscPCICmdRegBits_BusMastering) {
14226 			warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14227 		}
14228 	}
14229 
14230 	/*
14231 	 * PCI Latency Timer
14232 	 *
14233 	 * If the "latency timer" register is 0x20 or above, then we don't need
14234 	 * to change it.  Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
14235 	 * comes up less than 0x20).
14236 	 */
14237 	if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
14238 		DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer,
14239 					 0x20);
14240 		if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) <
14241 		    0x20) {
14242 			warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14243 		}
14244 	}
14245 
14246 	/*
14247 	 * Save the state of the PCI Configuration Command Register
14248 	 * "Parity Error Response Control" Bit. If the bit is clear (0),
14249 	 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
14250 	 * DMA parity errors.
14251 	 */
14252 	asc_dvc->cfg->control_flag = 0;
14253 	if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
14254 	      & AscPCICmdRegBits_ParErrRespCtrl)) == 0) {
14255 		asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
14256 	}
14257 
14258 	asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
14259 	    ADV_LIB_VERSION_MINOR;
14260 	asc_dvc->cfg->chip_version =
14261 	    AdvGetChipVersion(iop_base, asc_dvc->bus_type);
14262 
14263 	ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
14264 		 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
14265 		 (ushort)ADV_CHIP_ID_BYTE);
14266 
14267 	ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
14268 		 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
14269 		 (ushort)ADV_CHIP_ID_WORD);
14270 
14271 	/*
14272 	 * Reset the chip to start and allow register writes.
14273 	 */
14274 	if (AdvFindSignature(iop_base) == 0) {
14275 		asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
14276 		return ADV_ERROR;
14277 	} else {
14278 		/*
14279 		 * The caller must set 'chip_type' to a valid setting.
14280 		 */
14281 		if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
14282 		    asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
14283 		    asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
14284 			asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14285 			return ADV_ERROR;
14286 		}
14287 
14288 		/*
14289 		 * Reset Chip.
14290 		 */
14291 		AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14292 				     ADV_CTRL_REG_CMD_RESET);
14293 		DvcSleepMilliSecond(100);
14294 		AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14295 				     ADV_CTRL_REG_CMD_WR_IO_REG);
14296 
14297 		if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
14298 			if ((status =
14299 			     AdvInitFrom38C1600EEP(asc_dvc)) == ADV_ERROR) {
14300 				return ADV_ERROR;
14301 			}
14302 		} else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
14303 			if ((status =
14304 			     AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR) {
14305 				return ADV_ERROR;
14306 			}
14307 		} else {
14308 			if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR) {
14309 				return ADV_ERROR;
14310 			}
14311 		}
14312 		warn_code |= status;
14313 	}
14314 
14315 	return warn_code;
14316 }
14317 
14318 /*
14319  * Initialize the ASC-3550.
14320  *
14321  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14322  *
14323  * For a non-fatal error return a warning code. If there are no warnings
14324  * then 0 is returned.
14325  *
14326  * Needed after initialization for error recovery.
14327  */
14328 static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
14329 {
14330 	AdvPortAddr iop_base;
14331 	ushort warn_code;
14332 	ADV_DCNT sum;
14333 	int begin_addr;
14334 	int end_addr;
14335 	ushort code_sum;
14336 	int word;
14337 	int j;
14338 	int adv_asc3550_expanded_size;
14339 	ADV_CARR_T *carrp;
14340 	ADV_DCNT contig_len;
14341 	ADV_SDCNT buf_size;
14342 	ADV_PADDR carr_paddr;
14343 	int i;
14344 	ushort scsi_cfg1;
14345 	uchar tid;
14346 	ushort bios_mem[ASC_MC_BIOSLEN / 2];	/* BIOS RISC Memory 0x40-0x8F. */
14347 	ushort wdtr_able = 0, sdtr_able, tagqng_able;
14348 	uchar max_cmd[ADV_MAX_TID + 1];
14349 
14350 	/* If there is already an error, don't continue. */
14351 	if (asc_dvc->err_code != 0) {
14352 		return ADV_ERROR;
14353 	}
14354 
14355 	/*
14356 	 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
14357 	 */
14358 	if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
14359 		asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14360 		return ADV_ERROR;
14361 	}
14362 
14363 	warn_code = 0;
14364 	iop_base = asc_dvc->iop_base;
14365 
14366 	/*
14367 	 * Save the RISC memory BIOS region before writing the microcode.
14368 	 * The BIOS may already be loaded and using its RISC LRAM region
14369 	 * so its region must be saved and restored.
14370 	 *
14371 	 * Note: This code makes the assumption, which is currently true,
14372 	 * that a chip reset does not clear RISC LRAM.
14373 	 */
14374 	for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14375 		AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14376 				bios_mem[i]);
14377 	}
14378 
14379 	/*
14380 	 * Save current per TID negotiated values.
14381 	 */
14382 	if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
14383 		ushort bios_version, major, minor;
14384 
14385 		bios_version =
14386 		    bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
14387 		major = (bios_version >> 12) & 0xF;
14388 		minor = (bios_version >> 8) & 0xF;
14389 		if (major < 3 || (major == 3 && minor == 1)) {
14390 			/* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
14391 			AdvReadWordLram(iop_base, 0x120, wdtr_able);
14392 		} else {
14393 			AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14394 		}
14395 	}
14396 	AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14397 	AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14398 	for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14399 		AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14400 				max_cmd[tid]);
14401 	}
14402 
14403 	/*
14404 	 * Load the Microcode
14405 	 *
14406 	 * Write the microcode image to RISC memory starting at address 0.
14407 	 */
14408 	AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14409 	/* Assume the following compressed format of the microcode buffer:
14410 	 *
14411 	 *  254 word (508 byte) table indexed by byte code followed
14412 	 *  by the following byte codes:
14413 	 *
14414 	 *    1-Byte Code:
14415 	 *      00: Emit word 0 in table.
14416 	 *      01: Emit word 1 in table.
14417 	 *      .
14418 	 *      FD: Emit word 253 in table.
14419 	 *
14420 	 *    Multi-Byte Code:
14421 	 *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14422 	 *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14423 	 */
14424 	word = 0;
14425 	for (i = 253 * 2; i < _adv_asc3550_size; i++) {
14426 		if (_adv_asc3550_buf[i] == 0xff) {
14427 			for (j = 0; j < _adv_asc3550_buf[i + 1]; j++) {
14428 				AdvWriteWordAutoIncLram(iop_base, (((ushort)
14429 								    _adv_asc3550_buf
14430 								    [i +
14431 								     3] << 8) |
14432 								   _adv_asc3550_buf
14433 								   [i + 2]));
14434 				word++;
14435 			}
14436 			i += 3;
14437 		} else if (_adv_asc3550_buf[i] == 0xfe) {
14438 			AdvWriteWordAutoIncLram(iop_base, (((ushort)
14439 							    _adv_asc3550_buf[i +
14440 									     2]
14441 							    << 8) |
14442 							   _adv_asc3550_buf[i +
14443 									    1]));
14444 			i += 2;
14445 			word++;
14446 		} else {
14447 			AdvWriteWordAutoIncLram(iop_base, (((ushort)
14448 							    _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) | _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
14449 			word++;
14450 		}
14451 	}
14452 
14453 	/*
14454 	 * Set 'word' for later use to clear the rest of memory and save
14455 	 * the expanded mcode size.
14456 	 */
14457 	word *= 2;
14458 	adv_asc3550_expanded_size = word;
14459 
14460 	/*
14461 	 * Clear the rest of ASC-3550 Internal RAM (8KB).
14462 	 */
14463 	for (; word < ADV_3550_MEMSIZE; word += 2) {
14464 		AdvWriteWordAutoIncLram(iop_base, 0);
14465 	}
14466 
14467 	/*
14468 	 * Verify the microcode checksum.
14469 	 */
14470 	sum = 0;
14471 	AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14472 
14473 	for (word = 0; word < adv_asc3550_expanded_size; word += 2) {
14474 		sum += AdvReadWordAutoIncLram(iop_base);
14475 	}
14476 
14477 	if (sum != _adv_asc3550_chksum) {
14478 		asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14479 		return ADV_ERROR;
14480 	}
14481 
14482 	/*
14483 	 * Restore the RISC memory BIOS region.
14484 	 */
14485 	for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14486 		AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14487 				 bios_mem[i]);
14488 	}
14489 
14490 	/*
14491 	 * Calculate and write the microcode code checksum to the microcode
14492 	 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14493 	 */
14494 	AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14495 	AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14496 	code_sum = 0;
14497 	AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14498 	for (word = begin_addr; word < end_addr; word += 2) {
14499 		code_sum += AdvReadWordAutoIncLram(iop_base);
14500 	}
14501 	AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14502 
14503 	/*
14504 	 * Read and save microcode version and date.
14505 	 */
14506 	AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
14507 			asc_dvc->cfg->mcode_date);
14508 	AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
14509 			asc_dvc->cfg->mcode_version);
14510 
14511 	/*
14512 	 * Set the chip type to indicate the ASC3550.
14513 	 */
14514 	AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
14515 
14516 	/*
14517 	 * If the PCI Configuration Command Register "Parity Error Response
14518 	 * Control" Bit was clear (0), then set the microcode variable
14519 	 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14520 	 * to ignore DMA parity errors.
14521 	 */
14522 	if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
14523 		AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14524 		word |= CONTROL_FLAG_IGNORE_PERR;
14525 		AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14526 	}
14527 
14528 	/*
14529 	 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
14530 	 * threshold of 128 bytes. This register is only accessible to the host.
14531 	 */
14532 	AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14533 			     START_CTL_EMFU | READ_CMD_MRM);
14534 
14535 	/*
14536 	 * Microcode operating variables for WDTR, SDTR, and command tag
14537 	 * queuing will be set in AdvInquiryHandling() based on what a
14538 	 * device reports it is capable of in Inquiry byte 7.
14539 	 *
14540 	 * If SCSI Bus Resets have been disabled, then directly set
14541 	 * SDTR and WDTR from the EEPROM configuration. This will allow
14542 	 * the BIOS and warm boot to work without a SCSI bus hang on
14543 	 * the Inquiry caused by host and target mismatched DTR values.
14544 	 * Without the SCSI Bus Reset, before an Inquiry a device can't
14545 	 * be assumed to be in Asynchronous, Narrow mode.
14546 	 */
14547 	if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
14548 		AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
14549 				 asc_dvc->wdtr_able);
14550 		AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
14551 				 asc_dvc->sdtr_able);
14552 	}
14553 
14554 	/*
14555 	 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
14556 	 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
14557 	 * bitmask. These values determine the maximum SDTR speed negotiated
14558 	 * with a device.
14559 	 *
14560 	 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14561 	 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14562 	 * without determining here whether the device supports SDTR.
14563 	 *
14564 	 * 4-bit speed  SDTR speed name
14565 	 * ===========  ===============
14566 	 * 0000b (0x0)  SDTR disabled
14567 	 * 0001b (0x1)  5 Mhz
14568 	 * 0010b (0x2)  10 Mhz
14569 	 * 0011b (0x3)  20 Mhz (Ultra)
14570 	 * 0100b (0x4)  40 Mhz (LVD/Ultra2)
14571 	 * 0101b (0x5)  80 Mhz (LVD2/Ultra3)
14572 	 * 0110b (0x6)  Undefined
14573 	 * .
14574 	 * 1111b (0xF)  Undefined
14575 	 */
14576 	word = 0;
14577 	for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14578 		if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
14579 			/* Set Ultra speed for TID 'tid'. */
14580 			word |= (0x3 << (4 * (tid % 4)));
14581 		} else {
14582 			/* Set Fast speed for TID 'tid'. */
14583 			word |= (0x2 << (4 * (tid % 4)));
14584 		}
14585 		if (tid == 3) {	/* Check if done with sdtr_speed1. */
14586 			AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
14587 			word = 0;
14588 		} else if (tid == 7) {	/* Check if done with sdtr_speed2. */
14589 			AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
14590 			word = 0;
14591 		} else if (tid == 11) {	/* Check if done with sdtr_speed3. */
14592 			AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
14593 			word = 0;
14594 		} else if (tid == 15) {	/* Check if done with sdtr_speed4. */
14595 			AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
14596 			/* End of loop. */
14597 		}
14598 	}
14599 
14600 	/*
14601 	 * Set microcode operating variable for the disconnect per TID bitmask.
14602 	 */
14603 	AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
14604 			 asc_dvc->cfg->disc_enable);
14605 
14606 	/*
14607 	 * Set SCSI_CFG0 Microcode Default Value.
14608 	 *
14609 	 * The microcode will set the SCSI_CFG0 register using this value
14610 	 * after it is started below.
14611 	 */
14612 	AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14613 			 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14614 			 asc_dvc->chip_scsi_id);
14615 
14616 	/*
14617 	 * Determine SCSI_CFG1 Microcode Default Value.
14618 	 *
14619 	 * The microcode will set the SCSI_CFG1 register using this value
14620 	 * after it is started below.
14621 	 */
14622 
14623 	/* Read current SCSI_CFG1 Register value. */
14624 	scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14625 
14626 	/*
14627 	 * If all three connectors are in use, return an error.
14628 	 */
14629 	if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
14630 	    (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
14631 		asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
14632 		return ADV_ERROR;
14633 	}
14634 
14635 	/*
14636 	 * If the internal narrow cable is reversed all of the SCSI_CTRL
14637 	 * register signals will be set. Check for and return an error if
14638 	 * this condition is found.
14639 	 */
14640 	if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
14641 		asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14642 		return ADV_ERROR;
14643 	}
14644 
14645 	/*
14646 	 * If this is a differential board and a single-ended device
14647 	 * is attached to one of the connectors, return an error.
14648 	 */
14649 	if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
14650 		asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
14651 		return ADV_ERROR;
14652 	}
14653 
14654 	/*
14655 	 * If automatic termination control is enabled, then set the
14656 	 * termination value based on a table listed in a_condor.h.
14657 	 *
14658 	 * If manual termination was specified with an EEPROM setting
14659 	 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
14660 	 * is ready to be 'ored' into SCSI_CFG1.
14661 	 */
14662 	if (asc_dvc->cfg->termination == 0) {
14663 		/*
14664 		 * The software always controls termination by setting TERM_CTL_SEL.
14665 		 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
14666 		 */
14667 		asc_dvc->cfg->termination |= TERM_CTL_SEL;
14668 
14669 		switch (scsi_cfg1 & CABLE_DETECT) {
14670 			/* TERM_CTL_H: on, TERM_CTL_L: on */
14671 		case 0x3:
14672 		case 0x7:
14673 		case 0xB:
14674 		case 0xD:
14675 		case 0xE:
14676 		case 0xF:
14677 			asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
14678 			break;
14679 
14680 			/* TERM_CTL_H: on, TERM_CTL_L: off */
14681 		case 0x1:
14682 		case 0x5:
14683 		case 0x9:
14684 		case 0xA:
14685 		case 0xC:
14686 			asc_dvc->cfg->termination |= TERM_CTL_H;
14687 			break;
14688 
14689 			/* TERM_CTL_H: off, TERM_CTL_L: off */
14690 		case 0x2:
14691 		case 0x6:
14692 			break;
14693 		}
14694 	}
14695 
14696 	/*
14697 	 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
14698 	 */
14699 	scsi_cfg1 &= ~TERM_CTL;
14700 
14701 	/*
14702 	 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
14703 	 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
14704 	 * referenced, because the hardware internally inverts
14705 	 * the Termination High and Low bits if TERM_POL is set.
14706 	 */
14707 	scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
14708 
14709 	/*
14710 	 * Set SCSI_CFG1 Microcode Default Value
14711 	 *
14712 	 * Set filter value and possibly modified termination control
14713 	 * bits in the Microcode SCSI_CFG1 Register Value.
14714 	 *
14715 	 * The microcode will set the SCSI_CFG1 register using this value
14716 	 * after it is started below.
14717 	 */
14718 	AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
14719 			 FLTR_DISABLE | scsi_cfg1);
14720 
14721 	/*
14722 	 * Set MEM_CFG Microcode Default Value
14723 	 *
14724 	 * The microcode will set the MEM_CFG register using this value
14725 	 * after it is started below.
14726 	 *
14727 	 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
14728 	 * are defined.
14729 	 *
14730 	 * ASC-3550 has 8KB internal memory.
14731 	 */
14732 	AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
14733 			 BIOS_EN | RAM_SZ_8KB);
14734 
14735 	/*
14736 	 * Set SEL_MASK Microcode Default Value
14737 	 *
14738 	 * The microcode will set the SEL_MASK register using this value
14739 	 * after it is started below.
14740 	 */
14741 	AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
14742 			 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
14743 
14744 	/*
14745 	 * Build carrier freelist.
14746 	 *
14747 	 * Driver must have already allocated memory and set 'carrier_buf'.
14748 	 */
14749 	ASC_ASSERT(asc_dvc->carrier_buf != NULL);
14750 
14751 	carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
14752 	asc_dvc->carr_freelist = NULL;
14753 	if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
14754 		buf_size = ADV_CARRIER_BUFSIZE;
14755 	} else {
14756 		buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
14757 	}
14758 
14759 	do {
14760 		/*
14761 		 * Get physical address of the carrier 'carrp'.
14762 		 */
14763 		contig_len = sizeof(ADV_CARR_T);
14764 		carr_paddr =
14765 		    cpu_to_le32(DvcGetPhyAddr
14766 				(asc_dvc, NULL, (uchar *)carrp,
14767 				 (ADV_SDCNT *)&contig_len,
14768 				 ADV_IS_CARRIER_FLAG));
14769 
14770 		buf_size -= sizeof(ADV_CARR_T);
14771 
14772 		/*
14773 		 * If the current carrier is not physically contiguous, then
14774 		 * maybe there was a page crossing. Try the next carrier aligned
14775 		 * start address.
14776 		 */
14777 		if (contig_len < sizeof(ADV_CARR_T)) {
14778 			carrp++;
14779 			continue;
14780 		}
14781 
14782 		carrp->carr_pa = carr_paddr;
14783 		carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
14784 
14785 		/*
14786 		 * Insert the carrier at the beginning of the freelist.
14787 		 */
14788 		carrp->next_vpa =
14789 		    cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
14790 		asc_dvc->carr_freelist = carrp;
14791 
14792 		carrp++;
14793 	}
14794 	while (buf_size > 0);
14795 
14796 	/*
14797 	 * Set-up the Host->RISC Initiator Command Queue (ICQ).
14798 	 */
14799 
14800 	if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
14801 		asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14802 		return ADV_ERROR;
14803 	}
14804 	asc_dvc->carr_freelist = (ADV_CARR_T *)
14805 	    ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
14806 
14807 	/*
14808 	 * The first command issued will be placed in the stopper carrier.
14809 	 */
14810 	asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14811 
14812 	/*
14813 	 * Set RISC ICQ physical address start value.
14814 	 */
14815 	AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
14816 
14817 	/*
14818 	 * Set-up the RISC->Host Initiator Response Queue (IRQ).
14819 	 */
14820 	if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
14821 		asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14822 		return ADV_ERROR;
14823 	}
14824 	asc_dvc->carr_freelist = (ADV_CARR_T *)
14825 	    ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
14826 
14827 	/*
14828 	 * The first command completed by the RISC will be placed in
14829 	 * the stopper.
14830 	 *
14831 	 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
14832 	 * completed the RISC will set the ASC_RQ_STOPPER bit.
14833 	 */
14834 	asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14835 
14836 	/*
14837 	 * Set RISC IRQ physical address start value.
14838 	 */
14839 	AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
14840 	asc_dvc->carr_pending_cnt = 0;
14841 
14842 	AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
14843 			     (ADV_INTR_ENABLE_HOST_INTR |
14844 			      ADV_INTR_ENABLE_GLOBAL_INTR));
14845 
14846 	AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
14847 	AdvWriteWordRegister(iop_base, IOPW_PC, word);
14848 
14849 	/* finally, finally, gentlemen, start your engine */
14850 	AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
14851 
14852 	/*
14853 	 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
14854 	 * Resets should be performed. The RISC has to be running
14855 	 * to issue a SCSI Bus Reset.
14856 	 */
14857 	if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
14858 		/*
14859 		 * If the BIOS Signature is present in memory, restore the
14860 		 * BIOS Handshake Configuration Table and do not perform
14861 		 * a SCSI Bus Reset.
14862 		 */
14863 		if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
14864 		    0x55AA) {
14865 			/*
14866 			 * Restore per TID negotiated values.
14867 			 */
14868 			AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14869 			AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14870 			AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
14871 					 tagqng_able);
14872 			for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14873 				AdvWriteByteLram(iop_base,
14874 						 ASC_MC_NUMBER_OF_MAX_CMD + tid,
14875 						 max_cmd[tid]);
14876 			}
14877 		} else {
14878 			if (AdvResetSB(asc_dvc) != ADV_TRUE) {
14879 				warn_code = ASC_WARN_BUSRESET_ERROR;
14880 			}
14881 		}
14882 	}
14883 
14884 	return warn_code;
14885 }
14886 
14887 /*
14888  * Initialize the ASC-38C0800.
14889  *
14890  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14891  *
14892  * For a non-fatal error return a warning code. If there are no warnings
14893  * then 0 is returned.
14894  *
14895  * Needed after initialization for error recovery.
14896  */
14897 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
14898 {
14899 	AdvPortAddr iop_base;
14900 	ushort warn_code;
14901 	ADV_DCNT sum;
14902 	int begin_addr;
14903 	int end_addr;
14904 	ushort code_sum;
14905 	int word;
14906 	int j;
14907 	int adv_asc38C0800_expanded_size;
14908 	ADV_CARR_T *carrp;
14909 	ADV_DCNT contig_len;
14910 	ADV_SDCNT buf_size;
14911 	ADV_PADDR carr_paddr;
14912 	int i;
14913 	ushort scsi_cfg1;
14914 	uchar byte;
14915 	uchar tid;
14916 	ushort bios_mem[ASC_MC_BIOSLEN / 2];	/* BIOS RISC Memory 0x40-0x8F. */
14917 	ushort wdtr_able, sdtr_able, tagqng_able;
14918 	uchar max_cmd[ADV_MAX_TID + 1];
14919 
14920 	/* If there is already an error, don't continue. */
14921 	if (asc_dvc->err_code != 0) {
14922 		return ADV_ERROR;
14923 	}
14924 
14925 	/*
14926 	 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
14927 	 */
14928 	if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
14929 		asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
14930 		return ADV_ERROR;
14931 	}
14932 
14933 	warn_code = 0;
14934 	iop_base = asc_dvc->iop_base;
14935 
14936 	/*
14937 	 * Save the RISC memory BIOS region before writing the microcode.
14938 	 * The BIOS may already be loaded and using its RISC LRAM region
14939 	 * so its region must be saved and restored.
14940 	 *
14941 	 * Note: This code makes the assumption, which is currently true,
14942 	 * that a chip reset does not clear RISC LRAM.
14943 	 */
14944 	for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14945 		AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14946 				bios_mem[i]);
14947 	}
14948 
14949 	/*
14950 	 * Save current per TID negotiated values.
14951 	 */
14952 	AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14953 	AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14954 	AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14955 	for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14956 		AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14957 				max_cmd[tid]);
14958 	}
14959 
14960 	/*
14961 	 * RAM BIST (RAM Built-In Self Test)
14962 	 *
14963 	 * Address : I/O base + offset 0x38h register (byte).
14964 	 * Function: Bit 7-6(RW) : RAM mode
14965 	 *                          Normal Mode   : 0x00
14966 	 *                          Pre-test Mode : 0x40
14967 	 *                          RAM Test Mode : 0x80
14968 	 *           Bit 5       : unused
14969 	 *           Bit 4(RO)   : Done bit
14970 	 *           Bit 3-0(RO) : Status
14971 	 *                          Host Error    : 0x08
14972 	 *                          Int_RAM Error : 0x04
14973 	 *                          RISC Error    : 0x02
14974 	 *                          SCSI Error    : 0x01
14975 	 *                          No Error      : 0x00
14976 	 *
14977 	 * Note: RAM BIST code should be put right here, before loading the
14978 	 * microcode and after saving the RISC memory BIOS region.
14979 	 */
14980 
14981 	/*
14982 	 * LRAM Pre-test
14983 	 *
14984 	 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
14985 	 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
14986 	 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
14987 	 * to NORMAL_MODE, return an error too.
14988 	 */
14989 	for (i = 0; i < 2; i++) {
14990 		AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
14991 		DvcSleepMilliSecond(10);	/* Wait for 10ms before reading back. */
14992 		byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14993 		if ((byte & RAM_TEST_DONE) == 0
14994 		    || (byte & 0x0F) != PRE_TEST_VALUE) {
14995 			asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14996 			return ADV_ERROR;
14997 		}
14998 
14999 		AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15000 		DvcSleepMilliSecond(10);	/* Wait for 10ms before reading back. */
15001 		if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15002 		    != NORMAL_VALUE) {
15003 			asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15004 			return ADV_ERROR;
15005 		}
15006 	}
15007 
15008 	/*
15009 	 * LRAM Test - It takes about 1.5 ms to run through the test.
15010 	 *
15011 	 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15012 	 * If Done bit not set or Status not 0, save register byte, set the
15013 	 * err_code, and return an error.
15014 	 */
15015 	AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15016 	DvcSleepMilliSecond(10);	/* Wait for 10ms before checking status. */
15017 
15018 	byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15019 	if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
15020 		/* Get here if Done bit not set or Status not 0. */
15021 		asc_dvc->bist_err_code = byte;	/* for BIOS display message */
15022 		asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15023 		return ADV_ERROR;
15024 	}
15025 
15026 	/* We need to reset back to normal mode after LRAM test passes. */
15027 	AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15028 
15029 	/*
15030 	 * Load the Microcode
15031 	 *
15032 	 * Write the microcode image to RISC memory starting at address 0.
15033 	 *
15034 	 */
15035 	AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15036 
15037 	/* Assume the following compressed format of the microcode buffer:
15038 	 *
15039 	 *  254 word (508 byte) table indexed by byte code followed
15040 	 *  by the following byte codes:
15041 	 *
15042 	 *    1-Byte Code:
15043 	 *      00: Emit word 0 in table.
15044 	 *      01: Emit word 1 in table.
15045 	 *      .
15046 	 *      FD: Emit word 253 in table.
15047 	 *
15048 	 *    Multi-Byte Code:
15049 	 *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15050 	 *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15051 	 */
15052 	word = 0;
15053 	for (i = 253 * 2; i < _adv_asc38C0800_size; i++) {
15054 		if (_adv_asc38C0800_buf[i] == 0xff) {
15055 			for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++) {
15056 				AdvWriteWordAutoIncLram(iop_base, (((ushort)
15057 								    _adv_asc38C0800_buf
15058 								    [i +
15059 								     3] << 8) |
15060 								   _adv_asc38C0800_buf
15061 								   [i + 2]));
15062 				word++;
15063 			}
15064 			i += 3;
15065 		} else if (_adv_asc38C0800_buf[i] == 0xfe) {
15066 			AdvWriteWordAutoIncLram(iop_base, (((ushort)
15067 							    _adv_asc38C0800_buf
15068 							    [i +
15069 							     2] << 8) |
15070 							   _adv_asc38C0800_buf[i
15071 									       +
15072 									       1]));
15073 			i += 2;
15074 			word++;
15075 		} else {
15076 			AdvWriteWordAutoIncLram(iop_base, (((ushort)
15077 							    _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) | _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
15078 			word++;
15079 		}
15080 	}
15081 
15082 	/*
15083 	 * Set 'word' for later use to clear the rest of memory and save
15084 	 * the expanded mcode size.
15085 	 */
15086 	word *= 2;
15087 	adv_asc38C0800_expanded_size = word;
15088 
15089 	/*
15090 	 * Clear the rest of ASC-38C0800 Internal RAM (16KB).
15091 	 */
15092 	for (; word < ADV_38C0800_MEMSIZE; word += 2) {
15093 		AdvWriteWordAutoIncLram(iop_base, 0);
15094 	}
15095 
15096 	/*
15097 	 * Verify the microcode checksum.
15098 	 */
15099 	sum = 0;
15100 	AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15101 
15102 	for (word = 0; word < adv_asc38C0800_expanded_size; word += 2) {
15103 		sum += AdvReadWordAutoIncLram(iop_base);
15104 	}
15105 	ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
15106 
15107 	ASC_DBG2(1,
15108 		 "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
15109 		 (ulong)sum, (ulong)_adv_asc38C0800_chksum);
15110 
15111 	if (sum != _adv_asc38C0800_chksum) {
15112 		asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15113 		return ADV_ERROR;
15114 	}
15115 
15116 	/*
15117 	 * Restore the RISC memory BIOS region.
15118 	 */
15119 	for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15120 		AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15121 				 bios_mem[i]);
15122 	}
15123 
15124 	/*
15125 	 * Calculate and write the microcode code checksum to the microcode
15126 	 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15127 	 */
15128 	AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15129 	AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15130 	code_sum = 0;
15131 	AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15132 	for (word = begin_addr; word < end_addr; word += 2) {
15133 		code_sum += AdvReadWordAutoIncLram(iop_base);
15134 	}
15135 	AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15136 
15137 	/*
15138 	 * Read microcode version and date.
15139 	 */
15140 	AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
15141 			asc_dvc->cfg->mcode_date);
15142 	AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
15143 			asc_dvc->cfg->mcode_version);
15144 
15145 	/*
15146 	 * Set the chip type to indicate the ASC38C0800.
15147 	 */
15148 	AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
15149 
15150 	/*
15151 	 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15152 	 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15153 	 * cable detection and then we are able to read C_DET[3:0].
15154 	 *
15155 	 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15156 	 * Microcode Default Value' section below.
15157 	 */
15158 	scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15159 	AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
15160 			     scsi_cfg1 | DIS_TERM_DRV);
15161 
15162 	/*
15163 	 * If the PCI Configuration Command Register "Parity Error Response
15164 	 * Control" Bit was clear (0), then set the microcode variable
15165 	 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15166 	 * to ignore DMA parity errors.
15167 	 */
15168 	if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
15169 		AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15170 		word |= CONTROL_FLAG_IGNORE_PERR;
15171 		AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15172 	}
15173 
15174 	/*
15175 	 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
15176 	 * bits for the default FIFO threshold.
15177 	 *
15178 	 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
15179 	 *
15180 	 * For DMA Errata #4 set the BC_THRESH_ENB bit.
15181 	 */
15182 	AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15183 			     BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
15184 			     READ_CMD_MRM);
15185 
15186 	/*
15187 	 * Microcode operating variables for WDTR, SDTR, and command tag
15188 	 * queuing will be set in AdvInquiryHandling() based on what a
15189 	 * device reports it is capable of in Inquiry byte 7.
15190 	 *
15191 	 * If SCSI Bus Resets have been disabled, then directly set
15192 	 * SDTR and WDTR from the EEPROM configuration. This will allow
15193 	 * the BIOS and warm boot to work without a SCSI bus hang on
15194 	 * the Inquiry caused by host and target mismatched DTR values.
15195 	 * Without the SCSI Bus Reset, before an Inquiry a device can't
15196 	 * be assumed to be in Asynchronous, Narrow mode.
15197 	 */
15198 	if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
15199 		AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
15200 				 asc_dvc->wdtr_able);
15201 		AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
15202 				 asc_dvc->sdtr_able);
15203 	}
15204 
15205 	/*
15206 	 * Set microcode operating variables for DISC and SDTR_SPEED1,
15207 	 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15208 	 * configuration values.
15209 	 *
15210 	 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15211 	 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15212 	 * without determining here whether the device supports SDTR.
15213 	 */
15214 	AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
15215 			 asc_dvc->cfg->disc_enable);
15216 	AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15217 	AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15218 	AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15219 	AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15220 
15221 	/*
15222 	 * Set SCSI_CFG0 Microcode Default Value.
15223 	 *
15224 	 * The microcode will set the SCSI_CFG0 register using this value
15225 	 * after it is started below.
15226 	 */
15227 	AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15228 			 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15229 			 asc_dvc->chip_scsi_id);
15230 
15231 	/*
15232 	 * Determine SCSI_CFG1 Microcode Default Value.
15233 	 *
15234 	 * The microcode will set the SCSI_CFG1 register using this value
15235 	 * after it is started below.
15236 	 */
15237 
15238 	/* Read current SCSI_CFG1 Register value. */
15239 	scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15240 
15241 	/*
15242 	 * If the internal narrow cable is reversed all of the SCSI_CTRL
15243 	 * register signals will be set. Check for and return an error if
15244 	 * this condition is found.
15245 	 */
15246 	if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
15247 		asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15248 		return ADV_ERROR;
15249 	}
15250 
15251 	/*
15252 	 * All kind of combinations of devices attached to one of four connectors
15253 	 * are acceptable except HVD device attached. For example, LVD device can
15254 	 * be attached to SE connector while SE device attached to LVD connector.
15255 	 * If LVD device attached to SE connector, it only runs up to Ultra speed.
15256 	 *
15257 	 * If an HVD device is attached to one of LVD connectors, return an error.
15258 	 * However, there is no way to detect HVD device attached to SE connectors.
15259 	 */
15260 	if (scsi_cfg1 & HVD) {
15261 		asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15262 		return ADV_ERROR;
15263 	}
15264 
15265 	/*
15266 	 * If either SE or LVD automatic termination control is enabled, then
15267 	 * set the termination value based on a table listed in a_condor.h.
15268 	 *
15269 	 * If manual termination was specified with an EEPROM setting then
15270 	 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
15271 	 * be 'ored' into SCSI_CFG1.
15272 	 */
15273 	if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
15274 		/* SE automatic termination control is enabled. */
15275 		switch (scsi_cfg1 & C_DET_SE) {
15276 			/* TERM_SE_HI: on, TERM_SE_LO: on */
15277 		case 0x1:
15278 		case 0x2:
15279 		case 0x3:
15280 			asc_dvc->cfg->termination |= TERM_SE;
15281 			break;
15282 
15283 			/* TERM_SE_HI: on, TERM_SE_LO: off */
15284 		case 0x0:
15285 			asc_dvc->cfg->termination |= TERM_SE_HI;
15286 			break;
15287 		}
15288 	}
15289 
15290 	if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
15291 		/* LVD automatic termination control is enabled. */
15292 		switch (scsi_cfg1 & C_DET_LVD) {
15293 			/* TERM_LVD_HI: on, TERM_LVD_LO: on */
15294 		case 0x4:
15295 		case 0x8:
15296 		case 0xC:
15297 			asc_dvc->cfg->termination |= TERM_LVD;
15298 			break;
15299 
15300 			/* TERM_LVD_HI: off, TERM_LVD_LO: off */
15301 		case 0x0:
15302 			break;
15303 		}
15304 	}
15305 
15306 	/*
15307 	 * Clear any set TERM_SE and TERM_LVD bits.
15308 	 */
15309 	scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
15310 
15311 	/*
15312 	 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
15313 	 */
15314 	scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
15315 
15316 	/*
15317 	 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
15318 	 * and set possibly modified termination control bits in the Microcode
15319 	 * SCSI_CFG1 Register Value.
15320 	 */
15321 	scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
15322 
15323 	/*
15324 	 * Set SCSI_CFG1 Microcode Default Value
15325 	 *
15326 	 * Set possibly modified termination control and reset DIS_TERM_DRV
15327 	 * bits in the Microcode SCSI_CFG1 Register Value.
15328 	 *
15329 	 * The microcode will set the SCSI_CFG1 register using this value
15330 	 * after it is started below.
15331 	 */
15332 	AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15333 
15334 	/*
15335 	 * Set MEM_CFG Microcode Default Value
15336 	 *
15337 	 * The microcode will set the MEM_CFG register using this value
15338 	 * after it is started below.
15339 	 *
15340 	 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15341 	 * are defined.
15342 	 *
15343 	 * ASC-38C0800 has 16KB internal memory.
15344 	 */
15345 	AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15346 			 BIOS_EN | RAM_SZ_16KB);
15347 
15348 	/*
15349 	 * Set SEL_MASK Microcode Default Value
15350 	 *
15351 	 * The microcode will set the SEL_MASK register using this value
15352 	 * after it is started below.
15353 	 */
15354 	AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15355 			 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15356 
15357 	/*
15358 	 * Build the carrier freelist.
15359 	 *
15360 	 * Driver must have already allocated memory and set 'carrier_buf'.
15361 	 */
15362 	ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15363 
15364 	carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15365 	asc_dvc->carr_freelist = NULL;
15366 	if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
15367 		buf_size = ADV_CARRIER_BUFSIZE;
15368 	} else {
15369 		buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15370 	}
15371 
15372 	do {
15373 		/*
15374 		 * Get physical address for the carrier 'carrp'.
15375 		 */
15376 		contig_len = sizeof(ADV_CARR_T);
15377 		carr_paddr =
15378 		    cpu_to_le32(DvcGetPhyAddr
15379 				(asc_dvc, NULL, (uchar *)carrp,
15380 				 (ADV_SDCNT *)&contig_len,
15381 				 ADV_IS_CARRIER_FLAG));
15382 
15383 		buf_size -= sizeof(ADV_CARR_T);
15384 
15385 		/*
15386 		 * If the current carrier is not physically contiguous, then
15387 		 * maybe there was a page crossing. Try the next carrier aligned
15388 		 * start address.
15389 		 */
15390 		if (contig_len < sizeof(ADV_CARR_T)) {
15391 			carrp++;
15392 			continue;
15393 		}
15394 
15395 		carrp->carr_pa = carr_paddr;
15396 		carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15397 
15398 		/*
15399 		 * Insert the carrier at the beginning of the freelist.
15400 		 */
15401 		carrp->next_vpa =
15402 		    cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15403 		asc_dvc->carr_freelist = carrp;
15404 
15405 		carrp++;
15406 	}
15407 	while (buf_size > 0);
15408 
15409 	/*
15410 	 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15411 	 */
15412 
15413 	if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
15414 		asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15415 		return ADV_ERROR;
15416 	}
15417 	asc_dvc->carr_freelist = (ADV_CARR_T *)
15418 	    ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15419 
15420 	/*
15421 	 * The first command issued will be placed in the stopper carrier.
15422 	 */
15423 	asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15424 
15425 	/*
15426 	 * Set RISC ICQ physical address start value.
15427 	 * carr_pa is LE, must be native before write
15428 	 */
15429 	AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15430 
15431 	/*
15432 	 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15433 	 */
15434 	if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
15435 		asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15436 		return ADV_ERROR;
15437 	}
15438 	asc_dvc->carr_freelist = (ADV_CARR_T *)
15439 	    ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15440 
15441 	/*
15442 	 * The first command completed by the RISC will be placed in
15443 	 * the stopper.
15444 	 *
15445 	 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15446 	 * completed the RISC will set the ASC_RQ_STOPPER bit.
15447 	 */
15448 	asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15449 
15450 	/*
15451 	 * Set RISC IRQ physical address start value.
15452 	 *
15453 	 * carr_pa is LE, must be native before write *
15454 	 */
15455 	AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15456 	asc_dvc->carr_pending_cnt = 0;
15457 
15458 	AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15459 			     (ADV_INTR_ENABLE_HOST_INTR |
15460 			      ADV_INTR_ENABLE_GLOBAL_INTR));
15461 
15462 	AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15463 	AdvWriteWordRegister(iop_base, IOPW_PC, word);
15464 
15465 	/* finally, finally, gentlemen, start your engine */
15466 	AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15467 
15468 	/*
15469 	 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15470 	 * Resets should be performed. The RISC has to be running
15471 	 * to issue a SCSI Bus Reset.
15472 	 */
15473 	if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
15474 		/*
15475 		 * If the BIOS Signature is present in memory, restore the
15476 		 * BIOS Handshake Configuration Table and do not perform
15477 		 * a SCSI Bus Reset.
15478 		 */
15479 		if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
15480 		    0x55AA) {
15481 			/*
15482 			 * Restore per TID negotiated values.
15483 			 */
15484 			AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15485 			AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15486 			AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
15487 					 tagqng_able);
15488 			for (tid = 0; tid <= ADV_MAX_TID; tid++) {
15489 				AdvWriteByteLram(iop_base,
15490 						 ASC_MC_NUMBER_OF_MAX_CMD + tid,
15491 						 max_cmd[tid]);
15492 			}
15493 		} else {
15494 			if (AdvResetSB(asc_dvc) != ADV_TRUE) {
15495 				warn_code = ASC_WARN_BUSRESET_ERROR;
15496 			}
15497 		}
15498 	}
15499 
15500 	return warn_code;
15501 }
15502 
15503 /*
15504  * Initialize the ASC-38C1600.
15505  *
15506  * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
15507  *
15508  * For a non-fatal error return a warning code. If there are no warnings
15509  * then 0 is returned.
15510  *
15511  * Needed after initialization for error recovery.
15512  */
15513 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
15514 {
15515 	AdvPortAddr iop_base;
15516 	ushort warn_code;
15517 	ADV_DCNT sum;
15518 	int begin_addr;
15519 	int end_addr;
15520 	ushort code_sum;
15521 	long word;
15522 	int j;
15523 	int adv_asc38C1600_expanded_size;
15524 	ADV_CARR_T *carrp;
15525 	ADV_DCNT contig_len;
15526 	ADV_SDCNT buf_size;
15527 	ADV_PADDR carr_paddr;
15528 	int i;
15529 	ushort scsi_cfg1;
15530 	uchar byte;
15531 	uchar tid;
15532 	ushort bios_mem[ASC_MC_BIOSLEN / 2];	/* BIOS RISC Memory 0x40-0x8F. */
15533 	ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
15534 	uchar max_cmd[ASC_MAX_TID + 1];
15535 
15536 	/* If there is already an error, don't continue. */
15537 	if (asc_dvc->err_code != 0) {
15538 		return ADV_ERROR;
15539 	}
15540 
15541 	/*
15542 	 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
15543 	 */
15544 	if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
15545 		asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
15546 		return ADV_ERROR;
15547 	}
15548 
15549 	warn_code = 0;
15550 	iop_base = asc_dvc->iop_base;
15551 
15552 	/*
15553 	 * Save the RISC memory BIOS region before writing the microcode.
15554 	 * The BIOS may already be loaded and using its RISC LRAM region
15555 	 * so its region must be saved and restored.
15556 	 *
15557 	 * Note: This code makes the assumption, which is currently true,
15558 	 * that a chip reset does not clear RISC LRAM.
15559 	 */
15560 	for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15561 		AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15562 				bios_mem[i]);
15563 	}
15564 
15565 	/*
15566 	 * Save current per TID negotiated values.
15567 	 */
15568 	AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15569 	AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15570 	AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15571 	AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15572 	for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15573 		AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15574 				max_cmd[tid]);
15575 	}
15576 
15577 	/*
15578 	 * RAM BIST (Built-In Self Test)
15579 	 *
15580 	 * Address : I/O base + offset 0x38h register (byte).
15581 	 * Function: Bit 7-6(RW) : RAM mode
15582 	 *                          Normal Mode   : 0x00
15583 	 *                          Pre-test Mode : 0x40
15584 	 *                          RAM Test Mode : 0x80
15585 	 *           Bit 5       : unused
15586 	 *           Bit 4(RO)   : Done bit
15587 	 *           Bit 3-0(RO) : Status
15588 	 *                          Host Error    : 0x08
15589 	 *                          Int_RAM Error : 0x04
15590 	 *                          RISC Error    : 0x02
15591 	 *                          SCSI Error    : 0x01
15592 	 *                          No Error      : 0x00
15593 	 *
15594 	 * Note: RAM BIST code should be put right here, before loading the
15595 	 * microcode and after saving the RISC memory BIOS region.
15596 	 */
15597 
15598 	/*
15599 	 * LRAM Pre-test
15600 	 *
15601 	 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15602 	 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15603 	 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15604 	 * to NORMAL_MODE, return an error too.
15605 	 */
15606 	for (i = 0; i < 2; i++) {
15607 		AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15608 		DvcSleepMilliSecond(10);	/* Wait for 10ms before reading back. */
15609 		byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15610 		if ((byte & RAM_TEST_DONE) == 0
15611 		    || (byte & 0x0F) != PRE_TEST_VALUE) {
15612 			asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15613 			return ADV_ERROR;
15614 		}
15615 
15616 		AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15617 		DvcSleepMilliSecond(10);	/* Wait for 10ms before reading back. */
15618 		if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15619 		    != NORMAL_VALUE) {
15620 			asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15621 			return ADV_ERROR;
15622 		}
15623 	}
15624 
15625 	/*
15626 	 * LRAM Test - It takes about 1.5 ms to run through the test.
15627 	 *
15628 	 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15629 	 * If Done bit not set or Status not 0, save register byte, set the
15630 	 * err_code, and return an error.
15631 	 */
15632 	AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15633 	DvcSleepMilliSecond(10);	/* Wait for 10ms before checking status. */
15634 
15635 	byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15636 	if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
15637 		/* Get here if Done bit not set or Status not 0. */
15638 		asc_dvc->bist_err_code = byte;	/* for BIOS display message */
15639 		asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15640 		return ADV_ERROR;
15641 	}
15642 
15643 	/* We need to reset back to normal mode after LRAM test passes. */
15644 	AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15645 
15646 	/*
15647 	 * Load the Microcode
15648 	 *
15649 	 * Write the microcode image to RISC memory starting at address 0.
15650 	 *
15651 	 */
15652 	AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15653 
15654 	/*
15655 	 * Assume the following compressed format of the microcode buffer:
15656 	 *
15657 	 *  254 word (508 byte) table indexed by byte code followed
15658 	 *  by the following byte codes:
15659 	 *
15660 	 *    1-Byte Code:
15661 	 *      00: Emit word 0 in table.
15662 	 *      01: Emit word 1 in table.
15663 	 *      .
15664 	 *      FD: Emit word 253 in table.
15665 	 *
15666 	 *    Multi-Byte Code:
15667 	 *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15668 	 *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15669 	 */
15670 	word = 0;
15671 	for (i = 253 * 2; i < _adv_asc38C1600_size; i++) {
15672 		if (_adv_asc38C1600_buf[i] == 0xff) {
15673 			for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++) {
15674 				AdvWriteWordAutoIncLram(iop_base, (((ushort)
15675 								    _adv_asc38C1600_buf
15676 								    [i +
15677 								     3] << 8) |
15678 								   _adv_asc38C1600_buf
15679 								   [i + 2]));
15680 				word++;
15681 			}
15682 			i += 3;
15683 		} else if (_adv_asc38C1600_buf[i] == 0xfe) {
15684 			AdvWriteWordAutoIncLram(iop_base, (((ushort)
15685 							    _adv_asc38C1600_buf
15686 							    [i +
15687 							     2] << 8) |
15688 							   _adv_asc38C1600_buf[i
15689 									       +
15690 									       1]));
15691 			i += 2;
15692 			word++;
15693 		} else {
15694 			AdvWriteWordAutoIncLram(iop_base, (((ushort)
15695 							    _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) | _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
15696 			word++;
15697 		}
15698 	}
15699 
15700 	/*
15701 	 * Set 'word' for later use to clear the rest of memory and save
15702 	 * the expanded mcode size.
15703 	 */
15704 	word *= 2;
15705 	adv_asc38C1600_expanded_size = word;
15706 
15707 	/*
15708 	 * Clear the rest of ASC-38C1600 Internal RAM (32KB).
15709 	 */
15710 	for (; word < ADV_38C1600_MEMSIZE; word += 2) {
15711 		AdvWriteWordAutoIncLram(iop_base, 0);
15712 	}
15713 
15714 	/*
15715 	 * Verify the microcode checksum.
15716 	 */
15717 	sum = 0;
15718 	AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15719 
15720 	for (word = 0; word < adv_asc38C1600_expanded_size; word += 2) {
15721 		sum += AdvReadWordAutoIncLram(iop_base);
15722 	}
15723 
15724 	if (sum != _adv_asc38C1600_chksum) {
15725 		asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15726 		return ADV_ERROR;
15727 	}
15728 
15729 	/*
15730 	 * Restore the RISC memory BIOS region.
15731 	 */
15732 	for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15733 		AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15734 				 bios_mem[i]);
15735 	}
15736 
15737 	/*
15738 	 * Calculate and write the microcode code checksum to the microcode
15739 	 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15740 	 */
15741 	AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15742 	AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15743 	code_sum = 0;
15744 	AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15745 	for (word = begin_addr; word < end_addr; word += 2) {
15746 		code_sum += AdvReadWordAutoIncLram(iop_base);
15747 	}
15748 	AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15749 
15750 	/*
15751 	 * Read microcode version and date.
15752 	 */
15753 	AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
15754 			asc_dvc->cfg->mcode_date);
15755 	AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
15756 			asc_dvc->cfg->mcode_version);
15757 
15758 	/*
15759 	 * Set the chip type to indicate the ASC38C1600.
15760 	 */
15761 	AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
15762 
15763 	/*
15764 	 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15765 	 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15766 	 * cable detection and then we are able to read C_DET[3:0].
15767 	 *
15768 	 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15769 	 * Microcode Default Value' section below.
15770 	 */
15771 	scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15772 	AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
15773 			     scsi_cfg1 | DIS_TERM_DRV);
15774 
15775 	/*
15776 	 * If the PCI Configuration Command Register "Parity Error Response
15777 	 * Control" Bit was clear (0), then set the microcode variable
15778 	 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15779 	 * to ignore DMA parity errors.
15780 	 */
15781 	if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
15782 		AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15783 		word |= CONTROL_FLAG_IGNORE_PERR;
15784 		AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15785 	}
15786 
15787 	/*
15788 	 * If the BIOS control flag AIPP (Asynchronous Information
15789 	 * Phase Protection) disable bit is not set, then set the firmware
15790 	 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
15791 	 * AIPP checking and encoding.
15792 	 */
15793 	if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
15794 		AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15795 		word |= CONTROL_FLAG_ENABLE_AIPP;
15796 		AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15797 	}
15798 
15799 	/*
15800 	 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
15801 	 * and START_CTL_TH [3:2].
15802 	 */
15803 	AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15804 			     FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
15805 
15806 	/*
15807 	 * Microcode operating variables for WDTR, SDTR, and command tag
15808 	 * queuing will be set in AdvInquiryHandling() based on what a
15809 	 * device reports it is capable of in Inquiry byte 7.
15810 	 *
15811 	 * If SCSI Bus Resets have been disabled, then directly set
15812 	 * SDTR and WDTR from the EEPROM configuration. This will allow
15813 	 * the BIOS and warm boot to work without a SCSI bus hang on
15814 	 * the Inquiry caused by host and target mismatched DTR values.
15815 	 * Without the SCSI Bus Reset, before an Inquiry a device can't
15816 	 * be assumed to be in Asynchronous, Narrow mode.
15817 	 */
15818 	if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
15819 		AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
15820 				 asc_dvc->wdtr_able);
15821 		AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
15822 				 asc_dvc->sdtr_able);
15823 	}
15824 
15825 	/*
15826 	 * Set microcode operating variables for DISC and SDTR_SPEED1,
15827 	 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15828 	 * configuration values.
15829 	 *
15830 	 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15831 	 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15832 	 * without determining here whether the device supports SDTR.
15833 	 */
15834 	AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
15835 			 asc_dvc->cfg->disc_enable);
15836 	AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15837 	AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15838 	AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15839 	AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15840 
15841 	/*
15842 	 * Set SCSI_CFG0 Microcode Default Value.
15843 	 *
15844 	 * The microcode will set the SCSI_CFG0 register using this value
15845 	 * after it is started below.
15846 	 */
15847 	AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15848 			 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15849 			 asc_dvc->chip_scsi_id);
15850 
15851 	/*
15852 	 * Calculate SCSI_CFG1 Microcode Default Value.
15853 	 *
15854 	 * The microcode will set the SCSI_CFG1 register using this value
15855 	 * after it is started below.
15856 	 *
15857 	 * Each ASC-38C1600 function has only two cable detect bits.
15858 	 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
15859 	 */
15860 	scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15861 
15862 	/*
15863 	 * If the cable is reversed all of the SCSI_CTRL register signals
15864 	 * will be set. Check for and return an error if this condition is
15865 	 * found.
15866 	 */
15867 	if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
15868 		asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15869 		return ADV_ERROR;
15870 	}
15871 
15872 	/*
15873 	 * Each ASC-38C1600 function has two connectors. Only an HVD device
15874 	 * can not be connected to either connector. An LVD device or SE device
15875 	 * may be connected to either connecor. If an SE device is connected,
15876 	 * then at most Ultra speed (20 Mhz) can be used on both connectors.
15877 	 *
15878 	 * If an HVD device is attached, return an error.
15879 	 */
15880 	if (scsi_cfg1 & HVD) {
15881 		asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15882 		return ADV_ERROR;
15883 	}
15884 
15885 	/*
15886 	 * Each function in the ASC-38C1600 uses only the SE cable detect and
15887 	 * termination because there are two connectors for each function. Each
15888 	 * function may use either LVD or SE mode. Corresponding the SE automatic
15889 	 * termination control EEPROM bits are used for each function. Each
15890 	 * function has its own EEPROM. If SE automatic control is enabled for
15891 	 * the function, then set the termination value based on a table listed
15892 	 * in a_condor.h.
15893 	 *
15894 	 * If manual termination is specified in the EEPROM for the function,
15895 	 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
15896 	 * ready to be 'ored' into SCSI_CFG1.
15897 	 */
15898 	if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
15899 		/* SE automatic termination control is enabled. */
15900 		switch (scsi_cfg1 & C_DET_SE) {
15901 			/* TERM_SE_HI: on, TERM_SE_LO: on */
15902 		case 0x1:
15903 		case 0x2:
15904 		case 0x3:
15905 			asc_dvc->cfg->termination |= TERM_SE;
15906 			break;
15907 
15908 		case 0x0:
15909 			if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0) {
15910 				/* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
15911 			} else {
15912 				/* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
15913 				asc_dvc->cfg->termination |= TERM_SE_HI;
15914 			}
15915 			break;
15916 		}
15917 	}
15918 
15919 	/*
15920 	 * Clear any set TERM_SE bits.
15921 	 */
15922 	scsi_cfg1 &= ~TERM_SE;
15923 
15924 	/*
15925 	 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
15926 	 */
15927 	scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
15928 
15929 	/*
15930 	 * Clear Big Endian and Terminator Polarity bits and set possibly
15931 	 * modified termination control bits in the Microcode SCSI_CFG1
15932 	 * Register Value.
15933 	 *
15934 	 * Big Endian bit is not used even on big endian machines.
15935 	 */
15936 	scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
15937 
15938 	/*
15939 	 * Set SCSI_CFG1 Microcode Default Value
15940 	 *
15941 	 * Set possibly modified termination control bits in the Microcode
15942 	 * SCSI_CFG1 Register Value.
15943 	 *
15944 	 * The microcode will set the SCSI_CFG1 register using this value
15945 	 * after it is started below.
15946 	 */
15947 	AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15948 
15949 	/*
15950 	 * Set MEM_CFG Microcode Default Value
15951 	 *
15952 	 * The microcode will set the MEM_CFG register using this value
15953 	 * after it is started below.
15954 	 *
15955 	 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15956 	 * are defined.
15957 	 *
15958 	 * ASC-38C1600 has 32KB internal memory.
15959 	 *
15960 	 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
15961 	 * out a special 16K Adv Library and Microcode version. After the issue
15962 	 * resolved, we should turn back to the 32K support. Both a_condor.h and
15963 	 * mcode.sas files also need to be updated.
15964 	 *
15965 	 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15966 	 *  BIOS_EN | RAM_SZ_32KB);
15967 	 */
15968 	AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15969 			 BIOS_EN | RAM_SZ_16KB);
15970 
15971 	/*
15972 	 * Set SEL_MASK Microcode Default Value
15973 	 *
15974 	 * The microcode will set the SEL_MASK register using this value
15975 	 * after it is started below.
15976 	 */
15977 	AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15978 			 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15979 
15980 	/*
15981 	 * Build the carrier freelist.
15982 	 *
15983 	 * Driver must have already allocated memory and set 'carrier_buf'.
15984 	 */
15985 
15986 	ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15987 
15988 	carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15989 	asc_dvc->carr_freelist = NULL;
15990 	if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
15991 		buf_size = ADV_CARRIER_BUFSIZE;
15992 	} else {
15993 		buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15994 	}
15995 
15996 	do {
15997 		/*
15998 		 * Get physical address for the carrier 'carrp'.
15999 		 */
16000 		contig_len = sizeof(ADV_CARR_T);
16001 		carr_paddr =
16002 		    cpu_to_le32(DvcGetPhyAddr
16003 				(asc_dvc, NULL, (uchar *)carrp,
16004 				 (ADV_SDCNT *)&contig_len,
16005 				 ADV_IS_CARRIER_FLAG));
16006 
16007 		buf_size -= sizeof(ADV_CARR_T);
16008 
16009 		/*
16010 		 * If the current carrier is not physically contiguous, then
16011 		 * maybe there was a page crossing. Try the next carrier aligned
16012 		 * start address.
16013 		 */
16014 		if (contig_len < sizeof(ADV_CARR_T)) {
16015 			carrp++;
16016 			continue;
16017 		}
16018 
16019 		carrp->carr_pa = carr_paddr;
16020 		carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
16021 
16022 		/*
16023 		 * Insert the carrier at the beginning of the freelist.
16024 		 */
16025 		carrp->next_vpa =
16026 		    cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
16027 		asc_dvc->carr_freelist = carrp;
16028 
16029 		carrp++;
16030 	}
16031 	while (buf_size > 0);
16032 
16033 	/*
16034 	 * Set-up the Host->RISC Initiator Command Queue (ICQ).
16035 	 */
16036 	if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
16037 		asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16038 		return ADV_ERROR;
16039 	}
16040 	asc_dvc->carr_freelist = (ADV_CARR_T *)
16041 	    ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
16042 
16043 	/*
16044 	 * The first command issued will be placed in the stopper carrier.
16045 	 */
16046 	asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16047 
16048 	/*
16049 	 * Set RISC ICQ physical address start value. Initialize the
16050 	 * COMMA register to the same value otherwise the RISC will
16051 	 * prematurely detect a command is available.
16052 	 */
16053 	AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
16054 	AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
16055 			      le32_to_cpu(asc_dvc->icq_sp->carr_pa));
16056 
16057 	/*
16058 	 * Set-up the RISC->Host Initiator Response Queue (IRQ).
16059 	 */
16060 	if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
16061 		asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16062 		return ADV_ERROR;
16063 	}
16064 	asc_dvc->carr_freelist = (ADV_CARR_T *)
16065 	    ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
16066 
16067 	/*
16068 	 * The first command completed by the RISC will be placed in
16069 	 * the stopper.
16070 	 *
16071 	 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
16072 	 * completed the RISC will set the ASC_RQ_STOPPER bit.
16073 	 */
16074 	asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16075 
16076 	/*
16077 	 * Set RISC IRQ physical address start value.
16078 	 */
16079 	AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
16080 	asc_dvc->carr_pending_cnt = 0;
16081 
16082 	AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
16083 			     (ADV_INTR_ENABLE_HOST_INTR |
16084 			      ADV_INTR_ENABLE_GLOBAL_INTR));
16085 	AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
16086 	AdvWriteWordRegister(iop_base, IOPW_PC, word);
16087 
16088 	/* finally, finally, gentlemen, start your engine */
16089 	AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
16090 
16091 	/*
16092 	 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
16093 	 * Resets should be performed. The RISC has to be running
16094 	 * to issue a SCSI Bus Reset.
16095 	 */
16096 	if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
16097 		/*
16098 		 * If the BIOS Signature is present in memory, restore the
16099 		 * per TID microcode operating variables.
16100 		 */
16101 		if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
16102 		    0x55AA) {
16103 			/*
16104 			 * Restore per TID negotiated values.
16105 			 */
16106 			AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16107 			AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16108 			AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16109 			AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
16110 					 tagqng_able);
16111 			for (tid = 0; tid <= ASC_MAX_TID; tid++) {
16112 				AdvWriteByteLram(iop_base,
16113 						 ASC_MC_NUMBER_OF_MAX_CMD + tid,
16114 						 max_cmd[tid]);
16115 			}
16116 		} else {
16117 			if (AdvResetSB(asc_dvc) != ADV_TRUE) {
16118 				warn_code = ASC_WARN_BUSRESET_ERROR;
16119 			}
16120 		}
16121 	}
16122 
16123 	return warn_code;
16124 }
16125 
16126 /*
16127  * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16128  * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16129  * all of this is done.
16130  *
16131  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16132  *
16133  * For a non-fatal error return a warning code. If there are no warnings
16134  * then 0 is returned.
16135  *
16136  * Note: Chip is stopped on entry.
16137  */
16138 static int __init AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
16139 {
16140 	AdvPortAddr iop_base;
16141 	ushort warn_code;
16142 	ADVEEP_3550_CONFIG eep_config;
16143 	int i;
16144 
16145 	iop_base = asc_dvc->iop_base;
16146 
16147 	warn_code = 0;
16148 
16149 	/*
16150 	 * Read the board's EEPROM configuration.
16151 	 *
16152 	 * Set default values if a bad checksum is found.
16153 	 */
16154 	if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
16155 		warn_code |= ASC_WARN_EEPROM_CHKSUM;
16156 
16157 		/*
16158 		 * Set EEPROM default values.
16159 		 */
16160 		for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++) {
16161 			*((uchar *)&eep_config + i) =
16162 			    *((uchar *)&Default_3550_EEPROM_Config + i);
16163 		}
16164 
16165 		/*
16166 		 * Assume the 6 byte board serial number that was read
16167 		 * from EEPROM is correct even if the EEPROM checksum
16168 		 * failed.
16169 		 */
16170 		eep_config.serial_number_word3 =
16171 		    AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16172 
16173 		eep_config.serial_number_word2 =
16174 		    AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16175 
16176 		eep_config.serial_number_word1 =
16177 		    AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16178 
16179 		AdvSet3550EEPConfig(iop_base, &eep_config);
16180 	}
16181 	/*
16182 	 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16183 	 * EEPROM configuration that was read.
16184 	 *
16185 	 * This is the mapping of EEPROM fields to Adv Library fields.
16186 	 */
16187 	asc_dvc->wdtr_able = eep_config.wdtr_able;
16188 	asc_dvc->sdtr_able = eep_config.sdtr_able;
16189 	asc_dvc->ultra_able = eep_config.ultra_able;
16190 	asc_dvc->tagqng_able = eep_config.tagqng_able;
16191 	asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16192 	asc_dvc->max_host_qng = eep_config.max_host_qng;
16193 	asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16194 	asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16195 	asc_dvc->start_motor = eep_config.start_motor;
16196 	asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16197 	asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16198 	asc_dvc->no_scam = eep_config.scam_tolerant;
16199 	asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16200 	asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16201 	asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16202 
16203 	/*
16204 	 * Set the host maximum queuing (max. 253, min. 16) and the per device
16205 	 * maximum queuing (max. 63, min. 4).
16206 	 */
16207 	if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
16208 		eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16209 	} else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
16210 		/* If the value is zero, assume it is uninitialized. */
16211 		if (eep_config.max_host_qng == 0) {
16212 			eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16213 		} else {
16214 			eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16215 		}
16216 	}
16217 
16218 	if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
16219 		eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16220 	} else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
16221 		/* If the value is zero, assume it is uninitialized. */
16222 		if (eep_config.max_dvc_qng == 0) {
16223 			eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16224 		} else {
16225 			eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16226 		}
16227 	}
16228 
16229 	/*
16230 	 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16231 	 * set 'max_dvc_qng' to 'max_host_qng'.
16232 	 */
16233 	if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
16234 		eep_config.max_dvc_qng = eep_config.max_host_qng;
16235 	}
16236 
16237 	/*
16238 	 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16239 	 * values based on possibly adjusted EEPROM values.
16240 	 */
16241 	asc_dvc->max_host_qng = eep_config.max_host_qng;
16242 	asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16243 
16244 	/*
16245 	 * If the EEPROM 'termination' field is set to automatic (0), then set
16246 	 * the ADV_DVC_CFG 'termination' field to automatic also.
16247 	 *
16248 	 * If the termination is specified with a non-zero 'termination'
16249 	 * value check that a legal value is set and set the ADV_DVC_CFG
16250 	 * 'termination' field appropriately.
16251 	 */
16252 	if (eep_config.termination == 0) {
16253 		asc_dvc->cfg->termination = 0;	/* auto termination */
16254 	} else {
16255 		/* Enable manual control with low off / high off. */
16256 		if (eep_config.termination == 1) {
16257 			asc_dvc->cfg->termination = TERM_CTL_SEL;
16258 
16259 			/* Enable manual control with low off / high on. */
16260 		} else if (eep_config.termination == 2) {
16261 			asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
16262 
16263 			/* Enable manual control with low on / high on. */
16264 		} else if (eep_config.termination == 3) {
16265 			asc_dvc->cfg->termination =
16266 			    TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
16267 		} else {
16268 			/*
16269 			 * The EEPROM 'termination' field contains a bad value. Use
16270 			 * automatic termination instead.
16271 			 */
16272 			asc_dvc->cfg->termination = 0;
16273 			warn_code |= ASC_WARN_EEPROM_TERMINATION;
16274 		}
16275 	}
16276 
16277 	return warn_code;
16278 }
16279 
16280 /*
16281  * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16282  * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16283  * all of this is done.
16284  *
16285  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16286  *
16287  * For a non-fatal error return a warning code. If there are no warnings
16288  * then 0 is returned.
16289  *
16290  * Note: Chip is stopped on entry.
16291  */
16292 static int __init AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
16293 {
16294 	AdvPortAddr iop_base;
16295 	ushort warn_code;
16296 	ADVEEP_38C0800_CONFIG eep_config;
16297 	int i;
16298 	uchar tid, termination;
16299 	ushort sdtr_speed = 0;
16300 
16301 	iop_base = asc_dvc->iop_base;
16302 
16303 	warn_code = 0;
16304 
16305 	/*
16306 	 * Read the board's EEPROM configuration.
16307 	 *
16308 	 * Set default values if a bad checksum is found.
16309 	 */
16310 	if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
16311 	    eep_config.check_sum) {
16312 		warn_code |= ASC_WARN_EEPROM_CHKSUM;
16313 
16314 		/*
16315 		 * Set EEPROM default values.
16316 		 */
16317 		for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++) {
16318 			*((uchar *)&eep_config + i) =
16319 			    *((uchar *)&Default_38C0800_EEPROM_Config + i);
16320 		}
16321 
16322 		/*
16323 		 * Assume the 6 byte board serial number that was read
16324 		 * from EEPROM is correct even if the EEPROM checksum
16325 		 * failed.
16326 		 */
16327 		eep_config.serial_number_word3 =
16328 		    AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16329 
16330 		eep_config.serial_number_word2 =
16331 		    AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16332 
16333 		eep_config.serial_number_word1 =
16334 		    AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16335 
16336 		AdvSet38C0800EEPConfig(iop_base, &eep_config);
16337 	}
16338 	/*
16339 	 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
16340 	 * EEPROM configuration that was read.
16341 	 *
16342 	 * This is the mapping of EEPROM fields to Adv Library fields.
16343 	 */
16344 	asc_dvc->wdtr_able = eep_config.wdtr_able;
16345 	asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16346 	asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16347 	asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16348 	asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16349 	asc_dvc->tagqng_able = eep_config.tagqng_able;
16350 	asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16351 	asc_dvc->max_host_qng = eep_config.max_host_qng;
16352 	asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16353 	asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16354 	asc_dvc->start_motor = eep_config.start_motor;
16355 	asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16356 	asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16357 	asc_dvc->no_scam = eep_config.scam_tolerant;
16358 	asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16359 	asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16360 	asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16361 
16362 	/*
16363 	 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16364 	 * are set, then set an 'sdtr_able' bit for it.
16365 	 */
16366 	asc_dvc->sdtr_able = 0;
16367 	for (tid = 0; tid <= ADV_MAX_TID; tid++) {
16368 		if (tid == 0) {
16369 			sdtr_speed = asc_dvc->sdtr_speed1;
16370 		} else if (tid == 4) {
16371 			sdtr_speed = asc_dvc->sdtr_speed2;
16372 		} else if (tid == 8) {
16373 			sdtr_speed = asc_dvc->sdtr_speed3;
16374 		} else if (tid == 12) {
16375 			sdtr_speed = asc_dvc->sdtr_speed4;
16376 		}
16377 		if (sdtr_speed & ADV_MAX_TID) {
16378 			asc_dvc->sdtr_able |= (1 << tid);
16379 		}
16380 		sdtr_speed >>= 4;
16381 	}
16382 
16383 	/*
16384 	 * Set the host maximum queuing (max. 253, min. 16) and the per device
16385 	 * maximum queuing (max. 63, min. 4).
16386 	 */
16387 	if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
16388 		eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16389 	} else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
16390 		/* If the value is zero, assume it is uninitialized. */
16391 		if (eep_config.max_host_qng == 0) {
16392 			eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16393 		} else {
16394 			eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16395 		}
16396 	}
16397 
16398 	if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
16399 		eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16400 	} else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
16401 		/* If the value is zero, assume it is uninitialized. */
16402 		if (eep_config.max_dvc_qng == 0) {
16403 			eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16404 		} else {
16405 			eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16406 		}
16407 	}
16408 
16409 	/*
16410 	 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16411 	 * set 'max_dvc_qng' to 'max_host_qng'.
16412 	 */
16413 	if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
16414 		eep_config.max_dvc_qng = eep_config.max_host_qng;
16415 	}
16416 
16417 	/*
16418 	 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16419 	 * values based on possibly adjusted EEPROM values.
16420 	 */
16421 	asc_dvc->max_host_qng = eep_config.max_host_qng;
16422 	asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16423 
16424 	/*
16425 	 * If the EEPROM 'termination' field is set to automatic (0), then set
16426 	 * the ADV_DVC_CFG 'termination' field to automatic also.
16427 	 *
16428 	 * If the termination is specified with a non-zero 'termination'
16429 	 * value check that a legal value is set and set the ADV_DVC_CFG
16430 	 * 'termination' field appropriately.
16431 	 */
16432 	if (eep_config.termination_se == 0) {
16433 		termination = 0;	/* auto termination for SE */
16434 	} else {
16435 		/* Enable manual control with low off / high off. */
16436 		if (eep_config.termination_se == 1) {
16437 			termination = 0;
16438 
16439 			/* Enable manual control with low off / high on. */
16440 		} else if (eep_config.termination_se == 2) {
16441 			termination = TERM_SE_HI;
16442 
16443 			/* Enable manual control with low on / high on. */
16444 		} else if (eep_config.termination_se == 3) {
16445 			termination = TERM_SE;
16446 		} else {
16447 			/*
16448 			 * The EEPROM 'termination_se' field contains a bad value.
16449 			 * Use automatic termination instead.
16450 			 */
16451 			termination = 0;
16452 			warn_code |= ASC_WARN_EEPROM_TERMINATION;
16453 		}
16454 	}
16455 
16456 	if (eep_config.termination_lvd == 0) {
16457 		asc_dvc->cfg->termination = termination;	/* auto termination for LVD */
16458 	} else {
16459 		/* Enable manual control with low off / high off. */
16460 		if (eep_config.termination_lvd == 1) {
16461 			asc_dvc->cfg->termination = termination;
16462 
16463 			/* Enable manual control with low off / high on. */
16464 		} else if (eep_config.termination_lvd == 2) {
16465 			asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16466 
16467 			/* Enable manual control with low on / high on. */
16468 		} else if (eep_config.termination_lvd == 3) {
16469 			asc_dvc->cfg->termination = termination | TERM_LVD;
16470 		} else {
16471 			/*
16472 			 * The EEPROM 'termination_lvd' field contains a bad value.
16473 			 * Use automatic termination instead.
16474 			 */
16475 			asc_dvc->cfg->termination = termination;
16476 			warn_code |= ASC_WARN_EEPROM_TERMINATION;
16477 		}
16478 	}
16479 
16480 	return warn_code;
16481 }
16482 
16483 /*
16484  * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
16485  * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
16486  * all of this is done.
16487  *
16488  * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
16489  *
16490  * For a non-fatal error return a warning code. If there are no warnings
16491  * then 0 is returned.
16492  *
16493  * Note: Chip is stopped on entry.
16494  */
16495 static int __init AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
16496 {
16497 	AdvPortAddr iop_base;
16498 	ushort warn_code;
16499 	ADVEEP_38C1600_CONFIG eep_config;
16500 	int i;
16501 	uchar tid, termination;
16502 	ushort sdtr_speed = 0;
16503 
16504 	iop_base = asc_dvc->iop_base;
16505 
16506 	warn_code = 0;
16507 
16508 	/*
16509 	 * Read the board's EEPROM configuration.
16510 	 *
16511 	 * Set default values if a bad checksum is found.
16512 	 */
16513 	if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
16514 	    eep_config.check_sum) {
16515 		warn_code |= ASC_WARN_EEPROM_CHKSUM;
16516 
16517 		/*
16518 		 * Set EEPROM default values.
16519 		 */
16520 		for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++) {
16521 			if (i == 1
16522 			    && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) !=
16523 			    0) {
16524 				/*
16525 				 * Set Function 1 EEPROM Word 0 MSB
16526 				 *
16527 				 * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11)
16528 				 * EEPROM bits.
16529 				 *
16530 				 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and
16531 				 * old Mac system booting problem. The Expansion ROM must
16532 				 * be disabled in Function 1 for these systems.
16533 				 *
16534 				 */
16535 				*((uchar *)&eep_config + i) =
16536 				    ((*
16537 				      ((uchar *)&Default_38C1600_EEPROM_Config
16538 				       +
16539 				       i)) &
16540 				     (~
16541 				      (((ADV_EEPROM_BIOS_ENABLE |
16542 					 ADV_EEPROM_INTAB) >> 8) & 0xFF)));
16543 
16544 				/*
16545 				 * Set the INTAB (bit 11) if the GPIO 0 input indicates
16546 				 * the Function 1 interrupt line is wired to INTA.
16547 				 *
16548 				 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
16549 				 *   1 - Function 1 interrupt line wired to INT A.
16550 				 *   0 - Function 1 interrupt line wired to INT B.
16551 				 *
16552 				 * Note: Adapter boards always have Function 0 wired to INTA.
16553 				 * Put all 5 GPIO bits in input mode and then read
16554 				 * their input values.
16555 				 */
16556 				AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL,
16557 						     0);
16558 				if (AdvReadByteRegister
16559 				    (iop_base, IOPB_GPIO_DATA) & 0x01) {
16560 					/* Function 1 interrupt wired to INTA; Set EEPROM bit. */
16561 					*((uchar *)&eep_config + i) |=
16562 					    ((ADV_EEPROM_INTAB >> 8) & 0xFF);
16563 				}
16564 			} else {
16565 				*((uchar *)&eep_config + i) =
16566 				    *((uchar *)&Default_38C1600_EEPROM_Config
16567 				      + i);
16568 			}
16569 		}
16570 
16571 		/*
16572 		 * Assume the 6 byte board serial number that was read
16573 		 * from EEPROM is correct even if the EEPROM checksum
16574 		 * failed.
16575 		 */
16576 		eep_config.serial_number_word3 =
16577 		    AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16578 
16579 		eep_config.serial_number_word2 =
16580 		    AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16581 
16582 		eep_config.serial_number_word1 =
16583 		    AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16584 
16585 		AdvSet38C1600EEPConfig(iop_base, &eep_config);
16586 	}
16587 
16588 	/*
16589 	 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16590 	 * EEPROM configuration that was read.
16591 	 *
16592 	 * This is the mapping of EEPROM fields to Adv Library fields.
16593 	 */
16594 	asc_dvc->wdtr_able = eep_config.wdtr_able;
16595 	asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16596 	asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16597 	asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16598 	asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16599 	asc_dvc->ppr_able = 0;
16600 	asc_dvc->tagqng_able = eep_config.tagqng_able;
16601 	asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16602 	asc_dvc->max_host_qng = eep_config.max_host_qng;
16603 	asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16604 	asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
16605 	asc_dvc->start_motor = eep_config.start_motor;
16606 	asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16607 	asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16608 	asc_dvc->no_scam = eep_config.scam_tolerant;
16609 
16610 	/*
16611 	 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16612 	 * are set, then set an 'sdtr_able' bit for it.
16613 	 */
16614 	asc_dvc->sdtr_able = 0;
16615 	for (tid = 0; tid <= ASC_MAX_TID; tid++) {
16616 		if (tid == 0) {
16617 			sdtr_speed = asc_dvc->sdtr_speed1;
16618 		} else if (tid == 4) {
16619 			sdtr_speed = asc_dvc->sdtr_speed2;
16620 		} else if (tid == 8) {
16621 			sdtr_speed = asc_dvc->sdtr_speed3;
16622 		} else if (tid == 12) {
16623 			sdtr_speed = asc_dvc->sdtr_speed4;
16624 		}
16625 		if (sdtr_speed & ASC_MAX_TID) {
16626 			asc_dvc->sdtr_able |= (1 << tid);
16627 		}
16628 		sdtr_speed >>= 4;
16629 	}
16630 
16631 	/*
16632 	 * Set the host maximum queuing (max. 253, min. 16) and the per device
16633 	 * maximum queuing (max. 63, min. 4).
16634 	 */
16635 	if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
16636 		eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16637 	} else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
16638 		/* If the value is zero, assume it is uninitialized. */
16639 		if (eep_config.max_host_qng == 0) {
16640 			eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16641 		} else {
16642 			eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16643 		}
16644 	}
16645 
16646 	if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
16647 		eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16648 	} else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
16649 		/* If the value is zero, assume it is uninitialized. */
16650 		if (eep_config.max_dvc_qng == 0) {
16651 			eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16652 		} else {
16653 			eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16654 		}
16655 	}
16656 
16657 	/*
16658 	 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16659 	 * set 'max_dvc_qng' to 'max_host_qng'.
16660 	 */
16661 	if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
16662 		eep_config.max_dvc_qng = eep_config.max_host_qng;
16663 	}
16664 
16665 	/*
16666 	 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
16667 	 * values based on possibly adjusted EEPROM values.
16668 	 */
16669 	asc_dvc->max_host_qng = eep_config.max_host_qng;
16670 	asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16671 
16672 	/*
16673 	 * If the EEPROM 'termination' field is set to automatic (0), then set
16674 	 * the ASC_DVC_CFG 'termination' field to automatic also.
16675 	 *
16676 	 * If the termination is specified with a non-zero 'termination'
16677 	 * value check that a legal value is set and set the ASC_DVC_CFG
16678 	 * 'termination' field appropriately.
16679 	 */
16680 	if (eep_config.termination_se == 0) {
16681 		termination = 0;	/* auto termination for SE */
16682 	} else {
16683 		/* Enable manual control with low off / high off. */
16684 		if (eep_config.termination_se == 1) {
16685 			termination = 0;
16686 
16687 			/* Enable manual control with low off / high on. */
16688 		} else if (eep_config.termination_se == 2) {
16689 			termination = TERM_SE_HI;
16690 
16691 			/* Enable manual control with low on / high on. */
16692 		} else if (eep_config.termination_se == 3) {
16693 			termination = TERM_SE;
16694 		} else {
16695 			/*
16696 			 * The EEPROM 'termination_se' field contains a bad value.
16697 			 * Use automatic termination instead.
16698 			 */
16699 			termination = 0;
16700 			warn_code |= ASC_WARN_EEPROM_TERMINATION;
16701 		}
16702 	}
16703 
16704 	if (eep_config.termination_lvd == 0) {
16705 		asc_dvc->cfg->termination = termination;	/* auto termination for LVD */
16706 	} else {
16707 		/* Enable manual control with low off / high off. */
16708 		if (eep_config.termination_lvd == 1) {
16709 			asc_dvc->cfg->termination = termination;
16710 
16711 			/* Enable manual control with low off / high on. */
16712 		} else if (eep_config.termination_lvd == 2) {
16713 			asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16714 
16715 			/* Enable manual control with low on / high on. */
16716 		} else if (eep_config.termination_lvd == 3) {
16717 			asc_dvc->cfg->termination = termination | TERM_LVD;
16718 		} else {
16719 			/*
16720 			 * The EEPROM 'termination_lvd' field contains a bad value.
16721 			 * Use automatic termination instead.
16722 			 */
16723 			asc_dvc->cfg->termination = termination;
16724 			warn_code |= ASC_WARN_EEPROM_TERMINATION;
16725 		}
16726 	}
16727 
16728 	return warn_code;
16729 }
16730 
16731 /*
16732  * Read EEPROM configuration into the specified buffer.
16733  *
16734  * Return a checksum based on the EEPROM configuration read.
16735  */
16736 static ushort __init
16737 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16738 {
16739 	ushort wval, chksum;
16740 	ushort *wbuf;
16741 	int eep_addr;
16742 	ushort *charfields;
16743 
16744 	charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16745 	wbuf = (ushort *)cfg_buf;
16746 	chksum = 0;
16747 
16748 	for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16749 	     eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16750 		wval = AdvReadEEPWord(iop_base, eep_addr);
16751 		chksum += wval;	/* Checksum is calculated from word values. */
16752 		if (*charfields++) {
16753 			*wbuf = le16_to_cpu(wval);
16754 		} else {
16755 			*wbuf = wval;
16756 		}
16757 	}
16758 	/* Read checksum word. */
16759 	*wbuf = AdvReadEEPWord(iop_base, eep_addr);
16760 	wbuf++;
16761 	charfields++;
16762 
16763 	/* Read rest of EEPROM not covered by the checksum. */
16764 	for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16765 	     eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16766 		*wbuf = AdvReadEEPWord(iop_base, eep_addr);
16767 		if (*charfields++) {
16768 			*wbuf = le16_to_cpu(*wbuf);
16769 		}
16770 	}
16771 	return chksum;
16772 }
16773 
16774 /*
16775  * Read EEPROM configuration into the specified buffer.
16776  *
16777  * Return a checksum based on the EEPROM configuration read.
16778  */
16779 static ushort __init
16780 AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
16781 {
16782 	ushort wval, chksum;
16783 	ushort *wbuf;
16784 	int eep_addr;
16785 	ushort *charfields;
16786 
16787 	charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16788 	wbuf = (ushort *)cfg_buf;
16789 	chksum = 0;
16790 
16791 	for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16792 	     eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16793 		wval = AdvReadEEPWord(iop_base, eep_addr);
16794 		chksum += wval;	/* Checksum is calculated from word values. */
16795 		if (*charfields++) {
16796 			*wbuf = le16_to_cpu(wval);
16797 		} else {
16798 			*wbuf = wval;
16799 		}
16800 	}
16801 	/* Read checksum word. */
16802 	*wbuf = AdvReadEEPWord(iop_base, eep_addr);
16803 	wbuf++;
16804 	charfields++;
16805 
16806 	/* Read rest of EEPROM not covered by the checksum. */
16807 	for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16808 	     eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16809 		*wbuf = AdvReadEEPWord(iop_base, eep_addr);
16810 		if (*charfields++) {
16811 			*wbuf = le16_to_cpu(*wbuf);
16812 		}
16813 	}
16814 	return chksum;
16815 }
16816 
16817 /*
16818  * Read EEPROM configuration into the specified buffer.
16819  *
16820  * Return a checksum based on the EEPROM configuration read.
16821  */
16822 static ushort __init
16823 AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
16824 {
16825 	ushort wval, chksum;
16826 	ushort *wbuf;
16827 	int eep_addr;
16828 	ushort *charfields;
16829 
16830 	charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16831 	wbuf = (ushort *)cfg_buf;
16832 	chksum = 0;
16833 
16834 	for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16835 	     eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16836 		wval = AdvReadEEPWord(iop_base, eep_addr);
16837 		chksum += wval;	/* Checksum is calculated from word values. */
16838 		if (*charfields++) {
16839 			*wbuf = le16_to_cpu(wval);
16840 		} else {
16841 			*wbuf = wval;
16842 		}
16843 	}
16844 	/* Read checksum word. */
16845 	*wbuf = AdvReadEEPWord(iop_base, eep_addr);
16846 	wbuf++;
16847 	charfields++;
16848 
16849 	/* Read rest of EEPROM not covered by the checksum. */
16850 	for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16851 	     eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16852 		*wbuf = AdvReadEEPWord(iop_base, eep_addr);
16853 		if (*charfields++) {
16854 			*wbuf = le16_to_cpu(*wbuf);
16855 		}
16856 	}
16857 	return chksum;
16858 }
16859 
16860 /*
16861  * Read the EEPROM from specified location
16862  */
16863 static ushort __init AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
16864 {
16865 	AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16866 			     ASC_EEP_CMD_READ | eep_word_addr);
16867 	AdvWaitEEPCmd(iop_base);
16868 	return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
16869 }
16870 
16871 /*
16872  * Wait for EEPROM command to complete
16873  */
16874 static void __init AdvWaitEEPCmd(AdvPortAddr iop_base)
16875 {
16876 	int eep_delay_ms;
16877 
16878 	for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
16879 		if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
16880 		    ASC_EEP_CMD_DONE) {
16881 			break;
16882 		}
16883 		DvcSleepMilliSecond(1);
16884 	}
16885 	if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
16886 	    0) {
16887 		ASC_ASSERT(0);
16888 	}
16889 	return;
16890 }
16891 
16892 /*
16893  * Write the EEPROM from 'cfg_buf'.
16894  */
16895 void __init
16896 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16897 {
16898 	ushort *wbuf;
16899 	ushort addr, chksum;
16900 	ushort *charfields;
16901 
16902 	wbuf = (ushort *)cfg_buf;
16903 	charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16904 	chksum = 0;
16905 
16906 	AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16907 	AdvWaitEEPCmd(iop_base);
16908 
16909 	/*
16910 	 * Write EEPROM from word 0 to word 20.
16911 	 */
16912 	for (addr = ADV_EEP_DVC_CFG_BEGIN;
16913 	     addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16914 		ushort word;
16915 
16916 		if (*charfields++) {
16917 			word = cpu_to_le16(*wbuf);
16918 		} else {
16919 			word = *wbuf;
16920 		}
16921 		chksum += *wbuf;	/* Checksum is calculated from word values. */
16922 		AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16923 		AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16924 				     ASC_EEP_CMD_WRITE | addr);
16925 		AdvWaitEEPCmd(iop_base);
16926 		DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16927 	}
16928 
16929 	/*
16930 	 * Write EEPROM checksum at word 21.
16931 	 */
16932 	AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16933 	AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16934 	AdvWaitEEPCmd(iop_base);
16935 	wbuf++;
16936 	charfields++;
16937 
16938 	/*
16939 	 * Write EEPROM OEM name at words 22 to 29.
16940 	 */
16941 	for (addr = ADV_EEP_DVC_CTL_BEGIN;
16942 	     addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16943 		ushort word;
16944 
16945 		if (*charfields++) {
16946 			word = cpu_to_le16(*wbuf);
16947 		} else {
16948 			word = *wbuf;
16949 		}
16950 		AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16951 		AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16952 				     ASC_EEP_CMD_WRITE | addr);
16953 		AdvWaitEEPCmd(iop_base);
16954 	}
16955 	AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16956 	AdvWaitEEPCmd(iop_base);
16957 	return;
16958 }
16959 
16960 /*
16961  * Write the EEPROM from 'cfg_buf'.
16962  */
16963 void __init
16964 AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
16965 {
16966 	ushort *wbuf;
16967 	ushort *charfields;
16968 	ushort addr, chksum;
16969 
16970 	wbuf = (ushort *)cfg_buf;
16971 	charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16972 	chksum = 0;
16973 
16974 	AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16975 	AdvWaitEEPCmd(iop_base);
16976 
16977 	/*
16978 	 * Write EEPROM from word 0 to word 20.
16979 	 */
16980 	for (addr = ADV_EEP_DVC_CFG_BEGIN;
16981 	     addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16982 		ushort word;
16983 
16984 		if (*charfields++) {
16985 			word = cpu_to_le16(*wbuf);
16986 		} else {
16987 			word = *wbuf;
16988 		}
16989 		chksum += *wbuf;	/* Checksum is calculated from word values. */
16990 		AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16991 		AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16992 				     ASC_EEP_CMD_WRITE | addr);
16993 		AdvWaitEEPCmd(iop_base);
16994 		DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16995 	}
16996 
16997 	/*
16998 	 * Write EEPROM checksum at word 21.
16999 	 */
17000 	AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17001 	AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17002 	AdvWaitEEPCmd(iop_base);
17003 	wbuf++;
17004 	charfields++;
17005 
17006 	/*
17007 	 * Write EEPROM OEM name at words 22 to 29.
17008 	 */
17009 	for (addr = ADV_EEP_DVC_CTL_BEGIN;
17010 	     addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
17011 		ushort word;
17012 
17013 		if (*charfields++) {
17014 			word = cpu_to_le16(*wbuf);
17015 		} else {
17016 			word = *wbuf;
17017 		}
17018 		AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17019 		AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
17020 				     ASC_EEP_CMD_WRITE | addr);
17021 		AdvWaitEEPCmd(iop_base);
17022 	}
17023 	AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17024 	AdvWaitEEPCmd(iop_base);
17025 	return;
17026 }
17027 
17028 /*
17029  * Write the EEPROM from 'cfg_buf'.
17030  */
17031 void __init
17032 AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
17033 {
17034 	ushort *wbuf;
17035 	ushort *charfields;
17036 	ushort addr, chksum;
17037 
17038 	wbuf = (ushort *)cfg_buf;
17039 	charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
17040 	chksum = 0;
17041 
17042 	AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17043 	AdvWaitEEPCmd(iop_base);
17044 
17045 	/*
17046 	 * Write EEPROM from word 0 to word 20.
17047 	 */
17048 	for (addr = ADV_EEP_DVC_CFG_BEGIN;
17049 	     addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
17050 		ushort word;
17051 
17052 		if (*charfields++) {
17053 			word = cpu_to_le16(*wbuf);
17054 		} else {
17055 			word = *wbuf;
17056 		}
17057 		chksum += *wbuf;	/* Checksum is calculated from word values. */
17058 		AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17059 		AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
17060 				     ASC_EEP_CMD_WRITE | addr);
17061 		AdvWaitEEPCmd(iop_base);
17062 		DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17063 	}
17064 
17065 	/*
17066 	 * Write EEPROM checksum at word 21.
17067 	 */
17068 	AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17069 	AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17070 	AdvWaitEEPCmd(iop_base);
17071 	wbuf++;
17072 	charfields++;
17073 
17074 	/*
17075 	 * Write EEPROM OEM name at words 22 to 29.
17076 	 */
17077 	for (addr = ADV_EEP_DVC_CTL_BEGIN;
17078 	     addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
17079 		ushort word;
17080 
17081 		if (*charfields++) {
17082 			word = cpu_to_le16(*wbuf);
17083 		} else {
17084 			word = *wbuf;
17085 		}
17086 		AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17087 		AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
17088 				     ASC_EEP_CMD_WRITE | addr);
17089 		AdvWaitEEPCmd(iop_base);
17090 	}
17091 	AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17092 	AdvWaitEEPCmd(iop_base);
17093 	return;
17094 }
17095 
17096 /* a_advlib.c */
17097 /*
17098  * AdvExeScsiQueue() - Send a request to the RISC microcode program.
17099  *
17100  *   Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
17101  *   add the carrier to the ICQ (Initiator Command Queue), and tickle the
17102  *   RISC to notify it a new command is ready to be executed.
17103  *
17104  * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
17105  * set to SCSI_MAX_RETRY.
17106  *
17107  * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
17108  * for DMA addresses or math operations are byte swapped to little-endian
17109  * order.
17110  *
17111  * Return:
17112  *      ADV_SUCCESS(1) - The request was successfully queued.
17113  *      ADV_BUSY(0) -    Resource unavailable; Retry again after pending
17114  *                       request completes.
17115  *      ADV_ERROR(-1) -  Invalid ADV_SCSI_REQ_Q request structure
17116  *                       host IC error.
17117  */
17118 static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
17119 {
17120 	ulong last_int_level;
17121 	AdvPortAddr iop_base;
17122 	ADV_DCNT req_size;
17123 	ADV_PADDR req_paddr;
17124 	ADV_CARR_T *new_carrp;
17125 
17126 	ASC_ASSERT(scsiq != NULL);	/* 'scsiq' should never be NULL. */
17127 
17128 	/*
17129 	 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
17130 	 */
17131 	if (scsiq->target_id > ADV_MAX_TID) {
17132 		scsiq->host_status = QHSTA_M_INVALID_DEVICE;
17133 		scsiq->done_status = QD_WITH_ERROR;
17134 		return ADV_ERROR;
17135 	}
17136 
17137 	iop_base = asc_dvc->iop_base;
17138 
17139 	last_int_level = DvcEnterCritical();
17140 
17141 	/*
17142 	 * Allocate a carrier ensuring at least one carrier always
17143 	 * remains on the freelist and initialize fields.
17144 	 */
17145 	if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
17146 		DvcLeaveCritical(last_int_level);
17147 		return ADV_BUSY;
17148 	}
17149 	asc_dvc->carr_freelist = (ADV_CARR_T *)
17150 	    ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
17151 	asc_dvc->carr_pending_cnt++;
17152 
17153 	/*
17154 	 * Set the carrier to be a stopper by setting 'next_vpa'
17155 	 * to the stopper value. The current stopper will be changed
17156 	 * below to point to the new stopper.
17157 	 */
17158 	new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
17159 
17160 	/*
17161 	 * Clear the ADV_SCSI_REQ_Q done flag.
17162 	 */
17163 	scsiq->a_flag &= ~ADV_SCSIQ_DONE;
17164 
17165 	req_size = sizeof(ADV_SCSI_REQ_Q);
17166 	req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
17167 				  (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
17168 
17169 	ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
17170 	ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
17171 
17172 	/* Wait for assertion before making little-endian */
17173 	req_paddr = cpu_to_le32(req_paddr);
17174 
17175 	/* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
17176 	scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
17177 	scsiq->scsiq_rptr = req_paddr;
17178 
17179 	scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
17180 	/*
17181 	 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
17182 	 * order during initialization.
17183 	 */
17184 	scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
17185 
17186 	/*
17187 	 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
17188 	 * the microcode. The newly allocated stopper will become the new
17189 	 * stopper.
17190 	 */
17191 	asc_dvc->icq_sp->areq_vpa = req_paddr;
17192 
17193 	/*
17194 	 * Set the 'next_vpa' pointer for the old stopper to be the
17195 	 * physical address of the new stopper. The RISC can only
17196 	 * follow physical addresses.
17197 	 */
17198 	asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
17199 
17200 	/*
17201 	 * Set the host adapter stopper pointer to point to the new carrier.
17202 	 */
17203 	asc_dvc->icq_sp = new_carrp;
17204 
17205 	if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17206 	    asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
17207 		/*
17208 		 * Tickle the RISC to tell it to read its Command Queue Head pointer.
17209 		 */
17210 		AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
17211 		if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
17212 			/*
17213 			 * Clear the tickle value. In the ASC-3550 the RISC flag
17214 			 * command 'clr_tickle_a' does not work unless the host
17215 			 * value is cleared.
17216 			 */
17217 			AdvWriteByteRegister(iop_base, IOPB_TICKLE,
17218 					     ADV_TICKLE_NOP);
17219 		}
17220 	} else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17221 		/*
17222 		 * Notify the RISC a carrier is ready by writing the physical
17223 		 * address of the new carrier stopper to the COMMA register.
17224 		 */
17225 		AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
17226 				      le32_to_cpu(new_carrp->carr_pa));
17227 	}
17228 
17229 	DvcLeaveCritical(last_int_level);
17230 
17231 	return ADV_SUCCESS;
17232 }
17233 
17234 /*
17235  * Reset SCSI Bus and purge all outstanding requests.
17236  *
17237  * Return Value:
17238  *      ADV_TRUE(1) -   All requests are purged and SCSI Bus is reset.
17239  *      ADV_FALSE(0) -  Microcode command failed.
17240  *      ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
17241  *                      may be hung which requires driver recovery.
17242  */
17243 static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
17244 {
17245 	int status;
17246 
17247 	/*
17248 	 * Send the SCSI Bus Reset idle start idle command which asserts
17249 	 * the SCSI Bus Reset signal.
17250 	 */
17251 	status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
17252 	if (status != ADV_TRUE) {
17253 		return status;
17254 	}
17255 
17256 	/*
17257 	 * Delay for the specified SCSI Bus Reset hold time.
17258 	 *
17259 	 * The hold time delay is done on the host because the RISC has no
17260 	 * microsecond accurate timer.
17261 	 */
17262 	DvcDelayMicroSecond(asc_dvc, (ushort)ASC_SCSI_RESET_HOLD_TIME_US);
17263 
17264 	/*
17265 	 * Send the SCSI Bus Reset end idle command which de-asserts
17266 	 * the SCSI Bus Reset signal and purges any pending requests.
17267 	 */
17268 	status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
17269 	if (status != ADV_TRUE) {
17270 		return status;
17271 	}
17272 
17273 	DvcSleepMilliSecond((ADV_DCNT)asc_dvc->scsi_reset_wait * 1000);
17274 
17275 	return status;
17276 }
17277 
17278 /*
17279  * Reset chip and SCSI Bus.
17280  *
17281  * Return Value:
17282  *      ADV_TRUE(1) -   Chip re-initialization and SCSI Bus Reset successful.
17283  *      ADV_FALSE(0) -  Chip re-initialization and SCSI Bus Reset failure.
17284  */
17285 static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
17286 {
17287 	int status;
17288 	ushort wdtr_able, sdtr_able, tagqng_able;
17289 	ushort ppr_able = 0;
17290 	uchar tid, max_cmd[ADV_MAX_TID + 1];
17291 	AdvPortAddr iop_base;
17292 	ushort bios_sig;
17293 
17294 	iop_base = asc_dvc->iop_base;
17295 
17296 	/*
17297 	 * Save current per TID negotiated values.
17298 	 */
17299 	AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17300 	AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17301 	if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17302 		AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17303 	}
17304 	AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17305 	for (tid = 0; tid <= ADV_MAX_TID; tid++) {
17306 		AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17307 				max_cmd[tid]);
17308 	}
17309 
17310 	/*
17311 	 * Force the AdvInitAsc3550/38C0800Driver() function to
17312 	 * perform a SCSI Bus Reset by clearing the BIOS signature word.
17313 	 * The initialization functions assumes a SCSI Bus Reset is not
17314 	 * needed if the BIOS signature word is present.
17315 	 */
17316 	AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17317 	AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
17318 
17319 	/*
17320 	 * Stop chip and reset it.
17321 	 */
17322 	AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
17323 	AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
17324 	DvcSleepMilliSecond(100);
17325 	AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
17326 			     ADV_CTRL_REG_CMD_WR_IO_REG);
17327 
17328 	/*
17329 	 * Reset Adv Library error code, if any, and try
17330 	 * re-initializing the chip.
17331 	 */
17332 	asc_dvc->err_code = 0;
17333 	if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17334 		status = AdvInitAsc38C1600Driver(asc_dvc);
17335 	} else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
17336 		status = AdvInitAsc38C0800Driver(asc_dvc);
17337 	} else {
17338 		status = AdvInitAsc3550Driver(asc_dvc);
17339 	}
17340 
17341 	/* Translate initialization return value to status value. */
17342 	if (status == 0) {
17343 		status = ADV_TRUE;
17344 	} else {
17345 		status = ADV_FALSE;
17346 	}
17347 
17348 	/*
17349 	 * Restore the BIOS signature word.
17350 	 */
17351 	AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17352 
17353 	/*
17354 	 * Restore per TID negotiated values.
17355 	 */
17356 	AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17357 	AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17358 	if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17359 		AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17360 	}
17361 	AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17362 	for (tid = 0; tid <= ADV_MAX_TID; tid++) {
17363 		AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17364 				 max_cmd[tid]);
17365 	}
17366 
17367 	return status;
17368 }
17369 
17370 /*
17371  * Adv Library Interrupt Service Routine
17372  *
17373  *  This function is called by a driver's interrupt service routine.
17374  *  The function disables and re-enables interrupts.
17375  *
17376  *  When a microcode idle command is completed, the ADV_DVC_VAR
17377  *  'idle_cmd_done' field is set to ADV_TRUE.
17378  *
17379  *  Note: AdvISR() can be called when interrupts are disabled or even
17380  *  when there is no hardware interrupt condition present. It will
17381  *  always check for completed idle commands and microcode requests.
17382  *  This is an important feature that shouldn't be changed because it
17383  *  allows commands to be completed from polling mode loops.
17384  *
17385  * Return:
17386  *   ADV_TRUE(1) - interrupt was pending
17387  *   ADV_FALSE(0) - no interrupt was pending
17388  */
17389 static int AdvISR(ADV_DVC_VAR *asc_dvc)
17390 {
17391 	AdvPortAddr iop_base;
17392 	uchar int_stat;
17393 	ushort target_bit;
17394 	ADV_CARR_T *free_carrp;
17395 	ADV_VADDR irq_next_vpa;
17396 	int flags;
17397 	ADV_SCSI_REQ_Q *scsiq;
17398 
17399 	flags = DvcEnterCritical();
17400 
17401 	iop_base = asc_dvc->iop_base;
17402 
17403 	/* Reading the register clears the interrupt. */
17404 	int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
17405 
17406 	if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
17407 			 ADV_INTR_STATUS_INTRC)) == 0) {
17408 		DvcLeaveCritical(flags);
17409 		return ADV_FALSE;
17410 	}
17411 
17412 	/*
17413 	 * Notify the driver of an asynchronous microcode condition by
17414 	 * calling the ADV_DVC_VAR.async_callback function. The function
17415 	 * is passed the microcode ASC_MC_INTRB_CODE byte value.
17416 	 */
17417 	if (int_stat & ADV_INTR_STATUS_INTRB) {
17418 		uchar intrb_code;
17419 
17420 		AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
17421 
17422 		if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17423 		    asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
17424 			if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
17425 			    asc_dvc->carr_pending_cnt != 0) {
17426 				AdvWriteByteRegister(iop_base, IOPB_TICKLE,
17427 						     ADV_TICKLE_A);
17428 				if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
17429 					AdvWriteByteRegister(iop_base,
17430 							     IOPB_TICKLE,
17431 							     ADV_TICKLE_NOP);
17432 				}
17433 			}
17434 		}
17435 
17436 		if (asc_dvc->async_callback != 0) {
17437 			(*asc_dvc->async_callback) (asc_dvc, intrb_code);
17438 		}
17439 	}
17440 
17441 	/*
17442 	 * Check if the IRQ stopper carrier contains a completed request.
17443 	 */
17444 	while (((irq_next_vpa =
17445 		 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
17446 		/*
17447 		 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
17448 		 * The RISC will have set 'areq_vpa' to a virtual address.
17449 		 *
17450 		 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
17451 		 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
17452 		 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
17453 		 * in AdvExeScsiQueue().
17454 		 */
17455 		scsiq = (ADV_SCSI_REQ_Q *)
17456 		    ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
17457 
17458 		/*
17459 		 * Request finished with good status and the queue was not
17460 		 * DMAed to host memory by the firmware. Set all status fields
17461 		 * to indicate good status.
17462 		 */
17463 		if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
17464 			scsiq->done_status = QD_NO_ERROR;
17465 			scsiq->host_status = scsiq->scsi_status = 0;
17466 			scsiq->data_cnt = 0L;
17467 		}
17468 
17469 		/*
17470 		 * Advance the stopper pointer to the next carrier
17471 		 * ignoring the lower four bits. Free the previous
17472 		 * stopper carrier.
17473 		 */
17474 		free_carrp = asc_dvc->irq_sp;
17475 		asc_dvc->irq_sp = (ADV_CARR_T *)
17476 		    ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
17477 
17478 		free_carrp->next_vpa =
17479 		    cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
17480 		asc_dvc->carr_freelist = free_carrp;
17481 		asc_dvc->carr_pending_cnt--;
17482 
17483 		ASC_ASSERT(scsiq != NULL);
17484 		target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
17485 
17486 		/*
17487 		 * Clear request microcode control flag.
17488 		 */
17489 		scsiq->cntl = 0;
17490 
17491 		/*
17492 		 * If the command that completed was a SCSI INQUIRY and
17493 		 * LUN 0 was sent the command, then process the INQUIRY
17494 		 * command information for the device.
17495 		 *
17496 		 * Note: If data returned were either VPD or CmdDt data,
17497 		 * don't process the INQUIRY command information for
17498 		 * the device, otherwise may erroneously set *_able bits.
17499 		 */
17500 		if (scsiq->done_status == QD_NO_ERROR &&
17501 		    scsiq->cdb[0] == INQUIRY &&
17502 		    scsiq->target_lun == 0 &&
17503 		    (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
17504 		    == ADV_INQ_RTN_STD_INQUIRY_DATA) {
17505 			AdvInquiryHandling(asc_dvc, scsiq);
17506 		}
17507 
17508 		/*
17509 		 * Notify the driver of the completed request by passing
17510 		 * the ADV_SCSI_REQ_Q pointer to its callback function.
17511 		 */
17512 		scsiq->a_flag |= ADV_SCSIQ_DONE;
17513 		(*asc_dvc->isr_callback) (asc_dvc, scsiq);
17514 		/*
17515 		 * Note: After the driver callback function is called, 'scsiq'
17516 		 * can no longer be referenced.
17517 		 *
17518 		 * Fall through and continue processing other completed
17519 		 * requests...
17520 		 */
17521 
17522 		/*
17523 		 * Disable interrupts again in case the driver inadvertently
17524 		 * enabled interrupts in its callback function.
17525 		 *
17526 		 * The DvcEnterCritical() return value is ignored, because
17527 		 * the 'flags' saved when AdvISR() was first entered will be
17528 		 * used to restore the interrupt flag on exit.
17529 		 */
17530 		(void)DvcEnterCritical();
17531 	}
17532 	DvcLeaveCritical(flags);
17533 	return ADV_TRUE;
17534 }
17535 
17536 /*
17537  * Send an idle command to the chip and wait for completion.
17538  *
17539  * Command completion is polled for once per microsecond.
17540  *
17541  * The function can be called from anywhere including an interrupt handler.
17542  * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
17543  * functions to prevent reentrancy.
17544  *
17545  * Return Values:
17546  *   ADV_TRUE - command completed successfully
17547  *   ADV_FALSE - command failed
17548  *   ADV_ERROR - command timed out
17549  */
17550 static int
17551 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
17552 	       ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
17553 {
17554 	ulong last_int_level;
17555 	int result;
17556 	ADV_DCNT i, j;
17557 	AdvPortAddr iop_base;
17558 
17559 	last_int_level = DvcEnterCritical();
17560 
17561 	iop_base = asc_dvc->iop_base;
17562 
17563 	/*
17564 	 * Clear the idle command status which is set by the microcode
17565 	 * to a non-zero value to indicate when the command is completed.
17566 	 * The non-zero result is one of the IDLE_CMD_STATUS_* values
17567 	 * defined in a_advlib.h.
17568 	 */
17569 	AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
17570 
17571 	/*
17572 	 * Write the idle command value after the idle command parameter
17573 	 * has been written to avoid a race condition. If the order is not
17574 	 * followed, the microcode may process the idle command before the
17575 	 * parameters have been written to LRAM.
17576 	 */
17577 	AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
17578 				cpu_to_le32(idle_cmd_parameter));
17579 	AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
17580 
17581 	/*
17582 	 * Tickle the RISC to tell it to process the idle command.
17583 	 */
17584 	AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
17585 	if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
17586 		/*
17587 		 * Clear the tickle value. In the ASC-3550 the RISC flag
17588 		 * command 'clr_tickle_b' does not work unless the host
17589 		 * value is cleared.
17590 		 */
17591 		AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17592 	}
17593 
17594 	/* Wait for up to 100 millisecond for the idle command to timeout. */
17595 	for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
17596 		/* Poll once each microsecond for command completion. */
17597 		for (j = 0; j < SCSI_US_PER_MSEC; j++) {
17598 			AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
17599 					result);
17600 			if (result != 0) {
17601 				DvcLeaveCritical(last_int_level);
17602 				return result;
17603 			}
17604 			DvcDelayMicroSecond(asc_dvc, (ushort)1);
17605 		}
17606 	}
17607 
17608 	ASC_ASSERT(0);		/* The idle command should never timeout. */
17609 	DvcLeaveCritical(last_int_level);
17610 	return ADV_ERROR;
17611 }
17612 
17613 /*
17614  * Inquiry Information Byte 7 Handling
17615  *
17616  * Handle SCSI Inquiry Command information for a device by setting
17617  * microcode operating variables that affect WDTR, SDTR, and Tag
17618  * Queuing.
17619  */
17620 static void AdvInquiryHandling(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
17621 {
17622 	AdvPortAddr iop_base;
17623 	uchar tid;
17624 	ADV_SCSI_INQUIRY *inq;
17625 	ushort tidmask;
17626 	ushort cfg_word;
17627 
17628 	/*
17629 	 * AdvInquiryHandling() requires up to INQUIRY information Byte 7
17630 	 * to be available.
17631 	 *
17632 	 * If less than 8 bytes of INQUIRY information were requested or less
17633 	 * than 8 bytes were transferred, then return. cdb[4] is the request
17634 	 * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
17635 	 * microcode to the transfer residual count.
17636 	 */
17637 
17638 	if (scsiq->cdb[4] < 8 ||
17639 	    (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8) {
17640 		return;
17641 	}
17642 
17643 	iop_base = asc_dvc->iop_base;
17644 	tid = scsiq->target_id;
17645 
17646 	inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr;
17647 
17648 	/*
17649 	 * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
17650 	 */
17651 	if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2) {
17652 		return;
17653 	} else {
17654 		/*
17655 		 * INQUIRY Byte 7 Handling
17656 		 *
17657 		 * Use a device's INQUIRY byte 7 to determine whether it
17658 		 * supports WDTR, SDTR, and Tag Queuing. If the feature
17659 		 * is enabled in the EEPROM and the device supports the
17660 		 * feature, then enable it in the microcode.
17661 		 */
17662 
17663 		tidmask = ADV_TID_TO_TIDMASK(tid);
17664 
17665 		/*
17666 		 * Wide Transfers
17667 		 *
17668 		 * If the EEPROM enabled WDTR for the device and the device
17669 		 * supports wide bus (16 bit) transfers, then turn on the
17670 		 * device's 'wdtr_able' bit and write the new value to the
17671 		 * microcode.
17672 		 */
17673 		if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq)) {
17674 			AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
17675 			if ((cfg_word & tidmask) == 0) {
17676 				cfg_word |= tidmask;
17677 				AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
17678 						 cfg_word);
17679 
17680 				/*
17681 				 * Clear the microcode "SDTR negotiation" and "WDTR
17682 				 * negotiation" done indicators for the target to cause
17683 				 * it to negotiate with the new setting set above.
17684 				 * WDTR when accepted causes the target to enter
17685 				 * asynchronous mode, so SDTR must be negotiated.
17686 				 */
17687 				AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE,
17688 						cfg_word);
17689 				cfg_word &= ~tidmask;
17690 				AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE,
17691 						 cfg_word);
17692 				AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE,
17693 						cfg_word);
17694 				cfg_word &= ~tidmask;
17695 				AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE,
17696 						 cfg_word);
17697 			}
17698 		}
17699 
17700 		/*
17701 		 * Synchronous Transfers
17702 		 *
17703 		 * If the EEPROM enabled SDTR for the device and the device
17704 		 * supports synchronous transfers, then turn on the device's
17705 		 * 'sdtr_able' bit. Write the new value to the microcode.
17706 		 */
17707 		if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq)) {
17708 			AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
17709 			if ((cfg_word & tidmask) == 0) {
17710 				cfg_word |= tidmask;
17711 				AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
17712 						 cfg_word);
17713 
17714 				/*
17715 				 * Clear the microcode "SDTR negotiation" done indicator
17716 				 * for the target to cause it to negotiate with the new
17717 				 * setting set above.
17718 				 */
17719 				AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE,
17720 						cfg_word);
17721 				cfg_word &= ~tidmask;
17722 				AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE,
17723 						 cfg_word);
17724 			}
17725 		}
17726 		/*
17727 		 * If the Inquiry data included enough space for the SPI-3
17728 		 * Clocking field, then check if DT mode is supported.
17729 		 */
17730 		if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 &&
17731 		    (scsiq->cdb[4] >= 57 ||
17732 		     (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57)) {
17733 			/*
17734 			 * PPR (Parallel Protocol Request) Capable
17735 			 *
17736 			 * If the device supports DT mode, then it must be PPR capable.
17737 			 * The PPR message will be used in place of the SDTR and WDTR
17738 			 * messages to negotiate synchronous speed and offset, transfer
17739 			 * width, and protocol options.
17740 			 */
17741 			if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY) {
17742 				AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE,
17743 						asc_dvc->ppr_able);
17744 				asc_dvc->ppr_able |= tidmask;
17745 				AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE,
17746 						 asc_dvc->ppr_able);
17747 			}
17748 		}
17749 
17750 		/*
17751 		 * If the EEPROM enabled Tag Queuing for the device and the
17752 		 * device supports Tag Queueing, then turn on the device's
17753 		 * 'tagqng_enable' bit in the microcode and set the microcode
17754 		 * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
17755 		 * value.
17756 		 *
17757 		 * Tag Queuing is disabled for the BIOS which runs in polled
17758 		 * mode and would see no benefit from Tag Queuing. Also by
17759 		 * disabling Tag Queuing in the BIOS devices with Tag Queuing
17760 		 * bugs will at least work with the BIOS.
17761 		 */
17762 		if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq)) {
17763 			AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
17764 			cfg_word |= tidmask;
17765 			AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
17766 					 cfg_word);
17767 
17768 			AdvWriteByteLram(iop_base,
17769 					 ASC_MC_NUMBER_OF_MAX_CMD + tid,
17770 					 asc_dvc->max_dvc_qng);
17771 		}
17772 	}
17773 }
17774 
17775 MODULE_LICENSE("Dual BSD/GPL");
17776 
17777 static struct Scsi_Host *__devinit
17778 advansys_board_found(int iop, struct device *dev, int bus_type)
17779 {
17780 	struct Scsi_Host *shost;
17781 	struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL;
17782 	asc_board_t *boardp;
17783 	ASC_DVC_VAR *asc_dvc_varp = NULL;
17784 	ADV_DVC_VAR *adv_dvc_varp = NULL;
17785 	adv_sgblk_t *sgp = NULL;
17786 	int share_irq = FALSE;
17787 	int iolen = 0;
17788 	ADV_PADDR pci_memory_address;
17789 	int warn_code, err_code;
17790 	int ret;
17791 
17792 	/*
17793 	 * Adapter found.
17794 	 *
17795 	 * Register the adapter, get its configuration, and
17796 	 * initialize it.
17797 	 */
17798 	ASC_DBG(2, "advansys_board_found: scsi_register()\n");
17799 	shost = scsi_register(&driver_template, sizeof(asc_board_t));
17800 
17801 	if (!shost)
17802 		return NULL;
17803 
17804 	/* Save a pointer to the Scsi_Host of each board found. */
17805 	asc_host[asc_board_count++] = shost;
17806 
17807 	/* Initialize private per board data */
17808 	boardp = ASC_BOARDP(shost);
17809 	memset(boardp, 0, sizeof(asc_board_t));
17810 	boardp->id = asc_board_count - 1;
17811 
17812 	/* Initialize spinlock. */
17813 	spin_lock_init(&boardp->lock);
17814 
17815 	/*
17816 	 * Handle both narrow and wide boards.
17817 	 *
17818 	 * If a Wide board was detected, set the board structure
17819 	 * wide board flag. Set-up the board structure based on
17820 	 * the board type.
17821 	 */
17822 #ifdef CONFIG_PCI
17823 	if (bus_type == ASC_IS_PCI &&
17824 	    (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
17825 	     pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
17826 	     pdev->device == PCI_DEVICE_ID_38C1600_REV1)) {
17827 		boardp->flags |= ASC_IS_WIDE_BOARD;
17828 	}
17829 #endif /* CONFIG_PCI */
17830 
17831 	if (ASC_NARROW_BOARD(boardp)) {
17832 		ASC_DBG(1, "advansys_board_found: narrow board\n");
17833 		asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
17834 		asc_dvc_varp->bus_type = bus_type;
17835 		asc_dvc_varp->drv_ptr = boardp;
17836 		asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
17837 		asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
17838 		asc_dvc_varp->iop_base = iop;
17839 		asc_dvc_varp->isr_callback = asc_isr_callback;
17840 	} else {
17841 		ASC_DBG(1, "advansys_board_found: wide board\n");
17842 		adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
17843 		adv_dvc_varp->drv_ptr = boardp;
17844 		adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
17845 		adv_dvc_varp->isr_callback = adv_isr_callback;
17846 		adv_dvc_varp->async_callback = adv_async_callback;
17847 #ifdef CONFIG_PCI
17848 		if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
17849 			ASC_DBG(1, "advansys_board_found: ASC-3550\n");
17850 			adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
17851 		} else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
17852 			ASC_DBG(1, "advansys_board_found: ASC-38C0800\n");
17853 			adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
17854 		} else {
17855 			ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
17856 			adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
17857 		}
17858 #endif /* CONFIG_PCI */
17859 
17860 		/*
17861 		 * Map the board's registers into virtual memory for
17862 		 * PCI slave access. Only memory accesses are used to
17863 		 * access the board's registers.
17864 		 *
17865 		 * Note: The PCI register base address is not always
17866 		 * page aligned, but the address passed to ioremap()
17867 		 * must be page aligned. It is guaranteed that the
17868 		 * PCI register base address will not cross a page
17869 		 * boundary.
17870 		 */
17871 		if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17872 			iolen = ADV_3550_IOLEN;
17873 		} else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17874 			iolen = ADV_38C0800_IOLEN;
17875 		} else {
17876 			iolen = ADV_38C1600_IOLEN;
17877 		}
17878 #ifdef CONFIG_PCI
17879 		pci_memory_address = pci_resource_start(pdev, 1);
17880 		ASC_DBG1(1,
17881 			 "advansys_board_found: pci_memory_address: 0x%lx\n",
17882 			 (ulong)pci_memory_address);
17883 		if ((boardp->ioremap_addr =
17884 		     ioremap(pci_memory_address & PAGE_MASK, PAGE_SIZE)) == 0) {
17885 			ASC_PRINT3
17886 			    ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
17887 			     boardp->id, pci_memory_address, iolen);
17888 			scsi_unregister(shost);
17889 			asc_board_count--;
17890 			return NULL;
17891 		}
17892 		ASC_DBG1(1,
17893 			 "advansys_board_found: ioremap_addr: 0x%lx\n",
17894 			 (ulong)boardp->ioremap_addr);
17895 		adv_dvc_varp->iop_base = (AdvPortAddr)
17896 		    (boardp->ioremap_addr +
17897 		     (pci_memory_address - (pci_memory_address & PAGE_MASK)));
17898 		ASC_DBG1(1,
17899 			 "advansys_board_found: iop_base: 0x%lx\n",
17900 			 adv_dvc_varp->iop_base);
17901 #endif /* CONFIG_PCI */
17902 
17903 		/*
17904 		 * Even though it isn't used to access wide boards, other
17905 		 * than for the debug line below, save I/O Port address so
17906 		 * that it can be reported.
17907 		 */
17908 		boardp->ioport = iop;
17909 
17910 		ASC_DBG2(1,
17911 			 "advansys_board_found: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
17912 			 (ushort)inp(iop + 1), (ushort)inpw(iop));
17913 	}
17914 
17915 #ifdef CONFIG_PROC_FS
17916 	/*
17917 	 * Allocate buffer for printing information from
17918 	 * /proc/scsi/advansys/[0...].
17919 	 */
17920 	if ((boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) {
17921 		ASC_PRINT3
17922 		    ("advansys_board_found: board %d: kmalloc(%d, %d) returned NULL\n",
17923 		     boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC);
17924 		scsi_unregister(shost);
17925 		asc_board_count--;
17926 		return NULL;
17927 	}
17928 #endif /* CONFIG_PROC_FS */
17929 
17930 	if (ASC_NARROW_BOARD(boardp)) {
17931 		asc_dvc_varp->cfg->dev = dev;
17932 		/*
17933 		 * Set the board bus type and PCI IRQ before
17934 		 * calling AscInitGetConfig().
17935 		 */
17936 		switch (asc_dvc_varp->bus_type) {
17937 #ifdef CONFIG_ISA
17938 		case ASC_IS_ISA:
17939 			shost->unchecked_isa_dma = TRUE;
17940 			share_irq = FALSE;
17941 			break;
17942 		case ASC_IS_VL:
17943 			shost->unchecked_isa_dma = FALSE;
17944 			share_irq = FALSE;
17945 			break;
17946 		case ASC_IS_EISA:
17947 			shost->unchecked_isa_dma = FALSE;
17948 			share_irq = TRUE;
17949 			break;
17950 #endif /* CONFIG_ISA */
17951 #ifdef CONFIG_PCI
17952 		case ASC_IS_PCI:
17953 			shost->irq = asc_dvc_varp->irq_no = pdev->irq;
17954 			asc_dvc_varp->cfg->pci_slot_info =
17955 			    ASC_PCI_MKID(pdev->bus->number,
17956 					 PCI_SLOT(pdev->devfn),
17957 					 PCI_FUNC(pdev->devfn));
17958 			shost->unchecked_isa_dma = FALSE;
17959 			share_irq = TRUE;
17960 			break;
17961 #endif /* CONFIG_PCI */
17962 		default:
17963 			ASC_PRINT2
17964 			    ("advansys_board_found: board %d: unknown adapter type: %d\n",
17965 			     boardp->id, asc_dvc_varp->bus_type);
17966 			shost->unchecked_isa_dma = TRUE;
17967 			share_irq = FALSE;
17968 			break;
17969 		}
17970 	} else {
17971 		adv_dvc_varp->cfg->dev = dev;
17972 		/*
17973 		 * For Wide boards set PCI information before calling
17974 		 * AdvInitGetConfig().
17975 		 */
17976 #ifdef CONFIG_PCI
17977 		shost->irq = adv_dvc_varp->irq_no = pdev->irq;
17978 		adv_dvc_varp->cfg->pci_slot_info =
17979 		    ASC_PCI_MKID(pdev->bus->number,
17980 				 PCI_SLOT(pdev->devfn),
17981 				 PCI_FUNC(pdev->devfn));
17982 		shost->unchecked_isa_dma = FALSE;
17983 		share_irq = TRUE;
17984 #endif /* CONFIG_PCI */
17985 	}
17986 
17987 	/*
17988 	 * Read the board configuration.
17989 	 */
17990 	if (ASC_NARROW_BOARD(boardp)) {
17991 		/*
17992 		 * NOTE: AscInitGetConfig() may change the board's
17993 		 * bus_type value. The bus_type value should no
17994 		 * longer be used. If the bus_type field must be
17995 		 * referenced only use the bit-wise AND operator "&".
17996 		 */
17997 		ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
17998 		switch (ret = AscInitGetConfig(asc_dvc_varp)) {
17999 		case 0:	/* No error */
18000 			break;
18001 		case ASC_WARN_IO_PORT_ROTATE:
18002 			ASC_PRINT1
18003 			    ("AscInitGetConfig: board %d: I/O port address modified\n",
18004 			     boardp->id);
18005 			break;
18006 		case ASC_WARN_AUTO_CONFIG:
18007 			ASC_PRINT1
18008 			    ("AscInitGetConfig: board %d: I/O port increment switch enabled\n",
18009 			     boardp->id);
18010 			break;
18011 		case ASC_WARN_EEPROM_CHKSUM:
18012 			ASC_PRINT1
18013 			    ("AscInitGetConfig: board %d: EEPROM checksum error\n",
18014 			     boardp->id);
18015 			break;
18016 		case ASC_WARN_IRQ_MODIFIED:
18017 			ASC_PRINT1
18018 			    ("AscInitGetConfig: board %d: IRQ modified\n",
18019 			     boardp->id);
18020 			break;
18021 		case ASC_WARN_CMD_QNG_CONFLICT:
18022 			ASC_PRINT1
18023 			    ("AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
18024 			     boardp->id);
18025 			break;
18026 		default:
18027 			ASC_PRINT2
18028 			    ("AscInitGetConfig: board %d: unknown warning: 0x%x\n",
18029 			     boardp->id, ret);
18030 			break;
18031 		}
18032 		if ((err_code = asc_dvc_varp->err_code) != 0) {
18033 			ASC_PRINT3
18034 			    ("AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
18035 			     boardp->id,
18036 			     asc_dvc_varp->init_state, asc_dvc_varp->err_code);
18037 		}
18038 	} else {
18039 		ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
18040 		if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
18041 			ASC_PRINT2
18042 			    ("AdvInitGetConfig: board %d: warning: 0x%x\n",
18043 			     boardp->id, ret);
18044 		}
18045 		if ((err_code = adv_dvc_varp->err_code) != 0) {
18046 			ASC_PRINT2
18047 			    ("AdvInitGetConfig: board %d error: err_code 0x%x\n",
18048 			     boardp->id, adv_dvc_varp->err_code);
18049 		}
18050 	}
18051 
18052 	if (err_code != 0) {
18053 #ifdef CONFIG_PROC_FS
18054 		kfree(boardp->prtbuf);
18055 #endif /* CONFIG_PROC_FS */
18056 		scsi_unregister(shost);
18057 		asc_board_count--;
18058 		return NULL;
18059 	}
18060 
18061 	/*
18062 	 * Save the EEPROM configuration so that it can be displayed
18063 	 * from /proc/scsi/advansys/[0...].
18064 	 */
18065 	if (ASC_NARROW_BOARD(boardp)) {
18066 
18067 		ASCEEP_CONFIG *ep;
18068 
18069 		/*
18070 		 * Set the adapter's target id bit in the 'init_tidmask' field.
18071 		 */
18072 		boardp->init_tidmask |=
18073 		    ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
18074 
18075 		/*
18076 		 * Save EEPROM settings for the board.
18077 		 */
18078 		ep = &boardp->eep_config.asc_eep;
18079 
18080 		ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
18081 		ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
18082 		ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
18083 		ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
18084 		ep->start_motor = asc_dvc_varp->start_motor;
18085 		ep->cntl = asc_dvc_varp->dvc_cntl;
18086 		ep->no_scam = asc_dvc_varp->no_scam;
18087 		ep->max_total_qng = asc_dvc_varp->max_total_qng;
18088 		ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
18089 		/* 'max_tag_qng' is set to the same value for every device. */
18090 		ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
18091 		ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
18092 		ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
18093 		ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
18094 		ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
18095 		ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
18096 		ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
18097 
18098 		/*
18099 		 * Modify board configuration.
18100 		 */
18101 		ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
18102 		switch (ret = AscInitSetConfig(asc_dvc_varp)) {
18103 		case 0:	/* No error. */
18104 			break;
18105 		case ASC_WARN_IO_PORT_ROTATE:
18106 			ASC_PRINT1
18107 			    ("AscInitSetConfig: board %d: I/O port address modified\n",
18108 			     boardp->id);
18109 			break;
18110 		case ASC_WARN_AUTO_CONFIG:
18111 			ASC_PRINT1
18112 			    ("AscInitSetConfig: board %d: I/O port increment switch enabled\n",
18113 			     boardp->id);
18114 			break;
18115 		case ASC_WARN_EEPROM_CHKSUM:
18116 			ASC_PRINT1
18117 			    ("AscInitSetConfig: board %d: EEPROM checksum error\n",
18118 			     boardp->id);
18119 			break;
18120 		case ASC_WARN_IRQ_MODIFIED:
18121 			ASC_PRINT1
18122 			    ("AscInitSetConfig: board %d: IRQ modified\n",
18123 			     boardp->id);
18124 			break;
18125 		case ASC_WARN_CMD_QNG_CONFLICT:
18126 			ASC_PRINT1
18127 			    ("AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
18128 			     boardp->id);
18129 			break;
18130 		default:
18131 			ASC_PRINT2
18132 			    ("AscInitSetConfig: board %d: unknown warning: 0x%x\n",
18133 			     boardp->id, ret);
18134 			break;
18135 		}
18136 		if (asc_dvc_varp->err_code != 0) {
18137 			ASC_PRINT3
18138 			    ("AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
18139 			     boardp->id,
18140 			     asc_dvc_varp->init_state, asc_dvc_varp->err_code);
18141 #ifdef CONFIG_PROC_FS
18142 			kfree(boardp->prtbuf);
18143 #endif /* CONFIG_PROC_FS */
18144 			scsi_unregister(shost);
18145 			asc_board_count--;
18146 			return NULL;
18147 		}
18148 
18149 		/*
18150 		 * Finish initializing the 'Scsi_Host' structure.
18151 		 */
18152 		/* AscInitSetConfig() will set the IRQ for non-PCI boards. */
18153 		if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
18154 			shost->irq = asc_dvc_varp->irq_no;
18155 		}
18156 	} else {
18157 		ADVEEP_3550_CONFIG *ep_3550;
18158 		ADVEEP_38C0800_CONFIG *ep_38C0800;
18159 		ADVEEP_38C1600_CONFIG *ep_38C1600;
18160 
18161 		/*
18162 		 * Save Wide EEP Configuration Information.
18163 		 */
18164 		if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
18165 			ep_3550 = &boardp->eep_config.adv_3550_eep;
18166 
18167 			ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
18168 			ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
18169 			ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
18170 			ep_3550->termination = adv_dvc_varp->cfg->termination;
18171 			ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
18172 			ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
18173 			ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
18174 			ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
18175 			ep_3550->ultra_able = adv_dvc_varp->ultra_able;
18176 			ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
18177 			ep_3550->start_motor = adv_dvc_varp->start_motor;
18178 			ep_3550->scsi_reset_delay =
18179 			    adv_dvc_varp->scsi_reset_wait;
18180 			ep_3550->serial_number_word1 =
18181 			    adv_dvc_varp->cfg->serial1;
18182 			ep_3550->serial_number_word2 =
18183 			    adv_dvc_varp->cfg->serial2;
18184 			ep_3550->serial_number_word3 =
18185 			    adv_dvc_varp->cfg->serial3;
18186 		} else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
18187 			ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
18188 
18189 			ep_38C0800->adapter_scsi_id =
18190 			    adv_dvc_varp->chip_scsi_id;
18191 			ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
18192 			ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
18193 			ep_38C0800->termination_lvd =
18194 			    adv_dvc_varp->cfg->termination;
18195 			ep_38C0800->disc_enable =
18196 			    adv_dvc_varp->cfg->disc_enable;
18197 			ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
18198 			ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
18199 			ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
18200 			ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
18201 			ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
18202 			ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
18203 			ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
18204 			ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
18205 			ep_38C0800->start_motor = adv_dvc_varp->start_motor;
18206 			ep_38C0800->scsi_reset_delay =
18207 			    adv_dvc_varp->scsi_reset_wait;
18208 			ep_38C0800->serial_number_word1 =
18209 			    adv_dvc_varp->cfg->serial1;
18210 			ep_38C0800->serial_number_word2 =
18211 			    adv_dvc_varp->cfg->serial2;
18212 			ep_38C0800->serial_number_word3 =
18213 			    adv_dvc_varp->cfg->serial3;
18214 		} else {
18215 			ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
18216 
18217 			ep_38C1600->adapter_scsi_id =
18218 			    adv_dvc_varp->chip_scsi_id;
18219 			ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
18220 			ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
18221 			ep_38C1600->termination_lvd =
18222 			    adv_dvc_varp->cfg->termination;
18223 			ep_38C1600->disc_enable =
18224 			    adv_dvc_varp->cfg->disc_enable;
18225 			ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
18226 			ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
18227 			ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
18228 			ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
18229 			ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
18230 			ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
18231 			ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
18232 			ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
18233 			ep_38C1600->start_motor = adv_dvc_varp->start_motor;
18234 			ep_38C1600->scsi_reset_delay =
18235 			    adv_dvc_varp->scsi_reset_wait;
18236 			ep_38C1600->serial_number_word1 =
18237 			    adv_dvc_varp->cfg->serial1;
18238 			ep_38C1600->serial_number_word2 =
18239 			    adv_dvc_varp->cfg->serial2;
18240 			ep_38C1600->serial_number_word3 =
18241 			    adv_dvc_varp->cfg->serial3;
18242 		}
18243 
18244 		/*
18245 		 * Set the adapter's target id bit in the 'init_tidmask' field.
18246 		 */
18247 		boardp->init_tidmask |=
18248 		    ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
18249 
18250 		/*
18251 		 * Finish initializing the 'Scsi_Host' structure.
18252 		 */
18253 		shost->irq = adv_dvc_varp->irq_no;
18254 	}
18255 
18256 	/*
18257 	 * Channels are numbered beginning with 0. For AdvanSys one host
18258 	 * structure supports one channel. Multi-channel boards have a
18259 	 * separate host structure for each channel.
18260 	 */
18261 	shost->max_channel = 0;
18262 	if (ASC_NARROW_BOARD(boardp)) {
18263 		shost->max_id = ASC_MAX_TID + 1;
18264 		shost->max_lun = ASC_MAX_LUN + 1;
18265 
18266 		shost->io_port = asc_dvc_varp->iop_base;
18267 		boardp->asc_n_io_port = ASC_IOADR_GAP;
18268 		shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
18269 
18270 		/* Set maximum number of queues the adapter can handle. */
18271 		shost->can_queue = asc_dvc_varp->max_total_qng;
18272 	} else {
18273 		shost->max_id = ADV_MAX_TID + 1;
18274 		shost->max_lun = ADV_MAX_LUN + 1;
18275 
18276 		/*
18277 		 * Save the I/O Port address and length even though
18278 		 * I/O ports are not used to access Wide boards.
18279 		 * Instead the Wide boards are accessed with
18280 		 * PCI Memory Mapped I/O.
18281 		 */
18282 		shost->io_port = iop;
18283 		boardp->asc_n_io_port = iolen;
18284 
18285 		shost->this_id = adv_dvc_varp->chip_scsi_id;
18286 
18287 		/* Set maximum number of queues the adapter can handle. */
18288 		shost->can_queue = adv_dvc_varp->max_host_qng;
18289 	}
18290 
18291 	/*
18292 	 * 'n_io_port' currently is one byte.
18293 	 *
18294 	 * Set a value to 'n_io_port', but never referenced it because
18295 	 * it may be truncated.
18296 	 */
18297 	shost->n_io_port = boardp->asc_n_io_port <= 255 ?
18298 	    boardp->asc_n_io_port : 255;
18299 
18300 	/*
18301 	 * Following v1.3.89, 'cmd_per_lun' is no longer needed
18302 	 * and should be set to zero.
18303 	 *
18304 	 * But because of a bug introduced in v1.3.89 if the driver is
18305 	 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
18306 	 * SCSI function 'allocate_device' will panic. To allow the driver
18307 	 * to work as a module in these kernels set 'cmd_per_lun' to 1.
18308 	 *
18309 	 * Note: This is wrong.  cmd_per_lun should be set to the depth
18310 	 * you want on untagged devices always.
18311 	 #ifdef MODULE
18312 	 */
18313 	shost->cmd_per_lun = 1;
18314 /* #else
18315             shost->cmd_per_lun = 0;
18316 #endif */
18317 
18318 	/*
18319 	 * Set the maximum number of scatter-gather elements the
18320 	 * adapter can handle.
18321 	 */
18322 	if (ASC_NARROW_BOARD(boardp)) {
18323 		/*
18324 		 * Allow two commands with 'sg_tablesize' scatter-gather
18325 		 * elements to be executed simultaneously. This value is
18326 		 * the theoretical hardware limit. It may be decreased
18327 		 * below.
18328 		 */
18329 		shost->sg_tablesize =
18330 		    (((asc_dvc_varp->max_total_qng - 2) / 2) *
18331 		     ASC_SG_LIST_PER_Q) + 1;
18332 	} else {
18333 		shost->sg_tablesize = ADV_MAX_SG_LIST;
18334 	}
18335 
18336 	/*
18337 	 * The value of 'sg_tablesize' can not exceed the SCSI
18338 	 * mid-level driver definition of SG_ALL. SG_ALL also
18339 	 * must not be exceeded, because it is used to define the
18340 	 * size of the scatter-gather table in 'struct asc_sg_head'.
18341 	 */
18342 	if (shost->sg_tablesize > SG_ALL) {
18343 		shost->sg_tablesize = SG_ALL;
18344 	}
18345 
18346 	ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize);
18347 
18348 	/* BIOS start address. */
18349 	if (ASC_NARROW_BOARD(boardp)) {
18350 		shost->base = ((ulong)
18351 			     AscGetChipBiosAddress(asc_dvc_varp->
18352 						   iop_base,
18353 						   asc_dvc_varp->bus_type));
18354 	} else {
18355 		/*
18356 		 * Fill-in BIOS board variables. The Wide BIOS saves
18357 		 * information in LRAM that is used by the driver.
18358 		 */
18359 		AdvReadWordLram(adv_dvc_varp->iop_base,
18360 				BIOS_SIGNATURE, boardp->bios_signature);
18361 		AdvReadWordLram(adv_dvc_varp->iop_base,
18362 				BIOS_VERSION, boardp->bios_version);
18363 		AdvReadWordLram(adv_dvc_varp->iop_base,
18364 				BIOS_CODESEG, boardp->bios_codeseg);
18365 		AdvReadWordLram(adv_dvc_varp->iop_base,
18366 				BIOS_CODELEN, boardp->bios_codelen);
18367 
18368 		ASC_DBG2(1,
18369 			 "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n",
18370 			 boardp->bios_signature, boardp->bios_version);
18371 
18372 		ASC_DBG2(1,
18373 			 "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n",
18374 			 boardp->bios_codeseg, boardp->bios_codelen);
18375 
18376 		/*
18377 		 * If the BIOS saved a valid signature, then fill in
18378 		 * the BIOS code segment base address.
18379 		 */
18380 		if (boardp->bios_signature == 0x55AA) {
18381 			/*
18382 			 * Convert x86 realmode code segment to a linear
18383 			 * address by shifting left 4.
18384 			 */
18385 			shost->base = ((ulong)boardp->bios_codeseg << 4);
18386 		} else {
18387 			shost->base = 0;
18388 		}
18389 	}
18390 
18391 	/*
18392 	 * Register Board Resources - I/O Port, DMA, IRQ
18393 	 */
18394 
18395 	/*
18396 	 * Register I/O port range.
18397 	 *
18398 	 * For Wide boards the I/O ports are not used to access
18399 	 * the board, but request the region anyway.
18400 	 *
18401 	 * 'shost->n_io_port' is not referenced, because it may be truncated.
18402 	 */
18403 	ASC_DBG2(2,
18404 		 "advansys_board_found: request_region port 0x%lx, len 0x%x\n",
18405 		 (ulong)shost->io_port, boardp->asc_n_io_port);
18406 	if (request_region(shost->io_port, boardp->asc_n_io_port,
18407 			   "advansys") == NULL) {
18408 		ASC_PRINT3
18409 		    ("advansys_board_found: board %d: request_region() failed, port 0x%lx, len 0x%x\n",
18410 		     boardp->id, (ulong)shost->io_port, boardp->asc_n_io_port);
18411 #ifdef CONFIG_PROC_FS
18412 		kfree(boardp->prtbuf);
18413 #endif /* CONFIG_PROC_FS */
18414 		scsi_unregister(shost);
18415 		asc_board_count--;
18416 		return NULL;
18417 	}
18418 
18419 	/* Register DMA Channel for Narrow boards. */
18420 	shost->dma_channel = NO_ISA_DMA;	/* Default to no ISA DMA. */
18421 #ifdef CONFIG_ISA
18422 	if (ASC_NARROW_BOARD(boardp)) {
18423 		/* Register DMA channel for ISA bus. */
18424 		if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
18425 			shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
18426 			if ((ret =
18427 			     request_dma(shost->dma_channel, "advansys")) != 0) {
18428 				ASC_PRINT3
18429 				    ("advansys_board_found: board %d: request_dma() %d failed %d\n",
18430 				     boardp->id, shost->dma_channel, ret);
18431 				release_region(shost->io_port,
18432 					       boardp->asc_n_io_port);
18433 #ifdef CONFIG_PROC_FS
18434 				kfree(boardp->prtbuf);
18435 #endif /* CONFIG_PROC_FS */
18436 				scsi_unregister(shost);
18437 				asc_board_count--;
18438 				return NULL;
18439 			}
18440 			AscEnableIsaDma(shost->dma_channel);
18441 		}
18442 	}
18443 #endif /* CONFIG_ISA */
18444 
18445 	/* Register IRQ Number. */
18446 	ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq);
18447 	/*
18448 	 * If request_irq() fails with the IRQF_DISABLED flag set,
18449 	 * then try again without the IRQF_DISABLED flag set. This
18450 	 * allows IRQ sharing to work even with other drivers that
18451 	 * do not set the IRQF_DISABLED flag.
18452 	 *
18453 	 * If IRQF_DISABLED is not set, then interrupts are enabled
18454 	 * before the driver interrupt function is called.
18455 	 */
18456 	if (((ret = request_irq(shost->irq, advansys_interrupt,
18457 				IRQF_DISABLED | (share_irq ==
18458 						 TRUE ?
18459 						 IRQF_SHARED :
18460 						 0), "advansys", boardp)) != 0)
18461 	    &&
18462 	    ((ret =
18463 	      request_irq(shost->irq, advansys_interrupt,
18464 			  (share_irq == TRUE ? IRQF_SHARED : 0),
18465 			  "advansys", boardp)) != 0)) {
18466 		if (ret == -EBUSY) {
18467 			ASC_PRINT2
18468 			    ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
18469 			     boardp->id, shost->irq);
18470 		} else if (ret == -EINVAL) {
18471 			ASC_PRINT2
18472 			    ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
18473 			     boardp->id, shost->irq);
18474 		} else {
18475 			ASC_PRINT3
18476 			    ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
18477 			     boardp->id, shost->irq, ret);
18478 		}
18479 		release_region(shost->io_port, boardp->asc_n_io_port);
18480 		iounmap(boardp->ioremap_addr);
18481 		if (shost->dma_channel != NO_ISA_DMA) {
18482 			free_dma(shost->dma_channel);
18483 		}
18484 #ifdef CONFIG_PROC_FS
18485 		kfree(boardp->prtbuf);
18486 #endif /* CONFIG_PROC_FS */
18487 		scsi_unregister(shost);
18488 		asc_board_count--;
18489 		return NULL;
18490 	}
18491 
18492 	/*
18493 	 * Initialize board RISC chip and enable interrupts.
18494 	 */
18495 	if (ASC_NARROW_BOARD(boardp)) {
18496 		ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
18497 		warn_code = AscInitAsc1000Driver(asc_dvc_varp);
18498 		err_code = asc_dvc_varp->err_code;
18499 
18500 		if (warn_code || err_code) {
18501 			ASC_PRINT4
18502 			    ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
18503 			     boardp->id,
18504 			     asc_dvc_varp->init_state, warn_code, err_code);
18505 		}
18506 	} else {
18507 		ADV_CARR_T *carrp;
18508 		int req_cnt = 0;
18509 		adv_req_t *reqp = NULL;
18510 		int sg_cnt = 0;
18511 
18512 		/*
18513 		 * Allocate buffer carrier structures. The total size
18514 		 * is about 4 KB, so allocate all at once.
18515 		 */
18516 		carrp = (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC);
18517 		ASC_DBG1(1, "advansys_board_found: carrp 0x%lx\n", (ulong)carrp);
18518 
18519 		if (carrp == NULL) {
18520 			goto kmalloc_error;
18521 		}
18522 
18523 		/*
18524 		 * Allocate up to 'max_host_qng' request structures for
18525 		 * the Wide board. The total size is about 16 KB, so
18526 		 * allocate all at once. If the allocation fails decrement
18527 		 * and try again.
18528 		 */
18529 		for (req_cnt = adv_dvc_varp->max_host_qng;
18530 		     req_cnt > 0; req_cnt--) {
18531 
18532 			reqp = (adv_req_t *)
18533 			    kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC);
18534 
18535 			ASC_DBG3(1,
18536 				 "advansys_board_found: reqp 0x%lx, req_cnt %d, bytes %lu\n",
18537 				 (ulong)reqp, req_cnt,
18538 				 (ulong)sizeof(adv_req_t) * req_cnt);
18539 
18540 			if (reqp != NULL) {
18541 				break;
18542 			}
18543 		}
18544 		if (reqp == NULL) {
18545 			goto kmalloc_error;
18546 		}
18547 
18548 		/*
18549 		 * Allocate up to ADV_TOT_SG_BLOCK request structures for
18550 		 * the Wide board. Each structure is about 136 bytes.
18551 		 */
18552 		boardp->adv_sgblkp = NULL;
18553 		for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
18554 
18555 			sgp = (adv_sgblk_t *)
18556 			    kmalloc(sizeof(adv_sgblk_t), GFP_ATOMIC);
18557 
18558 			if (sgp == NULL) {
18559 				break;
18560 			}
18561 
18562 			sgp->next_sgblkp = boardp->adv_sgblkp;
18563 			boardp->adv_sgblkp = sgp;
18564 
18565 		}
18566 		ASC_DBG3(1,
18567 			 "advansys_board_found: sg_cnt %d * %u = %u bytes\n",
18568 			 sg_cnt, sizeof(adv_sgblk_t),
18569 			 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
18570 
18571 		/*
18572 		 * If no request structures or scatter-gather structures could
18573 		 * be allocated, then return an error. Otherwise continue with
18574 		 * initialization.
18575 		 */
18576  kmalloc_error:
18577 		if (carrp == NULL) {
18578 			ASC_PRINT1
18579 			    ("advansys_board_found: board %d error: failed to kmalloc() carrier buffer.\n",
18580 			     boardp->id);
18581 			err_code = ADV_ERROR;
18582 		} else if (reqp == NULL) {
18583 			kfree(carrp);
18584 			ASC_PRINT1
18585 			    ("advansys_board_found: board %d error: failed to kmalloc() adv_req_t buffer.\n",
18586 			     boardp->id);
18587 			err_code = ADV_ERROR;
18588 		} else if (boardp->adv_sgblkp == NULL) {
18589 			kfree(carrp);
18590 			kfree(reqp);
18591 			ASC_PRINT1
18592 			    ("advansys_board_found: board %d error: failed to kmalloc() adv_sgblk_t buffers.\n",
18593 			     boardp->id);
18594 			err_code = ADV_ERROR;
18595 		} else {
18596 
18597 			/* Save carrier buffer pointer. */
18598 			boardp->orig_carrp = carrp;
18599 
18600 			/*
18601 			 * Save original pointer for kfree() in case the
18602 			 * driver is built as a module and can be unloaded.
18603 			 */
18604 			boardp->orig_reqp = reqp;
18605 
18606 			adv_dvc_varp->carrier_buf = carrp;
18607 
18608 			/*
18609 			 * Point 'adv_reqp' to the request structures and
18610 			 * link them together.
18611 			 */
18612 			req_cnt--;
18613 			reqp[req_cnt].next_reqp = NULL;
18614 			for (; req_cnt > 0; req_cnt--) {
18615 				reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
18616 			}
18617 			boardp->adv_reqp = &reqp[0];
18618 
18619 			if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
18620 				ASC_DBG(2,
18621 					"advansys_board_found: AdvInitAsc3550Driver()\n");
18622 				warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
18623 			} else if (adv_dvc_varp->chip_type ==
18624 				   ADV_CHIP_ASC38C0800) {
18625 				ASC_DBG(2,
18626 					"advansys_board_found: AdvInitAsc38C0800Driver()\n");
18627 				warn_code =
18628 				    AdvInitAsc38C0800Driver(adv_dvc_varp);
18629 			} else {
18630 				ASC_DBG(2,
18631 					"advansys_board_found: AdvInitAsc38C1600Driver()\n");
18632 				warn_code =
18633 				    AdvInitAsc38C1600Driver(adv_dvc_varp);
18634 			}
18635 			err_code = adv_dvc_varp->err_code;
18636 
18637 			if (warn_code || err_code) {
18638 				ASC_PRINT3
18639 				    ("advansys_board_found: board %d error: warn 0x%x, error 0x%x\n",
18640 				     boardp->id, warn_code, err_code);
18641 			}
18642 		}
18643 	}
18644 
18645 	if (err_code != 0) {
18646 		release_region(shost->io_port, boardp->asc_n_io_port);
18647 		if (ASC_WIDE_BOARD(boardp)) {
18648 			iounmap(boardp->ioremap_addr);
18649 			kfree(boardp->orig_carrp);
18650 			boardp->orig_carrp = NULL;
18651 			if (boardp->orig_reqp) {
18652 				kfree(boardp->orig_reqp);
18653 				boardp->orig_reqp = boardp->adv_reqp = NULL;
18654 			}
18655 			while ((sgp = boardp->adv_sgblkp) != NULL) {
18656 				boardp->adv_sgblkp = sgp->next_sgblkp;
18657 				kfree(sgp);
18658 			}
18659 		}
18660 		if (shost->dma_channel != NO_ISA_DMA) {
18661 			free_dma(shost->dma_channel);
18662 		}
18663 #ifdef CONFIG_PROC_FS
18664 		kfree(boardp->prtbuf);
18665 #endif /* CONFIG_PROC_FS */
18666 		free_irq(shost->irq, boardp);
18667 		scsi_unregister(shost);
18668 		asc_board_count--;
18669 		return NULL;
18670 	}
18671 	ASC_DBG_PRT_SCSI_HOST(2, shost);
18672 
18673 	return shost;
18674 }
18675 
18676 /*
18677  * advansys_detect()
18678  *
18679  * Detect function for AdvanSys adapters.
18680  *
18681  * Argument is a pointer to the host driver's scsi_hosts entry.
18682  *
18683  * Return number of adapters found.
18684  *
18685  * Note: Because this function is called during system initialization
18686  * it must not call SCSI mid-level functions including scsi_malloc()
18687  * and scsi_free().
18688  */
18689 static int __init advansys_detect(struct scsi_host_template *tpnt)
18690 {
18691 	static int detect_called = ASC_FALSE;
18692 	int iop;
18693 	int bus;
18694 	int ioport = 0;
18695 	struct device *dev = NULL;
18696 #ifdef CONFIG_PCI
18697 	int pci_init_search = 0;
18698 	struct pci_dev *pci_devicep[ASC_NUM_BOARD_SUPPORTED];
18699 	int pci_card_cnt_max = 0;
18700 	int pci_card_cnt = 0;
18701 	struct pci_dev *pdev = NULL;
18702 	int pci_device_id_cnt = 0;
18703 	unsigned int pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
18704 		PCI_DEVICE_ID_ASP_1200A,
18705 		PCI_DEVICE_ID_ASP_ABP940,
18706 		PCI_DEVICE_ID_ASP_ABP940U,
18707 		PCI_DEVICE_ID_ASP_ABP940UW,
18708 		PCI_DEVICE_ID_38C0800_REV1,
18709 		PCI_DEVICE_ID_38C1600_REV1
18710 	};
18711 #endif /* CONFIG_PCI */
18712 
18713 	if (detect_called == ASC_FALSE) {
18714 		detect_called = ASC_TRUE;
18715 	} else {
18716 		printk
18717 		    ("AdvanSys SCSI: advansys_detect() multiple calls ignored\n");
18718 		return 0;
18719 	}
18720 
18721 	ASC_DBG(1, "advansys_detect: begin\n");
18722 
18723 	asc_board_count = 0;
18724 
18725 	/*
18726 	 * If I/O port probing has been modified, then verify and
18727 	 * clean-up the 'asc_ioport' list.
18728 	 */
18729 	if (asc_iopflag == ASC_TRUE) {
18730 		for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
18731 			ASC_DBG2(1, "advansys_detect: asc_ioport[%d] 0x%x\n",
18732 				 ioport, asc_ioport[ioport]);
18733 			if (asc_ioport[ioport] != 0) {
18734 				for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX;
18735 				     iop++) {
18736 					if (_asc_def_iop_base[iop] ==
18737 					    asc_ioport[ioport]) {
18738 						break;
18739 					}
18740 				}
18741 				if (iop == ASC_IOADR_TABLE_MAX_IX) {
18742 					printk
18743 					    ("AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
18744 					     asc_ioport[ioport]);
18745 					asc_ioport[ioport] = 0;
18746 				}
18747 			}
18748 		}
18749 		ioport = 0;
18750 	}
18751 
18752 	for (bus = 0; bus < ASC_NUM_BUS; bus++) {
18753 
18754 		ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
18755 			 bus, asc_bus_name[bus]);
18756 		iop = 0;
18757 
18758 		while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) {
18759 
18760 			ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
18761 				 asc_board_count);
18762 
18763 			switch (asc_bus[bus]) {
18764 			case ASC_IS_ISA:
18765 			case ASC_IS_VL:
18766 #ifdef CONFIG_ISA
18767 				if (asc_iopflag == ASC_FALSE) {
18768 					iop =
18769 					    AscSearchIOPortAddr(iop,
18770 								asc_bus[bus]);
18771 				} else {
18772 					/*
18773 					 * ISA and VL I/O port scanning has either been
18774 					 * eliminated or limited to selected ports on
18775 					 * the LILO command line, /etc/lilo.conf, or
18776 					 * by setting variables when the module was loaded.
18777 					 */
18778 					ASC_DBG(1,
18779 						"advansys_detect: I/O port scanning modified\n");
18780  ioport_try_again:
18781 					iop = 0;
18782 					for (; ioport < ASC_NUM_IOPORT_PROBE;
18783 					     ioport++) {
18784 						if ((iop =
18785 						     asc_ioport[ioport]) != 0) {
18786 							break;
18787 						}
18788 					}
18789 					if (iop) {
18790 						ASC_DBG1(1,
18791 							 "advansys_detect: probing I/O port 0x%x...\n",
18792 							 iop);
18793 						if (!request_region
18794 						    (iop, ASC_IOADR_GAP,
18795 						     "advansys")) {
18796 							printk
18797 							    ("AdvanSys SCSI: specified I/O Port 0x%X is busy\n",
18798 							     iop);
18799 							/* Don't try this I/O port twice. */
18800 							asc_ioport[ioport] = 0;
18801 							goto ioport_try_again;
18802 						} else if (AscFindSignature(iop)
18803 							   == ASC_FALSE) {
18804 							printk
18805 							    ("AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n",
18806 							     iop);
18807 							/* Don't try this I/O port twice. */
18808 							release_region(iop,
18809 								       ASC_IOADR_GAP);
18810 							asc_ioport[ioport] = 0;
18811 							goto ioport_try_again;
18812 						} else {
18813 							/*
18814 							 * If this isn't an ISA board, then it must be
18815 							 * a VL board. If currently looking an ISA
18816 							 * board is being looked for then try for
18817 							 * another ISA board in 'asc_ioport'.
18818 							 */
18819 							if (asc_bus[bus] ==
18820 							    ASC_IS_ISA
18821 							    &&
18822 							    (AscGetChipVersion
18823 							     (iop,
18824 							      ASC_IS_ISA) &
18825 							     ASC_CHIP_VER_ISA_BIT)
18826 							    == 0) {
18827 								/*
18828 								 * Don't clear 'asc_ioport[ioport]'. Try
18829 								 * this board again for VL. Increment
18830 								 * 'ioport' past this board.
18831 								 */
18832 								ioport++;
18833 								release_region
18834 								    (iop,
18835 								     ASC_IOADR_GAP);
18836 								goto ioport_try_again;
18837 							}
18838 						}
18839 						/*
18840 						 * This board appears good, don't try the I/O port
18841 						 * again by clearing its value. Increment 'ioport'
18842 						 * for the next iteration.
18843 						 */
18844 						asc_ioport[ioport++] = 0;
18845 					}
18846 				}
18847 #endif /* CONFIG_ISA */
18848 				break;
18849 
18850 			case ASC_IS_EISA:
18851 #ifdef CONFIG_ISA
18852 				iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
18853 #endif /* CONFIG_ISA */
18854 				break;
18855 
18856 			case ASC_IS_PCI:
18857 #ifdef CONFIG_PCI
18858 				if (pci_init_search == 0) {
18859 					int i, j;
18860 
18861 					pci_init_search = 1;
18862 
18863 					/* Find all PCI cards. */
18864 					while (pci_device_id_cnt <
18865 					       ASC_PCI_DEVICE_ID_CNT) {
18866 						if ((pdev =
18867 						     pci_find_device
18868 						     (PCI_VENDOR_ID_ASP,
18869 						      pci_device_id
18870 						      [pci_device_id_cnt],
18871 						      pdev)) == NULL) {
18872 							pci_device_id_cnt++;
18873 						} else {
18874 							if (pci_enable_device
18875 							    (pdev) == 0) {
18876 								pci_devicep
18877 								    [pci_card_cnt_max++]
18878 								    = pdev;
18879 							}
18880 						}
18881 					}
18882 
18883 					/*
18884 					 * Sort PCI cards in ascending order by PCI Bus, Slot,
18885 					 * and Device Number.
18886 					 */
18887 					for (i = 0; i < pci_card_cnt_max - 1;
18888 					     i++) {
18889 						for (j = i + 1;
18890 						     j < pci_card_cnt_max;
18891 						     j++) {
18892 							if ((pci_devicep[j]->
18893 							     bus->number <
18894 							     pci_devicep[i]->
18895 							     bus->number)
18896 							    ||
18897 							    ((pci_devicep[j]->
18898 							      bus->number ==
18899 							      pci_devicep[i]->
18900 							      bus->number)
18901 							     &&
18902 							     (pci_devicep[j]->
18903 							      devfn <
18904 							      pci_devicep[i]->
18905 							      devfn))) {
18906 								pdev =
18907 								    pci_devicep
18908 								    [i];
18909 								pci_devicep[i] =
18910 								    pci_devicep
18911 								    [j];
18912 								pci_devicep[j] =
18913 								    pdev;
18914 							}
18915 						}
18916 					}
18917 
18918 					pci_card_cnt = 0;
18919 				} else {
18920 					pci_card_cnt++;
18921 				}
18922 
18923 				if (pci_card_cnt == pci_card_cnt_max) {
18924 					iop = 0;
18925 				} else {
18926 					pdev = pci_devicep[pci_card_cnt];
18927 
18928 					ASC_DBG2(2,
18929 						 "advansys_detect: devfn %d, bus number %d\n",
18930 						 pdev->devfn,
18931 						 pdev->bus->number);
18932 					iop = pci_resource_start(pdev, 0);
18933 					ASC_DBG2(1,
18934 						 "advansys_detect: vendorID %X, deviceID %X\n",
18935 						 pdev->vendor,
18936 						 pdev->device);
18937 					ASC_DBG2(2,
18938 						 "advansys_detect: iop %X, irqLine %d\n",
18939 						 iop, pdev->irq);
18940 				}
18941 				if (pdev)
18942 					dev = &pdev->dev;
18943 
18944 #endif /* CONFIG_PCI */
18945 				break;
18946 
18947 			default:
18948 				ASC_PRINT1
18949 				    ("advansys_detect: unknown bus type: %d\n",
18950 				     asc_bus[bus]);
18951 				break;
18952 			}
18953 			ASC_DBG1(1, "advansys_detect: iop 0x%x\n", iop);
18954 
18955 			/*
18956 			 * Adapter not found, try next bus type.
18957 			 */
18958 			if (iop == 0) {
18959 				break;
18960 			}
18961 
18962 			advansys_board_found(iop, dev, asc_bus[bus]);
18963 		}
18964 	}
18965 
18966 	ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n",
18967 		 asc_board_count);
18968 	return asc_board_count;
18969 }
18970 
18971 /*
18972  * advansys_release()
18973  *
18974  * Release resources allocated for a single AdvanSys adapter.
18975  */
18976 static int advansys_release(struct Scsi_Host *shost)
18977 {
18978 	asc_board_t *boardp;
18979 
18980 	ASC_DBG(1, "advansys_release: begin\n");
18981 	boardp = ASC_BOARDP(shost);
18982 	free_irq(shost->irq, boardp);
18983 	if (shost->dma_channel != NO_ISA_DMA) {
18984 		ASC_DBG(1, "advansys_release: free_dma()\n");
18985 		free_dma(shost->dma_channel);
18986 	}
18987 	release_region(shost->io_port, boardp->asc_n_io_port);
18988 	if (ASC_WIDE_BOARD(boardp)) {
18989 		adv_sgblk_t *sgp = NULL;
18990 
18991 		iounmap(boardp->ioremap_addr);
18992 		kfree(boardp->orig_carrp);
18993 		boardp->orig_carrp = NULL;
18994 		if (boardp->orig_reqp) {
18995 			kfree(boardp->orig_reqp);
18996 			boardp->orig_reqp = boardp->adv_reqp = NULL;
18997 		}
18998 		while ((sgp = boardp->adv_sgblkp) != NULL) {
18999 			boardp->adv_sgblkp = sgp->next_sgblkp;
19000 			kfree(sgp);
19001 		}
19002 	}
19003 #ifdef CONFIG_PROC_FS
19004 	ASC_ASSERT(boardp->prtbuf != NULL);
19005 	kfree(boardp->prtbuf);
19006 #endif /* CONFIG_PROC_FS */
19007 	scsi_unregister(shost);
19008 	ASC_DBG(1, "advansys_release: end\n");
19009 	return 0;
19010 }
19011 
19012 #ifdef CONFIG_PCI
19013 /* PCI Devices supported by this driver */
19014 static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
19015 	{PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
19016 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
19017 	{PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
19018 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
19019 	{PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
19020 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
19021 	{PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
19022 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
19023 	{PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
19024 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
19025 	{PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
19026 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
19027 	{}
19028 };
19029 
19030 MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
19031 #endif /* CONFIG_PCI */
19032