1 #define ASC_VERSION "3.3G"    /* AdvanSys Driver Version */
2 
3 /*
4  * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
5  *
6  * Copyright (c) 1995-2000 Advanced System Products, Inc.
7  * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
8  * All Rights Reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that redistributions of source
12  * code retain the above copyright notice and this comment without
13  * modification.
14  *
15  * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
16  * changed its name to ConnectCom Solutions, Inc.
17  *
18  * There is an AdvanSys Linux WWW page at:
19  *  http://www.connectcom.net/downloads/software/os/linux.html
20  *  http://www.advansys.com/linux.html
21  *
22  * The latest released version of the AdvanSys driver is available at:
23  *  ftp://ftp.advansys.com/pub/linux/linux.tgz
24  *  ftp://ftp.connectcom.net/pub/linux/linux.tgz
25  *
26  * Please send questions, comments, bug reports to:
27  *  support@connectcom.net
28  */
29 
30 /*
31 
32   Documentation for the AdvanSys Driver
33 
34   A. Linux Kernels Supported by this Driver
35   B. Adapters Supported by this Driver
36   C. Linux source files modified by AdvanSys Driver
37   D. Source Comments
38   E. Driver Compile Time Options and Debugging
39   F. Driver LILO Option
40   G. Tests to run before releasing new driver
41   H. Release History
42   I. Known Problems/Fix List
43   J. Credits (Chronological Order)
44   K. ConnectCom (AdvanSys) Contact Information
45 
46   A. Linux Kernels Supported by this Driver
47 
48      This driver has been tested in the following Linux kernels: v2.2.18
49      v2.4.0. The driver is supported on v2.2 and v2.4 kernels and on x86,
50      alpha, and PowerPC platforms.
51 
52   B. Adapters Supported by this Driver
53 
54      AdvanSys (Advanced System Products, Inc.) manufactures the following
55      RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow
56      (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI
57      buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit
58      transfer) SCSI Host Adapters for the PCI bus.
59 
60      The CDB counts below indicate the number of SCSI CDB (Command
61      Descriptor Block) requests that can be stored in the RISC chip
62      cache and board LRAM. A CDB is a single SCSI command. The driver
63      detect routine will display the number of CDBs available for each
64      adapter detected. The number of CDBs used by the driver can be
65      lowered in the BIOS by changing the 'Host Queue Size' adapter setting.
66 
67      Laptop Products:
68         ABP-480 - Bus-Master CardBus (16 CDB) (2.4 kernel and greater)
69 
70      Connectivity Products:
71         ABP510/5150 - Bus-Master ISA (240 CDB)
72         ABP5140 - Bus-Master ISA PnP (16 CDB)
73         ABP5142 - Bus-Master ISA PnP with floppy (16 CDB)
74         ABP902/3902 - Bus-Master PCI (16 CDB)
75         ABP3905 - Bus-Master PCI (16 CDB)
76         ABP915 - Bus-Master PCI (16 CDB)
77         ABP920 - Bus-Master PCI (16 CDB)
78         ABP3922 - Bus-Master PCI (16 CDB)
79         ABP3925 - Bus-Master PCI (16 CDB)
80         ABP930 - Bus-Master PCI (16 CDB)
81         ABP930U - Bus-Master PCI Ultra (16 CDB)
82         ABP930UA - Bus-Master PCI Ultra (16 CDB)
83         ABP960 - Bus-Master PCI MAC/PC (16 CDB)
84         ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
85 
86      Single Channel Products:
87         ABP542 - Bus-Master ISA with floppy (240 CDB)
88         ABP742 - Bus-Master EISA (240 CDB)
89         ABP842 - Bus-Master VL (240 CDB)
90         ABP940 - Bus-Master PCI (240 CDB)
91         ABP940U - Bus-Master PCI Ultra (240 CDB)
92         ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB)
93         ABP970 - Bus-Master PCI MAC/PC (240 CDB)
94         ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
95         ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB)
96         ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB)
97         ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB)
98         ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB)
99 
100      Multi-Channel Products:
101         ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
102         ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
103         ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
104         ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel)
105         ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
106         ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
107         ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.)
108         ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB)
109         ABP3950U3W - Bus-Master PCI Dual LVD2/Ultra3-Wide (253 CDB)
110 
111   C. Linux source files modified by AdvanSys Driver
112 
113      This section for historical purposes documents the changes
114      originally made to the Linux kernel source to add the advansys
115      driver. As Linux has changed some of these files have also
116      been modified.
117 
118      1. linux/arch/i386/config.in:
119 
120           bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
121 
122      2. linux/drivers/scsi/hosts.c:
123 
124           #ifdef CONFIG_SCSI_ADVANSYS
125           #include "advansys.h"
126           #endif
127 
128         and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
129 
130           #ifdef CONFIG_SCSI_ADVANSYS
131           ADVANSYS,
132           #endif
133 
134      3. linux/drivers/scsi/Makefile:
135 
136           ifdef CONFIG_SCSI_ADVANSYS
137           SCSI_SRCS := $(SCSI_SRCS) advansys.c
138           SCSI_OBJS := $(SCSI_OBJS) advansys.o
139           else
140           SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
141           endif
142 
143      4. linux/init/main.c:
144 
145           extern void advansys_setup(char *str, int *ints);
146 
147         and add the following lines to the bootsetups[] array.
148 
149           #ifdef CONFIG_SCSI_ADVANSYS
150              { "advansys=", advansys_setup },
151           #endif
152 
153   D. Source Comments
154 
155      1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
156 
157      2. This driver should be maintained in multiple files. But to make
158         it easier to include with Linux and to follow Linux conventions,
159         the whole driver is maintained in the source files advansys.h and
160         advansys.c. In this file logical sections of the driver begin with
161         a comment that contains '---'. The following are the logical sections
162         of the driver below.
163 
164            --- Linux Version
165            --- Linux Include File
166            --- Driver Options
167            --- Debugging Header
168            --- Asc Library Constants and Macros
169            --- Adv Library Constants and Macros
170            --- Driver Constants and Macros
171            --- Driver Structures
172            --- Driver Data
173            --- Driver Function Prototypes
174            --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
175            --- Loadable Driver Support
176            --- Miscellaneous Driver Functions
177            --- Functions Required by the Asc Library
178            --- Functions Required by the Adv Library
179            --- Tracing and Debugging Functions
180            --- Asc Library Functions
181            --- Adv Library Functions
182 
183      3. The string 'XXX' is used to flag code that needs to be re-written
184         or that contains a problem that needs to be addressed.
185 
186      4. I have stripped comments from and reformatted the source for the
187         Asc Library and Adv Library to reduce the size of this file. This
188         source can be found under the following headings. The Asc Library
189         is used to support Narrow Boards. The Adv Library is used to
190         support Wide Boards.
191 
192            --- Asc Library Constants and Macros
193            --- Adv Library Constants and Macros
194            --- Asc Library Functions
195            --- Adv Library Functions
196 
197   E. Driver Compile Time Options and Debugging
198 
199      In this source file the following constants can be defined. They are
200      defined in the source below. Both of these options are enabled by
201      default.
202 
203      1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled)
204 
205         Enabling this option adds assertion logic statements to the
206         driver. If an assertion fails a message will be displayed to
207         the console, but the system will continue to operate. Any
208         assertions encountered should be reported to the person
209         responsible for the driver. Assertion statements may proactively
210         detect problems with the driver and facilitate fixing these
211         problems. Enabling assertions will add a small overhead to the
212         execution of the driver.
213 
214      2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled)
215 
216         Enabling this option adds tracing functions to the driver and
217         the ability to set a driver tracing level at boot time. This
218         option will also export symbols not required outside the driver to
219         the kernel name space. This option is very useful for debugging
220         the driver, but it will add to the size of the driver execution
221         image and add overhead to the execution of the driver.
222 
223         The amount of debugging output can be controlled with the global
224         variable 'asc_dbglvl'. The higher the number the more output. By
225         default the debug level is 0.
226 
227         If the driver is loaded at boot time and the LILO Driver Option
228         is included in the system, the debug level can be changed by
229         specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
230         first three hex digits of the pseudo I/O Port must be set to
231         'deb' and the fourth hex digit specifies the debug level: 0 - F.
232         The following command line will look for an adapter at 0x330
233         and set the debug level to 2.
234 
235            linux advansys=0x330,0,0,0,0xdeb2
236 
237         If the driver is built as a loadable module this variable can be
238         defined when the driver is loaded. The following insmod command
239         will set the debug level to one.
240 
241            insmod advansys.o asc_dbglvl=1
242 
243         Debugging Message Levels:
244            0: Errors Only
245            1: High-Level Tracing
246            2-N: Verbose Tracing
247 
248         To enable debug output to console, please make sure that:
249 
250         a. System and kernel logging is enabled (syslogd, klogd running).
251         b. Kernel messages are routed to console output. Check
252            /etc/syslog.conf for an entry similar to this:
253 
254                 kern.*                  /dev/console
255 
256         c. klogd is started with the appropriate -c parameter
257            (e.g. klogd -c 8)
258 
259         This will cause printk() messages to be be displayed on the
260         current console. Refer to the klogd(8) and syslogd(8) man pages
261         for details.
262 
263         Alternatively you can enable printk() to console with this
264         program. However, this is not the 'official' way to do this.
265         Debug output is logged in /var/log/messages.
266 
267           main()
268           {
269                   syscall(103, 7, 0, 0);
270           }
271 
272         Increasing LOG_BUF_LEN in kernel/printk.c to something like
273         40960 allows more debug messages to be buffered in the kernel
274         and written to the console or log file.
275 
276      3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0)
277 
278         Enabling this option adds statistics collection and display
279         through /proc to the driver. The information is useful for
280         monitoring driver and device performance. It will add to the
281         size of the driver execution image and add minor overhead to
282         the execution of the driver.
283 
284         Statistics are maintained on a per adapter basis. Driver entry
285         point call counts and transfer size counts are maintained.
286         Statistics are only available for kernels greater than or equal
287         to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured.
288 
289         AdvanSys SCSI adapter files have the following path name format:
290 
291            /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
292 
293         This information can be displayed with cat. For example:
294 
295            cat /proc/scsi/advansys/0
296 
297         When ADVANSYS_STATS is not defined the AdvanSys /proc files only
298         contain adapter and device configuration information.
299 
300   F. Driver LILO Option
301 
302      If init/main.c is modified as described in the 'Directions for Adding
303      the AdvanSys Driver to Linux' section (B.4.) above, the driver will
304      recognize the 'advansys' LILO command line and /etc/lilo.conf option.
305      This option can be used to either disable I/O port scanning or to limit
306      scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
307      PCI boards will still be searched for and detected. This option only
308      affects searching for ISA and VL boards.
309 
310      Examples:
311        1. Eliminate I/O port scanning:
312             boot: linux advansys=
313               or
314             boot: linux advansys=0x0
315        2. Limit I/O port scanning to one I/O port:
316             boot: linux advansys=0x110
317        3. Limit I/O port scanning to four I/O ports:
318             boot: linux advansys=0x110,0x210,0x230,0x330
319 
320      For a loadable module the same effect can be achieved by setting
321      the 'asc_iopflag' variable and 'asc_ioport' array when loading
322      the driver, e.g.
323 
324            insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
325 
326      If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1)
327      I/O Port may be added to specify the driver debug level. Refer to
328      the 'Driver Compile Time Options and Debugging' section above for
329      more information.
330 
331   G. Tests to run before releasing new driver
332 
333      1. In the supported kernels verify there are no warning or compile
334         errors when the kernel is built as both a driver and as a module
335         and with the following options:
336 
337         ADVANSYS_DEBUG - enabled and disabled
338         CONFIG_SMP - enabled and disabled
339         CONFIG_PROC_FS - enabled and disabled
340 
341      2. Run tests on an x86, alpha, and PowerPC with at least one narrow
342         card and one wide card attached to a hard disk and CD-ROM drive:
343         fdisk, mkfs, fsck, bonnie, copy/compare test from the
344         CD-ROM to the hard drive.
345 
346   H. Release History
347 
348      BETA-1.0 (12/23/95):
349          First Release
350 
351      BETA-1.1 (12/28/95):
352          1. Prevent advansys_detect() from being called twice.
353          2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
354 
355      1.2 (1/12/96):
356          1. Prevent re-entrancy in the interrupt handler which
357             resulted in the driver hanging Linux.
358          2. Fix problem that prevented ABP-940 cards from being
359             recognized on some PCI motherboards.
360          3. Add support for the ABP-5140 PnP ISA card.
361          4. Fix check condition return status.
362          5. Add conditionally compiled code for Linux v1.3.X.
363 
364      1.3 (2/23/96):
365          1. Fix problem in advansys_biosparam() that resulted in the
366             wrong drive geometry being returned for drives > 1GB with
367             extended translation enabled.
368          2. Add additional tracing during device initialization.
369          3. Change code that only applies to ISA PnP adapter.
370          4. Eliminate 'make dep' warning.
371          5. Try to fix problem with handling resets by increasing their
372             timeout value.
373 
374      1.4 (5/8/96):
375          1. Change definitions to eliminate conflicts with other subsystems.
376          2. Add versioning code for the shared interrupt changes.
377          3. Eliminate problem in asc_rmqueue() with iterating after removing
378             a request.
379          4. Remove reset request loop problem from the "Known Problems or
380             Issues" section. This problem was isolated and fixed in the
381             mid-level SCSI driver.
382 
383      1.5 (8/8/96):
384          1. Add support for ABP-940U (PCI Ultra) adapter.
385          2. Add support for IRQ sharing by setting the SA_SHIRQ flag for
386             request_irq and supplying a dev_id pointer to both request_irq()
387             and free_irq().
388          3. In AscSearchIOPortAddr11() restore a call to check_region() which
389             should be used before I/O port probing.
390          4. Fix bug in asc_prt_hex() which resulted in the displaying
391             the wrong data.
392          5. Incorporate miscellaneous Asc Library bug fixes and new microcode.
393          6. Change driver versioning to be specific to each Linux sub-level.
394          7. Change statistics gathering to be per adapter instead of global
395             to the driver.
396          8. Add more information and statistics to the adapter /proc file:
397             /proc/scsi/advansys[0...].
398          9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list.
399             This problem has been addressed with the SCSI mid-level changes
400             made in v1.3.89. The advansys_select_queue_depths() function
401             was added for the v1.3.89 changes.
402 
403      1.6 (9/10/96):
404          1. Incorporate miscellaneous Asc Library bug fixes and new microcode.
405 
406      1.7 (9/25/96):
407          1. Enable clustering and optimize the setting of the maximum number
408             of scatter gather elements for any particular board. Clustering
409             increases CPU utilization, but results in a relatively larger
410             increase in I/O throughput.
411          2. Improve the performance of the request queuing functions by
412             adding a last pointer to the queue structure.
413          3. Correct problems with reset and abort request handling that
414             could have hung or crashed Linux.
415          4. Add more information to the adapter /proc file:
416             /proc/scsi/advansys[0...].
417          5. Remove the request timeout issue form the driver issues list.
418          6. Miscellaneous documentation additions and changes.
419 
420      1.8 (10/4/96):
421          1. Make changes to handle the new v2.1.0 kernel memory mapping
422             in which a kernel virtual address may not be equivalent to its
423             bus or DMA memory address.
424          2. Change abort and reset request handling to make it yet even
425             more robust.
426          3. Try to mitigate request starvation by sending ordered requests
427             to heavily loaded, tag queuing enabled devices.
428          4. Maintain statistics on request response time.
429          5. Add request response time statistics and other information to
430             the adapter /proc file: /proc/scsi/advansys[0...].
431 
432      1.9 (10/21/96):
433          1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to
434             make use of mid-level SCSI driver device queue depth flow
435             control mechanism. This will eliminate aborts caused by a
436             device being unable to keep up with requests and eliminate
437             repeat busy or QUEUE FULL status returned by a device.
438          2. Incorporate miscellaneous Asc Library bug fixes.
439          3. To allow the driver to work in kernels with broken module
440             support set 'cmd_per_lun' if the driver is compiled as a
441             module. This change affects kernels v1.3.89 to present.
442          4. Remove PCI BIOS address from the driver banner. The PCI BIOS
443             is relocated by the motherboard BIOS and its new address can
444             not be determined by the driver.
445          5. Add mid-level SCSI queue depth information to the adapter
446             /proc file: /proc/scsi/advansys[0...].
447 
448      2.0 (11/14/96):
449          1. Change allocation of global structures used for device
450             initialization to guarantee they are in DMA-able memory.
451             Previously when the driver was loaded as a module these
452             structures might not have been in DMA-able memory, causing
453             device initialization to fail.
454 
455      2.1 (12/30/96):
456          1. In advansys_reset(), if the request is a synchronous reset
457             request, even if the request serial number has changed, then
458             complete the request.
459          2. Add Asc Library bug fixes including new microcode.
460          3. Clear inquiry buffer before using it.
461          4. Correct ifdef typo.
462 
463      2.2 (1/15/97):
464          1. Add Asc Library bug fixes including new microcode.
465          2. Add synchronous data transfer rate information to the
466             adapter /proc file: /proc/scsi/advansys[0...].
467          3. Change ADVANSYS_DEBUG to be disabled by default. This
468             will reduce the size of the driver image, eliminate execution
469             overhead, and remove unneeded symbols from the kernel symbol
470             space that were previously added by the driver.
471          4. Add new compile-time option ADVANSYS_ASSERT for assertion
472             code that used to be defined within ADVANSYS_DEBUG. This
473             option is enabled by default.
474 
475      2.8 (5/26/97):
476          1. Change version number to 2.8 to synchronize the Linux driver
477             version numbering with other AdvanSys drivers.
478          2. Reformat source files without tabs to present the same view
479             of the file to everyone regardless of the editor tab setting
480             being used.
481          3. Add Asc Library bug fixes.
482 
483      3.1A (1/8/98):
484          1. Change version number to 3.1 to indicate that support for
485             Ultra-Wide adapters (ABP-940UW) is included in this release.
486          2. Add Asc Library (Narrow Board) bug fixes.
487          3. Report an underrun condition with the host status byte set
488             to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which
489             causes the underrun condition to be ignored. When Linux defines
490             its own DID_UNDERRUN the constant defined in this file can be
491             removed.
492          4. Add patch to AscWaitTixISRDone().
493          5. Add support for up to 16 different AdvanSys host adapter SCSI
494             channels in one system. This allows four cards with four channels
495             to be used in one system.
496 
497      3.1B (1/9/98):
498          1. Handle that PCI register base addresses are not always page
499             aligned even though ioremap() requires that the address argument
500             be page aligned.
501 
502      3.1C (1/10/98):
503          1. Update latest BIOS version checked for from the /proc file.
504          2. Don't set microcode SDTR variable at initialization. Instead
505             wait until device capabilities have been detected from an Inquiry
506             command.
507 
508      3.1D (1/21/98):
509          1. Improve performance when the driver is compiled as module by
510             allowing up to 64 scatter-gather elements instead of 8.
511 
512      3.1E (5/1/98):
513          1. Set time delay in AscWaitTixISRDone() to 1000 ms.
514          2. Include SMP locking changes.
515          3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS
516             access functions.
517          4. Update board serial number printing.
518          5. Try allocating an IRQ both with and without the SA_INTERRUPT
519             flag set to allow IRQ sharing with drivers that do not set
520             the SA_INTERRUPT flag. Also display a more descriptive error
521             message if request_irq() fails.
522          6. Update to latest Asc and Adv Libraries.
523 
524      3.2A (7/22/99):
525          1. Update Adv Library to 4.16 which includes support for
526             the ASC38C0800 (Ultra2/LVD) IC.
527 
528      3.2B (8/23/99):
529          1. Correct PCI compile time option for v2.1.93 and greater
530             kernels, advansys_info() string, and debug compile time
531             option.
532          2. Correct DvcSleepMilliSecond() for v2.1.0 and greater
533             kernels. This caused an LVD detection/BIST problem problem
534             among other things.
535          3. Sort PCI cards by PCI Bus, Slot, Function ascending order
536             to be consistent with the BIOS.
537          4. Update to Asc Library S121 and Adv Library 5.2.
538 
539      3.2C (8/24/99):
540          1. Correct PCI card detection bug introduced in 3.2B that
541             prevented PCI cards from being detected in kernels older
542             than v2.1.93.
543 
544      3.2D (8/26/99):
545          1. Correct /proc device synchronous speed information display.
546             Also when re-negotiation is pending for a target device
547             note this condition with an * and footnote.
548          2. Correct initialization problem with Ultra-Wide cards that
549             have a pre-3.2 BIOS. A microcode variable changed locations
550             in 3.2 and greater BIOSes which caused WDTR to be attempted
551             erroneously with drives that don't support WDTR.
552 
553      3.2E (8/30/99):
554          1. Fix compile error caused by v2.3.13 PCI structure change.
555          2. Remove field from ASCEEP_CONFIG that resulted in an EEPROM
556             checksum error for ISA cards.
557          3. Remove ASC_QUEUE_FLOW_CONTROL conditional code. The mid-level
558             SCSI changes that it depended on were never included in Linux.
559 
560      3.2F (9/3/99):
561          1. Handle new initial function code added in v2.3.16 for all
562             driver versions.
563 
564      3.2G (9/8/99):
565          1. Fix PCI board detection in v2.3.13 and greater kernels.
566          2. Fix comiple errors in v2.3.X with debugging enabled.
567 
568      3.2H (9/13/99):
569          1. Add 64-bit address, long support for Alpha and UltraSPARC.
570             The driver has been verified to work on an Alpha system.
571          2. Add partial byte order handling support for Power PC and
572             other big-endian platforms. This support has not yet been
573             completed or verified.
574          3. For wide boards replace block zeroing of request and
575             scatter-gather structures with individual field initialization
576             to improve performance.
577          4. Correct and clarify ROM BIOS version detection.
578 
579      3.2I (10/8/99):
580          1. Update to Adv Library 5.4.
581          2. Add v2.3.19 underrun reporting to asc_isr_callback() and
582             adv_isr_callback().  Remove DID_UNDERRUN constant and other
583             no longer needed code that previously documented the lack
584             of underrun handling.
585 
586      3.2J (10/14/99):
587          1. Eliminate compile errors for v2.0 and earlier kernels.
588 
589      3.2K (11/15/99):
590          1. Correct debug compile error in asc_prt_adv_scsi_req_q().
591          2. Update Adv Library to 5.5.
592          3. Add ifdef handling for /proc changes added in v2.3.28.
593          4. Increase Wide board scatter-gather list maximum length to
594             255 when the driver is compiled into the kernel.
595 
596      3.2L (11/18/99):
597          1. Fix bug in adv_get_sglist() that caused an assertion failure
598             at line 7475. The reqp->sgblkp pointer must be initialized
599             to NULL in adv_get_sglist().
600 
601      3.2M (11/29/99):
602          1. Really fix bug in adv_get_sglist().
603          2. Incorporate v2.3.29 changes into driver.
604 
605      3.2N (4/1/00):
606          1. Add CONFIG_ISA ifdef code.
607          2. Include advansys_interrupts_enabled name change patch.
608          3. For >= v2.3.28 use new SCSI error handling with new function
609             advansys_eh_bus_reset(). Don't include an abort function
610             because of base library limitations.
611          4. For >= v2.3.28 use per board lock instead of io_request_lock.
612          5. For >= v2.3.28 eliminate advansys_command() and
613             advansys_command_done().
614          6. Add some changes for PowerPC (Big Endian) support, but it isn't
615             working yet.
616          7. Fix "nonexistent resource free" problem that occurred on a module
617             unload for boards with an I/O space >= 255. The 'n_io_port' field
618             is only one byte and can not be used to hold an ioport length more
619             than 255.
620 
621      3.3A (4/4/00):
622          1. Update to Adv Library 5.8.
623          2. For wide cards add support for CDBs up to 16 bytes.
624          3. Eliminate warnings when CONFIG_PROC_FS is not defined.
625 
626      3.3B (5/1/00):
627          1. Support for PowerPC (Big Endian) wide cards. Narrow cards
628             still need work.
629          2. Change bitfields to shift and mask access for endian
630             portability.
631 
632      3.3C (10/13/00):
633          1. Update for latest 2.4 kernel.
634          2. Test ABP-480 CardBus support in 2.4 kernel - works!
635          3. Update to Asc Library S123.
636          4. Update to Adv Library 5.12.
637 
638      3.3D (11/22/00):
639          1. Update for latest 2.4 kernel.
640          2. Create patches for 2.2 and 2.4 kernels.
641 
642      3.3E (1/9/01):
643          1. Now that 2.4 is released remove ifdef code for kernel versions
644             less than 2.2. The driver is now only supported in kernels 2.2,
645             2.4, and greater.
646          2. Add code to release and acquire the io_request_lock in
647             the driver entrypoint functions: advansys_detect and
648             advansys_queuecommand. In kernel 2.4 the SCSI mid-level driver
649             still holds the io_request_lock on entry to SCSI low-level drivers.
650             This was supposed to be removed before 2.4 was released but never
651             happened. When the mid-level SCSI driver is changed all references
652             to the io_request_lock should be removed from the driver.
653          3. Simplify error handling by removing advansys_abort(),
654             AscAbortSRB(), AscResetDevice(). SCSI bus reset requests are
655             now handled by resetting the SCSI bus and fully re-initializing
656             the chip. This simple method of error recovery has proven to work
657             most reliably after attempts at different methods. Also now only
658             support the "new" error handling method and remove the obsolete
659             error handling interface.
660          4. Fix debug build errors.
661 
662      3.3F (1/24/01):
663          1. Merge with ConnectCom version from Andy Kellner which
664             updates Adv Library to 5.14.
665          2. Make PowerPC (Big Endian) work for narrow cards and
666             fix problems writing EEPROM for wide cards.
667          3. Remove interrupts_enabled assertion function.
668 
669      3.3G (2/16/01):
670          1. Return an error from narrow boards if passed a 16 byte
671             CDB. The wide board can already handle 16 byte CDBs.
672 
673   I. Known Problems/Fix List (XXX)
674 
675      1. Need to add memory mapping workaround. Test the memory mapping.
676         If it doesn't work revert to I/O port access. Can a test be done
677         safely?
678      2. Handle an interrupt not working. Keep an interrupt counter in
679         the interrupt handler. In the timeout function if the interrupt
680         has not occurred then print a message and run in polled mode.
681      3. Allow bus type scanning order to be changed.
682      4. Need to add support for target mode commands, cf. CAM XPT.
683 
684   J. Credits (Chronological Order)
685 
686      Bob Frey <bfrey@turbolinux.com.cn> wrote the AdvanSys SCSI driver
687      and maintained it up to 3.3F. He continues to answer questions
688      and help maintain the driver.
689 
690      Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and
691      basis for the Linux v1.3.X changes which were included in the
692      1.2 release.
693 
694      Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug
695      in advansys_biosparam() which was fixed in the 1.3 release.
696 
697      Erik Ratcliffe <erik@caldera.com> has done testing of the
698      AdvanSys driver in the Caldera releases.
699 
700      Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to
701      AscWaitTixISRDone() which he found necessary to make the
702      driver work with a SCSI-1 disk.
703 
704      Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide
705      support in the 3.1A driver.
706 
707      Doug Gilbert <dgilbert@interlog.com> has made changes and
708      suggestions to improve the driver and done a lot of testing.
709 
710      Ken Mort <ken@mort.net> reported a DEBUG compile bug fixed
711      in 3.2K.
712 
713      Tom Rini <trini@kernel.crashing.org> provided the CONFIG_ISA
714      patch and helped with PowerPC wide and narrow board support.
715 
716      Philip Blundell <philb@gnu.org> provided an
717      advansys_interrupts_enabled patch.
718 
719      Dave Jones <dave@denial.force9.co.uk> reported the compiler
720      warnings generated when CONFIG_PROC_FS was not defined in
721      the 3.2M driver.
722 
723      Jerry Quinn <jlquinn@us.ibm.com> fixed PowerPC support (endian
724      problems) for wide cards.
725 
726      Bryan Henderson <bryanh@giraffe-data.com> helped debug narrow
727      card error handling.
728 
729      Manuel Veloso <veloso@pobox.com> worked hard on PowerPC narrow
730      board support and fixed a bug in AscGetEEPConfig().
731 
732      Arnaldo Carvalho de Melo <acme@conectiva.com.br> made
733      save_flags/restore_flags changes.
734 
735      Andy Kellner <AKellner@connectcom.net> continues the Advansys SCSI
736      driver development for ConnectCom (Version > 3.3F).
737 
738   K. ConnectCom (AdvanSys) Contact Information
739 
740      Mail:                   ConnectCom Solutions, Inc.
741                              1150 Ringwood Court
742                              San Jose, CA 95131
743      Operator/Sales:         1-408-383-9400
744      FAX:                    1-408-383-9612
745      Tech Support:           1-408-467-2930
746      Tech Support E-Mail:    linux@connectcom.net
747      FTP Site:               ftp.connectcom.net (login: anonymous)
748      Web Site:               http://www.connectcom.net
749 
750 */
751 
752 
753 /*
754  * --- Linux Version
755  */
756 
757 #ifndef LINUX_VERSION_CODE
758 #include <linux/version.h>
759 #endif /* LINUX_VERSION_CODE */
760 
761 /* Convert Linux Version, Patch-level, Sub-level to LINUX_VERSION_CODE. */
762 #define ASC_LINUX_VERSION(V, P, S)    (((V) * 65536) + ((P) * 256) + (S))
763 #define ASC_LINUX_KERNEL22 (LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,4,0))
764 #define ASC_LINUX_KERNEL24 (LINUX_VERSION_CODE >= ASC_LINUX_VERSION(2,4,0))
765 
766 /* Driver supported only in version 2.2 and version >= 2.4. */
767 #if LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,2,0) || \
768     (LINUX_VERSION_CODE > ASC_LINUX_VERSION(2,3,0) && \
769      LINUX_VERSION_CODE < ASC_LINUX_VERSION(2,4,0))
770 #error "AdvanSys driver supported only in 2.2 and 2.4 or greater kernels."
771 #endif
772 
773 /*
774  * --- Linux Include Files
775  */
776 
777 #include <linux/config.h>
778 #include <linux/module.h>
779 
780 #if defined(CONFIG_X86) && !defined(CONFIG_ISA)
781 #define CONFIG_ISA
782 #endif /* CONFIG_X86 && !CONFIG_ISA */
783 
784 #include <linux/string.h>
785 #include <linux/sched.h>
786 #include <linux/kernel.h>
787 #include <linux/types.h>
788 #include <linux/ioport.h>
789 #include <linux/delay.h>
790 #include <linux/slab.h>
791 #include <linux/mm.h>
792 #include <linux/proc_fs.h>
793 #include <linux/init.h>
794 #include <asm/io.h>
795 #include <asm/system.h>
796 #include <asm/dma.h>
797 #include <linux/blk.h>
798 #include <linux/stat.h>
799 #if ASC_LINUX_KERNEL24
800 #include <linux/spinlock.h>
801 #elif ASC_LINUX_KERNEL22
802 #include <asm/spinlock.h>
803 #endif
804 #include "scsi.h"
805 #include "hosts.h"
806 #include "sd.h"
807 #include "advansys.h"
808 #ifdef CONFIG_PCI
809 #include <linux/pci.h>
810 #endif /* CONFIG_PCI */
811 
812 
813 /*
814  * --- Driver Options
815  */
816 
817 /* Enable driver assertions. */
818 #define ADVANSYS_ASSERT
819 
820 /* Enable driver /proc statistics. */
821 #define ADVANSYS_STATS
822 
823 /* Enable driver tracing. */
824 /* #define ADVANSYS_DEBUG */
825 
826 
827 /*
828  * --- Debugging Header
829  */
830 
831 #ifdef ADVANSYS_DEBUG
832 #define STATIC
833 #else /* ADVANSYS_DEBUG */
834 #define STATIC static
835 #endif /* ADVANSYS_DEBUG */
836 
837 
838 /*
839  * --- Asc Library Constants and Macros
840  */
841 
842 #define ASC_LIB_VERSION_MAJOR  1
843 #define ASC_LIB_VERSION_MINOR  24
844 #define ASC_LIB_SERIAL_NUMBER  123
845 
846 /*
847  * Portable Data Types
848  *
849  * Any instance where a 32-bit long or pointer type is assumed
850  * for precision or HW defined structures, the following define
851  * types must be used. In Linux the char, short, and int types
852  * are all consistent at 8, 16, and 32 bits respectively. Pointers
853  * and long types are 64 bits on Alpha and UltraSPARC.
854  */
855 #define ASC_PADDR __u32         /* Physical/Bus address data type. */
856 #define ASC_VADDR __u32         /* Virtual address data type. */
857 #define ASC_DCNT  __u32         /* Unsigned Data count type. */
858 #define ASC_SDCNT __s32         /* Signed Data count type. */
859 
860 /*
861  * These macros are used to convert a virtual address to a
862  * 32-bit value. This currently can be used on Linux Alpha
863  * which uses 64-bit virtual address but a 32-bit bus address.
864  * This is likely to break in the future, but doing this now
865  * will give us time to change the HW and FW to handle 64-bit
866  * addresses.
867  */
868 #define ASC_VADDR_TO_U32   virt_to_bus
869 #define ASC_U32_TO_VADDR   bus_to_virt
870 
871 typedef unsigned char uchar;
872 
873 #ifndef NULL
874 #define NULL     (0)
875 #endif
876 #ifndef TRUE
877 #define TRUE     (1)
878 #endif
879 #ifndef FALSE
880 #define FALSE    (0)
881 #endif
882 
883 #define EOF      (-1)
884 #define ERR      (-1)
885 #define UW_ERR   (uint)(0xFFFF)
886 #define isodd_word(val)   ((((uint)val) & (uint)0x0001) != 0)
887 #define AscPCIConfigVendorIDRegister      0x0000
888 #define AscPCIConfigDeviceIDRegister      0x0002
889 #define AscPCIConfigCommandRegister       0x0004
890 #define AscPCIConfigStatusRegister        0x0006
891 #define AscPCIConfigRevisionIDRegister    0x0008
892 #define AscPCIConfigCacheSize             0x000C
893 #define AscPCIConfigLatencyTimer          0x000D
894 #define AscPCIIOBaseRegister              0x0010
895 #define AscPCICmdRegBits_IOMemBusMaster   0x0007
896 #define ASC_PCI_ID2BUS(id)    ((id) & 0xFF)
897 #define ASC_PCI_ID2DEV(id)    (((id) >> 11) & 0x1F)
898 #define ASC_PCI_ID2FUNC(id)   (((id) >> 8) & 0x7)
899 #define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
900 #define ASC_PCI_VENDORID                  0x10CD
901 #define ASC_PCI_DEVICEID_1200A            0x1100
902 #define ASC_PCI_DEVICEID_1200B            0x1200
903 #define ASC_PCI_DEVICEID_ULTRA            0x1300
904 #define ASC_PCI_REVISION_3150             0x02
905 #define ASC_PCI_REVISION_3050             0x03
906 
907 #define  ASC_DVCLIB_CALL_DONE     (1)
908 #define  ASC_DVCLIB_CALL_FAILED   (0)
909 #define  ASC_DVCLIB_CALL_ERROR    (-1)
910 
911 /*
912  * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
913  * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
914  * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
915  * SRB structure.
916  */
917 #define CC_VERY_LONG_SG_LIST 0
918 #define ASC_SRB2SCSIQ(srb_ptr)  (srb_ptr)
919 
920 #define PortAddr                 unsigned short    /* port address size  */
921 #define inp(port)                inb(port)
922 #define outp(port, byte)         outb((byte), (port))
923 
924 #define inpw(port)               inw(port)
925 #define outpw(port, word)        outw((word), (port))
926 
927 #define ASC_MAX_SG_QUEUE    7
928 #define ASC_MAX_SG_LIST     255
929 
930 #define ASC_CS_TYPE  unsigned short
931 
932 #define ASC_IS_ISA          (0x0001)
933 #define ASC_IS_ISAPNP       (0x0081)
934 #define ASC_IS_EISA         (0x0002)
935 #define ASC_IS_PCI          (0x0004)
936 #define ASC_IS_PCI_ULTRA    (0x0104)
937 #define ASC_IS_PCMCIA       (0x0008)
938 #define ASC_IS_MCA          (0x0020)
939 #define ASC_IS_VL           (0x0040)
940 #define ASC_ISA_PNP_PORT_ADDR  (0x279)
941 #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
942 #define ASC_IS_WIDESCSI_16  (0x0100)
943 #define ASC_IS_WIDESCSI_32  (0x0200)
944 #define ASC_IS_BIG_ENDIAN   (0x8000)
945 #define ASC_CHIP_MIN_VER_VL      (0x01)
946 #define ASC_CHIP_MAX_VER_VL      (0x07)
947 #define ASC_CHIP_MIN_VER_PCI     (0x09)
948 #define ASC_CHIP_MAX_VER_PCI     (0x0F)
949 #define ASC_CHIP_VER_PCI_BIT     (0x08)
950 #define ASC_CHIP_MIN_VER_ISA     (0x11)
951 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
952 #define ASC_CHIP_MAX_VER_ISA     (0x27)
953 #define ASC_CHIP_VER_ISA_BIT     (0x30)
954 #define ASC_CHIP_VER_ISAPNP_BIT  (0x20)
955 #define ASC_CHIP_VER_ASYN_BUG    (0x21)
956 #define ASC_CHIP_VER_PCI             0x08
957 #define ASC_CHIP_VER_PCI_ULTRA_3150  (ASC_CHIP_VER_PCI | 0x02)
958 #define ASC_CHIP_VER_PCI_ULTRA_3050  (ASC_CHIP_VER_PCI | 0x03)
959 #define ASC_CHIP_MIN_VER_EISA (0x41)
960 #define ASC_CHIP_MAX_VER_EISA (0x47)
961 #define ASC_CHIP_VER_EISA_BIT (0x40)
962 #define ASC_CHIP_LATEST_VER_EISA   ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
963 #define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER   0x21
964 #define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER   0x0A
965 #define ASC_MAX_VL_DMA_ADDR     (0x07FFFFFFL)
966 #define ASC_MAX_VL_DMA_COUNT    (0x07FFFFFFL)
967 #define ASC_MAX_PCI_DMA_ADDR    (0xFFFFFFFFL)
968 #define ASC_MAX_PCI_DMA_COUNT   (0xFFFFFFFFL)
969 #define ASC_MAX_ISA_DMA_ADDR    (0x00FFFFFFL)
970 #define ASC_MAX_ISA_DMA_COUNT   (0x00FFFFFFL)
971 #define ASC_MAX_EISA_DMA_ADDR   (0x07FFFFFFL)
972 #define ASC_MAX_EISA_DMA_COUNT  (0x07FFFFFFL)
973 
974 #define ASC_SCSI_ID_BITS  3
975 #define ASC_SCSI_TIX_TYPE     uchar
976 #define ASC_ALL_DEVICE_BIT_SET  0xFF
977 #define ASC_SCSI_BIT_ID_TYPE  uchar
978 #define ASC_MAX_TID       7
979 #define ASC_MAX_LUN       7
980 #define ASC_SCSI_WIDTH_BIT_SET  0xFF
981 #define ASC_MAX_SENSE_LEN   32
982 #define ASC_MIN_SENSE_LEN   14
983 #define ASC_MAX_CDB_LEN     12
984 #define ASC_SCSI_RESET_HOLD_TIME_US  60
985 #define SCSICMD_TestUnitReady     0x00
986 #define SCSICMD_Rewind            0x01
987 #define SCSICMD_Rezero            0x01
988 #define SCSICMD_RequestSense      0x03
989 #define SCSICMD_Format            0x04
990 #define SCSICMD_FormatUnit        0x04
991 #define SCSICMD_Read6             0x08
992 #define SCSICMD_Write6            0x0A
993 #define SCSICMD_Seek6             0x0B
994 #define SCSICMD_Inquiry           0x12
995 #define SCSICMD_Verify6           0x13
996 #define SCSICMD_ModeSelect6       0x15
997 #define SCSICMD_ModeSense6        0x1A
998 #define SCSICMD_StartStopUnit     0x1B
999 #define SCSICMD_LoadUnloadTape    0x1B
1000 #define SCSICMD_ReadCapacity      0x25
1001 #define SCSICMD_Read10            0x28
1002 #define SCSICMD_Write10           0x2A
1003 #define SCSICMD_Seek10            0x2B
1004 #define SCSICMD_Erase10           0x2C
1005 #define SCSICMD_WriteAndVerify10  0x2E
1006 #define SCSICMD_Verify10          0x2F
1007 #define SCSICMD_WriteBuffer       0x3B
1008 #define SCSICMD_ReadBuffer        0x3C
1009 #define SCSICMD_ReadLong          0x3E
1010 #define SCSICMD_WriteLong         0x3F
1011 #define SCSICMD_ReadTOC           0x43
1012 #define SCSICMD_ReadHeader        0x44
1013 #define SCSICMD_ModeSelect10      0x55
1014 #define SCSICMD_ModeSense10       0x5A
1015 
1016 /* Inquiry Data Peripheral Device Types */
1017 #define SCSI_TYPE_DASD     0x00
1018 #define SCSI_TYPE_SASD     0x01
1019 #define SCSI_TYPE_PRN      0x02
1020 #define SCSI_TYPE_PROC     0x03
1021 #define SCSI_TYPE_WORM     0x04
1022 #define SCSI_TYPE_CDROM    0x05
1023 #define SCSI_TYPE_SCANNER  0x06
1024 #define SCSI_TYPE_OPTMEM   0x07
1025 #define SCSI_TYPE_MED_CHG  0x08
1026 #define SCSI_TYPE_COMM     0x09
1027 #define SCSI_TYPE_UNKNOWN  0x1F
1028 
1029 #define ADV_INQ_CLOCKING_ST_ONLY    0x0
1030 #define ADV_INQ_CLOCKING_DT_ONLY    0x1
1031 #define ADV_INQ_CLOCKING_ST_AND_DT  0x3
1032 
1033 /*
1034  * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
1035  * and CmdDt (Command Support Data) field bit definitions.
1036  */
1037 #define ADV_INQ_RTN_VPD_AND_CMDDT           0x3
1038 #define ADV_INQ_RTN_CMDDT_FOR_OP_CODE       0x2
1039 #define ADV_INQ_RTN_VPD_FOR_PG_CODE         0x1
1040 #define ADV_INQ_RTN_STD_INQUIRY_DATA        0x0
1041 
1042 #define ASC_SCSIDIR_NOCHK    0x00
1043 #define ASC_SCSIDIR_T2H      0x08
1044 #define ASC_SCSIDIR_H2T      0x10
1045 #define ASC_SCSIDIR_NODATA   0x18
1046 #define SCSI_SENKEY_NO_SENSE      0x00
1047 #define SCSI_SENKEY_UNDEFINED     0x01
1048 #define SCSI_SENKEY_NOT_READY     0x02
1049 #define SCSI_SENKEY_MEDIUM_ERR    0x03
1050 #define SCSI_SENKEY_HW_ERR        0x04
1051 #define SCSI_SENKEY_ILLEGAL       0x05
1052 #define SCSI_SENKEY_ATTENTION     0x06
1053 #define SCSI_SENKEY_PROTECTED     0x07
1054 #define SCSI_SENKEY_BLANK         0x08
1055 #define SCSI_SENKEY_V_UNIQUE      0x09
1056 #define SCSI_SENKEY_CPY_ABORT     0x0A
1057 #define SCSI_SENKEY_ABORT         0x0B
1058 #define SCSI_SENKEY_EQUAL         0x0C
1059 #define SCSI_SENKEY_VOL_OVERFLOW  0x0D
1060 #define SCSI_SENKEY_MISCOMP       0x0E
1061 #define SCSI_SENKEY_RESERVED      0x0F
1062 #define SCSI_ASC_NOMEDIA          0x3A
1063 #define ASC_SRB_HOST(x)  ((uchar)((uchar)(x) >> 4))
1064 #define ASC_SRB_TID(x)   ((uchar)((uchar)(x) & (uchar)0x0F))
1065 #define ASC_SRB_LUN(x)   ((uchar)((uint)(x) >> 13))
1066 #define PUT_CDB1(x)   ((uchar)((uint)(x) >> 8))
1067 #define SS_GOOD              0x00
1068 #define SS_CHK_CONDITION     0x02
1069 #define SS_CONDITION_MET     0x04
1070 #define SS_TARGET_BUSY       0x08
1071 #define SS_INTERMID          0x10
1072 #define SS_INTERMID_COND_MET 0x14
1073 #define SS_RSERV_CONFLICT    0x18
1074 #define SS_CMD_TERMINATED    0x22
1075 #define SS_QUEUE_FULL        0x28
1076 #define MS_CMD_DONE    0x00
1077 #define MS_EXTEND      0x01
1078 #define MS_SDTR_LEN    0x03
1079 #define MS_SDTR_CODE   0x01
1080 #define MS_WDTR_LEN    0x02
1081 #define MS_WDTR_CODE   0x03
1082 #define MS_MDP_LEN    0x05
1083 #define MS_MDP_CODE   0x00
1084 #define M1_SAVE_DATA_PTR        0x02
1085 #define M1_RESTORE_PTRS         0x03
1086 #define M1_DISCONNECT           0x04
1087 #define M1_INIT_DETECTED_ERR    0x05
1088 #define M1_ABORT                0x06
1089 #define M1_MSG_REJECT           0x07
1090 #define M1_NO_OP                0x08
1091 #define M1_MSG_PARITY_ERR       0x09
1092 #define M1_LINK_CMD_DONE        0x0A
1093 #define M1_LINK_CMD_DONE_WFLAG  0x0B
1094 #define M1_BUS_DVC_RESET        0x0C
1095 #define M1_ABORT_TAG            0x0D
1096 #define M1_CLR_QUEUE            0x0E
1097 #define M1_INIT_RECOVERY        0x0F
1098 #define M1_RELEASE_RECOVERY     0x10
1099 #define M1_KILL_IO_PROC         0x11
1100 #define M2_QTAG_MSG_SIMPLE      0x20
1101 #define M2_QTAG_MSG_HEAD        0x21
1102 #define M2_QTAG_MSG_ORDERED     0x22
1103 #define M2_IGNORE_WIDE_RESIDUE  0x23
1104 
1105 /*
1106  * Inquiry data structure and bitfield macros
1107  *
1108  * Only quantities of more than 1 bit are shifted, since the others are
1109  * just tested for true or false. C bitfields aren't portable between big
1110  * and little-endian platforms so they are not used.
1111  */
1112 
1113 #define ASC_INQ_DVC_TYPE(inq)       ((inq)->periph & 0x1f)
1114 #define ASC_INQ_QUALIFIER(inq)      (((inq)->periph & 0xe0) >> 5)
1115 #define ASC_INQ_DVC_TYPE_MOD(inq)   ((inq)->devtype & 0x7f)
1116 #define ASC_INQ_REMOVABLE(inq)      ((inq)->devtype & 0x80)
1117 #define ASC_INQ_ANSI_VER(inq)       ((inq)->ver & 0x07)
1118 #define ASC_INQ_ECMA_VER(inq)       (((inq)->ver & 0x38) >> 3)
1119 #define ASC_INQ_ISO_VER(inq)        (((inq)->ver & 0xc0) >> 6)
1120 #define ASC_INQ_RESPONSE_FMT(inq)   ((inq)->byte3 & 0x0f)
1121 #define ASC_INQ_TERM_IO(inq)        ((inq)->byte3 & 0x40)
1122 #define ASC_INQ_ASYNC_NOTIF(inq)    ((inq)->byte3 & 0x80)
1123 #define ASC_INQ_SOFT_RESET(inq)     ((inq)->flags & 0x01)
1124 #define ASC_INQ_CMD_QUEUE(inq)      ((inq)->flags & 0x02)
1125 #define ASC_INQ_LINK_CMD(inq)       ((inq)->flags & 0x08)
1126 #define ASC_INQ_SYNC(inq)           ((inq)->flags & 0x10)
1127 #define ASC_INQ_WIDE16(inq)         ((inq)->flags & 0x20)
1128 #define ASC_INQ_WIDE32(inq)         ((inq)->flags & 0x40)
1129 #define ASC_INQ_REL_ADDR(inq)       ((inq)->flags & 0x80)
1130 #define ASC_INQ_INFO_UNIT(inq)      ((inq)->info & 0x01)
1131 #define ASC_INQ_QUICK_ARB(inq)      ((inq)->info & 0x02)
1132 #define ASC_INQ_CLOCKING(inq)       (((inq)->info & 0x0c) >> 2)
1133 
1134 typedef struct {
1135     uchar               periph;
1136     uchar               devtype;
1137     uchar               ver;
1138     uchar               byte3;
1139     uchar               add_len;
1140     uchar               res1;
1141     uchar               res2;
1142     uchar               flags;
1143     uchar               vendor_id[8];
1144     uchar               product_id[16];
1145     uchar               product_rev_level[4];
1146 } ASC_SCSI_INQUIRY;
1147 
1148 #define ASC_SG_LIST_PER_Q   7
1149 #define QS_FREE        0x00
1150 #define QS_READY       0x01
1151 #define QS_DISC1       0x02
1152 #define QS_DISC2       0x04
1153 #define QS_BUSY        0x08
1154 #define QS_ABORTED     0x40
1155 #define QS_DONE        0x80
1156 #define QC_NO_CALLBACK   0x01
1157 #define QC_SG_SWAP_QUEUE 0x02
1158 #define QC_SG_HEAD       0x04
1159 #define QC_DATA_IN       0x08
1160 #define QC_DATA_OUT      0x10
1161 #define QC_URGENT        0x20
1162 #define QC_MSG_OUT       0x40
1163 #define QC_REQ_SENSE     0x80
1164 #define QCSG_SG_XFER_LIST  0x02
1165 #define QCSG_SG_XFER_MORE  0x04
1166 #define QCSG_SG_XFER_END   0x08
1167 #define QD_IN_PROGRESS       0x00
1168 #define QD_NO_ERROR          0x01
1169 #define QD_ABORTED_BY_HOST   0x02
1170 #define QD_WITH_ERROR        0x04
1171 #define QD_INVALID_REQUEST   0x80
1172 #define QD_INVALID_HOST_NUM  0x81
1173 #define QD_INVALID_DEVICE    0x82
1174 #define QD_ERR_INTERNAL      0xFF
1175 #define QHSTA_NO_ERROR               0x00
1176 #define QHSTA_M_SEL_TIMEOUT          0x11
1177 #define QHSTA_M_DATA_OVER_RUN        0x12
1178 #define QHSTA_M_DATA_UNDER_RUN       0x12
1179 #define QHSTA_M_UNEXPECTED_BUS_FREE  0x13
1180 #define QHSTA_M_BAD_BUS_PHASE_SEQ    0x14
1181 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1182 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET  0x22
1183 #define QHSTA_D_HOST_ABORT_FAILED       0x23
1184 #define QHSTA_D_EXE_SCSI_Q_FAILED       0x24
1185 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1186 #define QHSTA_D_ASPI_NO_BUF_POOL        0x26
1187 #define QHSTA_M_WTM_TIMEOUT         0x41
1188 #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
1189 #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
1190 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1191 #define QHSTA_M_TARGET_STATUS_BUSY  0x45
1192 #define QHSTA_M_BAD_TAG_CODE        0x46
1193 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY  0x47
1194 #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1195 #define QHSTA_D_LRAM_CMP_ERROR        0x81
1196 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1197 #define ASC_FLAG_SCSIQ_REQ        0x01
1198 #define ASC_FLAG_BIOS_SCSIQ_REQ   0x02
1199 #define ASC_FLAG_BIOS_ASYNC_IO    0x04
1200 #define ASC_FLAG_SRB_LINEAR_ADDR  0x08
1201 #define ASC_FLAG_WIN16            0x10
1202 #define ASC_FLAG_WIN32            0x20
1203 #define ASC_FLAG_ISA_OVER_16MB    0x40
1204 #define ASC_FLAG_DOS_VM_CALLBACK  0x80
1205 #define ASC_TAG_FLAG_EXTRA_BYTES               0x10
1206 #define ASC_TAG_FLAG_DISABLE_DISCONNECT        0x04
1207 #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX  0x08
1208 #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1209 #define ASC_SCSIQ_CPY_BEG              4
1210 #define ASC_SCSIQ_SGHD_CPY_BEG         2
1211 #define ASC_SCSIQ_B_FWD                0
1212 #define ASC_SCSIQ_B_BWD                1
1213 #define ASC_SCSIQ_B_STATUS             2
1214 #define ASC_SCSIQ_B_QNO                3
1215 #define ASC_SCSIQ_B_CNTL               4
1216 #define ASC_SCSIQ_B_SG_QUEUE_CNT       5
1217 #define ASC_SCSIQ_D_DATA_ADDR          8
1218 #define ASC_SCSIQ_D_DATA_CNT          12
1219 #define ASC_SCSIQ_B_SENSE_LEN         20
1220 #define ASC_SCSIQ_DONE_INFO_BEG       22
1221 #define ASC_SCSIQ_D_SRBPTR            22
1222 #define ASC_SCSIQ_B_TARGET_IX         26
1223 #define ASC_SCSIQ_B_CDB_LEN           28
1224 #define ASC_SCSIQ_B_TAG_CODE          29
1225 #define ASC_SCSIQ_W_VM_ID             30
1226 #define ASC_SCSIQ_DONE_STATUS         32
1227 #define ASC_SCSIQ_HOST_STATUS         33
1228 #define ASC_SCSIQ_SCSI_STATUS         34
1229 #define ASC_SCSIQ_CDB_BEG             36
1230 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1231 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT  60
1232 #define ASC_SCSIQ_B_FIRST_SG_WK_QP    48
1233 #define ASC_SCSIQ_B_SG_WK_QP          49
1234 #define ASC_SCSIQ_B_SG_WK_IX          50
1235 #define ASC_SCSIQ_W_ALT_DC1           52
1236 #define ASC_SCSIQ_B_LIST_CNT          6
1237 #define ASC_SCSIQ_B_CUR_LIST_CNT      7
1238 #define ASC_SGQ_B_SG_CNTL             4
1239 #define ASC_SGQ_B_SG_HEAD_QP          5
1240 #define ASC_SGQ_B_SG_LIST_CNT         6
1241 #define ASC_SGQ_B_SG_CUR_LIST_CNT     7
1242 #define ASC_SGQ_LIST_BEG              8
1243 #define ASC_DEF_SCSI1_QNG    4
1244 #define ASC_MAX_SCSI1_QNG    4
1245 #define ASC_DEF_SCSI2_QNG    16
1246 #define ASC_MAX_SCSI2_QNG    32
1247 #define ASC_TAG_CODE_MASK    0x23
1248 #define ASC_STOP_REQ_RISC_STOP      0x01
1249 #define ASC_STOP_ACK_RISC_STOP      0x03
1250 #define ASC_STOP_CLEAN_UP_BUSY_Q    0x10
1251 #define ASC_STOP_CLEAN_UP_DISC_Q    0x20
1252 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1253 #define ASC_TIDLUN_TO_IX(tid, lun)  (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1254 #define ASC_TID_TO_TARGET_ID(tid)   (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1255 #define ASC_TIX_TO_TARGET_ID(tix)   (0x01 << ((tix) & ASC_MAX_TID))
1256 #define ASC_TIX_TO_TID(tix)         ((tix) & ASC_MAX_TID)
1257 #define ASC_TID_TO_TIX(tid)         ((tid) & ASC_MAX_TID)
1258 #define ASC_TIX_TO_LUN(tix)         (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1259 #define ASC_QNO_TO_QADDR(q_no)      ((ASC_QADR_BEG)+((int)(q_no) << 6))
1260 
1261 typedef struct asc_scsiq_1 {
1262     uchar               status;
1263     uchar               q_no;
1264     uchar               cntl;
1265     uchar               sg_queue_cnt;
1266     uchar               target_id;
1267     uchar               target_lun;
1268     ASC_PADDR           data_addr;
1269     ASC_DCNT            data_cnt;
1270     ASC_PADDR           sense_addr;
1271     uchar               sense_len;
1272     uchar               extra_bytes;
1273 } ASC_SCSIQ_1;
1274 
1275 typedef struct asc_scsiq_2 {
1276     ASC_VADDR           srb_ptr;
1277     uchar               target_ix;
1278     uchar               flag;
1279     uchar               cdb_len;
1280     uchar               tag_code;
1281     ushort              vm_id;
1282 } ASC_SCSIQ_2;
1283 
1284 typedef struct asc_scsiq_3 {
1285     uchar               done_stat;
1286     uchar               host_stat;
1287     uchar               scsi_stat;
1288     uchar               scsi_msg;
1289 } ASC_SCSIQ_3;
1290 
1291 typedef struct asc_scsiq_4 {
1292     uchar               cdb[ASC_MAX_CDB_LEN];
1293     uchar               y_first_sg_list_qp;
1294     uchar               y_working_sg_qp;
1295     uchar               y_working_sg_ix;
1296     uchar               y_res;
1297     ushort              x_req_count;
1298     ushort              x_reconnect_rtn;
1299     ASC_PADDR           x_saved_data_addr;
1300     ASC_DCNT            x_saved_data_cnt;
1301 } ASC_SCSIQ_4;
1302 
1303 typedef struct asc_q_done_info {
1304     ASC_SCSIQ_2         d2;
1305     ASC_SCSIQ_3         d3;
1306     uchar               q_status;
1307     uchar               q_no;
1308     uchar               cntl;
1309     uchar               sense_len;
1310     uchar               extra_bytes;
1311     uchar               res;
1312     ASC_DCNT            remain_bytes;
1313 } ASC_QDONE_INFO;
1314 
1315 typedef struct asc_sg_list {
1316     ASC_PADDR           addr;
1317     ASC_DCNT            bytes;
1318 } ASC_SG_LIST;
1319 
1320 typedef struct asc_sg_head {
1321     ushort              entry_cnt;
1322     ushort              queue_cnt;
1323     ushort              entry_to_copy;
1324     ushort              res;
1325     ASC_SG_LIST         sg_list[ASC_MAX_SG_LIST];
1326 } ASC_SG_HEAD;
1327 
1328 #define ASC_MIN_SG_LIST   2
1329 
1330 typedef struct asc_min_sg_head {
1331     ushort              entry_cnt;
1332     ushort              queue_cnt;
1333     ushort              entry_to_copy;
1334     ushort              res;
1335     ASC_SG_LIST         sg_list[ASC_MIN_SG_LIST];
1336 } ASC_MIN_SG_HEAD;
1337 
1338 #define QCX_SORT        (0x0001)
1339 #define QCX_COALEASE    (0x0002)
1340 
1341 typedef struct asc_scsi_q {
1342     ASC_SCSIQ_1         q1;
1343     ASC_SCSIQ_2         q2;
1344     uchar               *cdbptr;
1345     ASC_SG_HEAD         *sg_head;
1346     ushort              remain_sg_entry_cnt;
1347     ushort              next_sg_index;
1348 } ASC_SCSI_Q;
1349 
1350 typedef struct asc_scsi_req_q {
1351     ASC_SCSIQ_1         r1;
1352     ASC_SCSIQ_2         r2;
1353     uchar               *cdbptr;
1354     ASC_SG_HEAD         *sg_head;
1355     uchar               *sense_ptr;
1356     ASC_SCSIQ_3         r3;
1357     uchar               cdb[ASC_MAX_CDB_LEN];
1358     uchar               sense[ASC_MIN_SENSE_LEN];
1359 } ASC_SCSI_REQ_Q;
1360 
1361 typedef struct asc_scsi_bios_req_q {
1362     ASC_SCSIQ_1         r1;
1363     ASC_SCSIQ_2         r2;
1364     uchar               *cdbptr;
1365     ASC_SG_HEAD         *sg_head;
1366     uchar               *sense_ptr;
1367     ASC_SCSIQ_3         r3;
1368     uchar               cdb[ASC_MAX_CDB_LEN];
1369     uchar               sense[ASC_MIN_SENSE_LEN];
1370 } ASC_SCSI_BIOS_REQ_Q;
1371 
1372 typedef struct asc_risc_q {
1373     uchar               fwd;
1374     uchar               bwd;
1375     ASC_SCSIQ_1         i1;
1376     ASC_SCSIQ_2         i2;
1377     ASC_SCSIQ_3         i3;
1378     ASC_SCSIQ_4         i4;
1379 } ASC_RISC_Q;
1380 
1381 typedef struct asc_sg_list_q {
1382     uchar               seq_no;
1383     uchar               q_no;
1384     uchar               cntl;
1385     uchar               sg_head_qp;
1386     uchar               sg_list_cnt;
1387     uchar               sg_cur_list_cnt;
1388 } ASC_SG_LIST_Q;
1389 
1390 typedef struct asc_risc_sg_list_q {
1391     uchar               fwd;
1392     uchar               bwd;
1393     ASC_SG_LIST_Q       sg;
1394     ASC_SG_LIST         sg_list[7];
1395 } ASC_RISC_SG_LIST_Q;
1396 
1397 #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP  0x1000000UL
1398 #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP  1024
1399 #define ASCQ_ERR_NO_ERROR             0
1400 #define ASCQ_ERR_IO_NOT_FOUND         1
1401 #define ASCQ_ERR_LOCAL_MEM            2
1402 #define ASCQ_ERR_CHKSUM               3
1403 #define ASCQ_ERR_START_CHIP           4
1404 #define ASCQ_ERR_INT_TARGET_ID        5
1405 #define ASCQ_ERR_INT_LOCAL_MEM        6
1406 #define ASCQ_ERR_HALT_RISC            7
1407 #define ASCQ_ERR_GET_ASPI_ENTRY       8
1408 #define ASCQ_ERR_CLOSE_ASPI           9
1409 #define ASCQ_ERR_HOST_INQUIRY         0x0A
1410 #define ASCQ_ERR_SAVED_SRB_BAD        0x0B
1411 #define ASCQ_ERR_QCNTL_SG_LIST        0x0C
1412 #define ASCQ_ERR_Q_STATUS             0x0D
1413 #define ASCQ_ERR_WR_SCSIQ             0x0E
1414 #define ASCQ_ERR_PC_ADDR              0x0F
1415 #define ASCQ_ERR_SYN_OFFSET           0x10
1416 #define ASCQ_ERR_SYN_XFER_TIME        0x11
1417 #define ASCQ_ERR_LOCK_DMA             0x12
1418 #define ASCQ_ERR_UNLOCK_DMA           0x13
1419 #define ASCQ_ERR_VDS_CHK_INSTALL      0x14
1420 #define ASCQ_ERR_MICRO_CODE_HALT      0x15
1421 #define ASCQ_ERR_SET_LRAM_ADDR        0x16
1422 #define ASCQ_ERR_CUR_QNG              0x17
1423 #define ASCQ_ERR_SG_Q_LINKS           0x18
1424 #define ASCQ_ERR_SCSIQ_PTR            0x19
1425 #define ASCQ_ERR_ISR_RE_ENTRY         0x1A
1426 #define ASCQ_ERR_CRITICAL_RE_ENTRY    0x1B
1427 #define ASCQ_ERR_ISR_ON_CRITICAL      0x1C
1428 #define ASCQ_ERR_SG_LIST_ODD_ADDRESS  0x1D
1429 #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1430 #define ASCQ_ERR_SCSIQ_NULL_PTR       0x1F
1431 #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR   0x20
1432 #define ASCQ_ERR_GET_NUM_OF_FREE_Q    0x21
1433 #define ASCQ_ERR_SEND_SCSI_Q          0x22
1434 #define ASCQ_ERR_HOST_REQ_RISC_HALT   0x23
1435 #define ASCQ_ERR_RESET_SDTR           0x24
1436 
1437 /*
1438  * Warning code values are set in ASC_DVC_VAR  'warn_code'.
1439  */
1440 #define ASC_WARN_NO_ERROR             0x0000
1441 #define ASC_WARN_IO_PORT_ROTATE       0x0001
1442 #define ASC_WARN_EEPROM_CHKSUM        0x0002
1443 #define ASC_WARN_IRQ_MODIFIED         0x0004
1444 #define ASC_WARN_AUTO_CONFIG          0x0008
1445 #define ASC_WARN_CMD_QNG_CONFLICT     0x0010
1446 #define ASC_WARN_EEPROM_RECOVER       0x0020
1447 #define ASC_WARN_CFG_MSW_RECOVER      0x0040
1448 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1449 
1450 /*
1451  * Error code values are set in ASC_DVC_VAR  'err_code'.
1452  */
1453 #define ASC_IERR_WRITE_EEPROM         0x0001
1454 #define ASC_IERR_MCODE_CHKSUM         0x0002
1455 #define ASC_IERR_SET_PC_ADDR          0x0004
1456 #define ASC_IERR_START_STOP_CHIP      0x0008
1457 #define ASC_IERR_IRQ_NO               0x0010
1458 #define ASC_IERR_SET_IRQ_NO           0x0020
1459 #define ASC_IERR_CHIP_VERSION         0x0040
1460 #define ASC_IERR_SET_SCSI_ID          0x0080
1461 #define ASC_IERR_GET_PHY_ADDR         0x0100
1462 #define ASC_IERR_BAD_SIGNATURE        0x0200
1463 #define ASC_IERR_NO_BUS_TYPE          0x0400
1464 #define ASC_IERR_SCAM                 0x0800
1465 #define ASC_IERR_SET_SDTR             0x1000
1466 #define ASC_IERR_RW_LRAM              0x8000
1467 
1468 #define ASC_DEF_IRQ_NO  10
1469 #define ASC_MAX_IRQ_NO  15
1470 #define ASC_MIN_IRQ_NO  10
1471 #define ASC_MIN_REMAIN_Q        (0x02)
1472 #define ASC_DEF_MAX_TOTAL_QNG   (0xF0)
1473 #define ASC_MIN_TAG_Q_PER_DVC   (0x04)
1474 #define ASC_DEF_TAG_Q_PER_DVC   (0x04)
1475 #define ASC_MIN_FREE_Q        ASC_MIN_REMAIN_Q
1476 #define ASC_MIN_TOTAL_QNG     ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1477 #define ASC_MAX_TOTAL_QNG 240
1478 #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1479 #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG   8
1480 #define ASC_MAX_PCI_INRAM_TOTAL_QNG  20
1481 #define ASC_MAX_INRAM_TAG_QNG   16
1482 #define ASC_IOADR_TABLE_MAX_IX  11
1483 #define ASC_IOADR_GAP   0x10
1484 #define ASC_SEARCH_IOP_GAP 0x10
1485 #define ASC_MIN_IOP_ADDR   (PortAddr)0x0100
1486 #define ASC_MAX_IOP_ADDR   (PortAddr)0x3F0
1487 #define ASC_IOADR_1     (PortAddr)0x0110
1488 #define ASC_IOADR_2     (PortAddr)0x0130
1489 #define ASC_IOADR_3     (PortAddr)0x0150
1490 #define ASC_IOADR_4     (PortAddr)0x0190
1491 #define ASC_IOADR_5     (PortAddr)0x0210
1492 #define ASC_IOADR_6     (PortAddr)0x0230
1493 #define ASC_IOADR_7     (PortAddr)0x0250
1494 #define ASC_IOADR_8     (PortAddr)0x0330
1495 #define ASC_IOADR_DEF   ASC_IOADR_8
1496 #define ASC_LIB_SCSIQ_WK_SP        256
1497 #define ASC_MAX_SYN_XFER_NO        16
1498 #define ASC_SYN_MAX_OFFSET         0x0F
1499 #define ASC_DEF_SDTR_OFFSET        0x0F
1500 #define ASC_DEF_SDTR_INDEX         0x00
1501 #define ASC_SDTR_ULTRA_PCI_10MB_INDEX  0x02
1502 #define SYN_XFER_NS_0  25
1503 #define SYN_XFER_NS_1  30
1504 #define SYN_XFER_NS_2  35
1505 #define SYN_XFER_NS_3  40
1506 #define SYN_XFER_NS_4  50
1507 #define SYN_XFER_NS_5  60
1508 #define SYN_XFER_NS_6  70
1509 #define SYN_XFER_NS_7  85
1510 #define SYN_ULTRA_XFER_NS_0    12
1511 #define SYN_ULTRA_XFER_NS_1    19
1512 #define SYN_ULTRA_XFER_NS_2    25
1513 #define SYN_ULTRA_XFER_NS_3    32
1514 #define SYN_ULTRA_XFER_NS_4    38
1515 #define SYN_ULTRA_XFER_NS_5    44
1516 #define SYN_ULTRA_XFER_NS_6    50
1517 #define SYN_ULTRA_XFER_NS_7    57
1518 #define SYN_ULTRA_XFER_NS_8    63
1519 #define SYN_ULTRA_XFER_NS_9    69
1520 #define SYN_ULTRA_XFER_NS_10   75
1521 #define SYN_ULTRA_XFER_NS_11   82
1522 #define SYN_ULTRA_XFER_NS_12   88
1523 #define SYN_ULTRA_XFER_NS_13   94
1524 #define SYN_ULTRA_XFER_NS_14  100
1525 #define SYN_ULTRA_XFER_NS_15  107
1526 
1527 typedef struct ext_msg {
1528     uchar               msg_type;
1529     uchar               msg_len;
1530     uchar               msg_req;
1531     union {
1532         struct {
1533             uchar               sdtr_xfer_period;
1534             uchar               sdtr_req_ack_offset;
1535         } sdtr;
1536         struct {
1537             uchar               wdtr_width;
1538         } wdtr;
1539         struct {
1540             uchar               mdp_b3;
1541             uchar               mdp_b2;
1542             uchar               mdp_b1;
1543             uchar               mdp_b0;
1544         } mdp;
1545     } u_ext_msg;
1546     uchar               res;
1547 } EXT_MSG;
1548 
1549 #define xfer_period     u_ext_msg.sdtr.sdtr_xfer_period
1550 #define req_ack_offset  u_ext_msg.sdtr.sdtr_req_ack_offset
1551 #define wdtr_width      u_ext_msg.wdtr.wdtr_width
1552 #define mdp_b3          u_ext_msg.mdp_b3
1553 #define mdp_b2          u_ext_msg.mdp_b2
1554 #define mdp_b1          u_ext_msg.mdp_b1
1555 #define mdp_b0          u_ext_msg.mdp_b0
1556 
1557 typedef struct asc_dvc_cfg {
1558     ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1559     ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1560     ASC_SCSI_BIT_ID_TYPE disc_enable;
1561     ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1562     uchar               chip_scsi_id;
1563     uchar               isa_dma_speed;
1564     uchar               isa_dma_channel;
1565     uchar               chip_version;
1566     ushort              pci_device_id;
1567     ushort              lib_serial_no;
1568     ushort              lib_version;
1569     ushort              mcode_date;
1570     ushort              mcode_version;
1571     uchar               max_tag_qng[ASC_MAX_TID + 1];
1572     uchar               *overrun_buf;
1573     uchar               sdtr_period_offset[ASC_MAX_TID + 1];
1574     ushort              pci_slot_info;
1575     uchar               adapter_info[6];
1576 } ASC_DVC_CFG;
1577 
1578 #define ASC_DEF_DVC_CNTL       0xFFFF
1579 #define ASC_DEF_CHIP_SCSI_ID   7
1580 #define ASC_DEF_ISA_DMA_SPEED  4
1581 #define ASC_INIT_STATE_NULL          0x0000
1582 #define ASC_INIT_STATE_BEG_GET_CFG   0x0001
1583 #define ASC_INIT_STATE_END_GET_CFG   0x0002
1584 #define ASC_INIT_STATE_BEG_SET_CFG   0x0004
1585 #define ASC_INIT_STATE_END_SET_CFG   0x0008
1586 #define ASC_INIT_STATE_BEG_LOAD_MC   0x0010
1587 #define ASC_INIT_STATE_END_LOAD_MC   0x0020
1588 #define ASC_INIT_STATE_BEG_INQUIRY   0x0040
1589 #define ASC_INIT_STATE_END_INQUIRY   0x0080
1590 #define ASC_INIT_RESET_SCSI_DONE     0x0100
1591 #define ASC_INIT_STATE_WITHOUT_EEP   0x8000
1592 #define ASC_PCI_DEVICE_ID_REV_A      0x1100
1593 #define ASC_PCI_DEVICE_ID_REV_B      0x1200
1594 #define ASC_BUG_FIX_IF_NOT_DWB       0x0001
1595 #define ASC_BUG_FIX_ASYN_USE_SYN     0x0002
1596 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1597 #define ASC_MIN_TAGGED_CMD  7
1598 #define ASC_MAX_SCSI_RESET_WAIT      30
1599 
1600 struct asc_dvc_var;     /* Forward Declaration. */
1601 
1602 typedef void (* ASC_ISR_CALLBACK)(struct asc_dvc_var *, ASC_QDONE_INFO *);
1603 typedef int (* ASC_EXE_CALLBACK)(struct asc_dvc_var *, ASC_SCSI_Q *);
1604 
1605 typedef struct asc_dvc_var {
1606     PortAddr            iop_base;
1607     ushort              err_code;
1608     ushort              dvc_cntl;
1609     ushort              bug_fix_cntl;
1610     ushort              bus_type;
1611     ASC_ISR_CALLBACK    isr_callback;
1612     ASC_EXE_CALLBACK    exe_callback;
1613     ASC_SCSI_BIT_ID_TYPE init_sdtr;
1614     ASC_SCSI_BIT_ID_TYPE sdtr_done;
1615     ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1616     ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1617     ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1618     ASC_SCSI_BIT_ID_TYPE start_motor;
1619     uchar               scsi_reset_wait;
1620     uchar               chip_no;
1621     char                is_in_int;
1622     uchar               max_total_qng;
1623     uchar               cur_total_qng;
1624     uchar               in_critical_cnt;
1625     uchar               irq_no;
1626     uchar               last_q_shortage;
1627     ushort              init_state;
1628     uchar               cur_dvc_qng[ASC_MAX_TID + 1];
1629     uchar               max_dvc_qng[ASC_MAX_TID + 1];
1630     ASC_SCSI_Q  *scsiq_busy_head[ASC_MAX_TID + 1];
1631     ASC_SCSI_Q  *scsiq_busy_tail[ASC_MAX_TID + 1];
1632     uchar               sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1633     ASC_DVC_CFG *cfg;
1634     ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1635     char                redo_scam;
1636     ushort              res2;
1637     uchar               dos_int13_table[ASC_MAX_TID + 1];
1638     ASC_DCNT            max_dma_count;
1639     ASC_SCSI_BIT_ID_TYPE no_scam;
1640     ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1641     uchar               max_sdtr_index;
1642     uchar               host_init_sdtr_index;
1643     struct asc_board    *drv_ptr;
1644     ASC_DCNT            uc_break;
1645 } ASC_DVC_VAR;
1646 
1647 typedef struct asc_dvc_inq_info {
1648     uchar               type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1649 } ASC_DVC_INQ_INFO;
1650 
1651 typedef struct asc_cap_info {
1652     ASC_DCNT            lba;
1653     ASC_DCNT            blk_size;
1654 } ASC_CAP_INFO;
1655 
1656 typedef struct asc_cap_info_array {
1657     ASC_CAP_INFO        cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1658 } ASC_CAP_INFO_ARRAY;
1659 
1660 #define ASC_MCNTL_NO_SEL_TIMEOUT  (ushort)0x0001
1661 #define ASC_MCNTL_NULL_TARGET     (ushort)0x0002
1662 #define ASC_CNTL_INITIATOR         (ushort)0x0001
1663 #define ASC_CNTL_BIOS_GT_1GB       (ushort)0x0002
1664 #define ASC_CNTL_BIOS_GT_2_DISK    (ushort)0x0004
1665 #define ASC_CNTL_BIOS_REMOVABLE    (ushort)0x0008
1666 #define ASC_CNTL_NO_SCAM           (ushort)0x0010
1667 #define ASC_CNTL_INT_MULTI_Q       (ushort)0x0080
1668 #define ASC_CNTL_NO_LUN_SUPPORT    (ushort)0x0040
1669 #define ASC_CNTL_NO_VERIFY_COPY    (ushort)0x0100
1670 #define ASC_CNTL_RESET_SCSI        (ushort)0x0200
1671 #define ASC_CNTL_INIT_INQUIRY      (ushort)0x0400
1672 #define ASC_CNTL_INIT_VERBOSE      (ushort)0x0800
1673 #define ASC_CNTL_SCSI_PARITY       (ushort)0x1000
1674 #define ASC_CNTL_BURST_MODE        (ushort)0x2000
1675 #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1676 #define ASC_EEP_DVC_CFG_BEG_VL    2
1677 #define ASC_EEP_MAX_DVC_ADDR_VL   15
1678 #define ASC_EEP_DVC_CFG_BEG      32
1679 #define ASC_EEP_MAX_DVC_ADDR     45
1680 #define ASC_EEP_DEFINED_WORDS    10
1681 #define ASC_EEP_MAX_ADDR         63
1682 #define ASC_EEP_RES_WORDS         0
1683 #define ASC_EEP_MAX_RETRY        20
1684 #define ASC_MAX_INIT_BUSY_RETRY   8
1685 #define ASC_EEP_ISA_PNP_WSIZE    16
1686 
1687 /*
1688  * These macros keep the chip SCSI id and ISA DMA speed
1689  * bitfields in board order. C bitfields aren't portable
1690  * between big and little-endian platforms so they are
1691  * not used.
1692  */
1693 
1694 #define ASC_EEP_GET_CHIP_ID(cfg)    ((cfg)->id_speed & 0x0f)
1695 #define ASC_EEP_GET_DMA_SPD(cfg)    (((cfg)->id_speed & 0xf0) >> 4)
1696 #define ASC_EEP_SET_CHIP_ID(cfg, sid) \
1697    ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
1698 #define ASC_EEP_SET_DMA_SPD(cfg, spd) \
1699    ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
1700 
1701 typedef struct asceep_config {
1702     ushort              cfg_lsw;
1703     ushort              cfg_msw;
1704     uchar               init_sdtr;
1705     uchar               disc_enable;
1706     uchar               use_cmd_qng;
1707     uchar               start_motor;
1708     uchar               max_total_qng;
1709     uchar               max_tag_qng;
1710     uchar               bios_scan;
1711     uchar               power_up_wait;
1712     uchar               no_scam;
1713     uchar               id_speed; /* low order 4 bits is chip scsi id */
1714                                   /* high order 4 bits is isa dma speed */
1715     uchar               dos_int13_table[ASC_MAX_TID + 1];
1716     uchar               adapter_info[6];
1717     ushort              cntl;
1718     ushort              chksum;
1719 } ASCEEP_CONFIG;
1720 
1721 #define ASC_PCI_CFG_LSW_SCSI_PARITY  0x0800
1722 #define ASC_PCI_CFG_LSW_BURST_MODE   0x0080
1723 #define ASC_PCI_CFG_LSW_INTR_ABLE    0x0020
1724 
1725 #define ASC_EEP_CMD_READ          0x80
1726 #define ASC_EEP_CMD_WRITE         0x40
1727 #define ASC_EEP_CMD_WRITE_ABLE    0x30
1728 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
1729 #define ASC_OVERRUN_BSIZE  0x00000048UL
1730 #define ASC_CTRL_BREAK_ONCE        0x0001
1731 #define ASC_CTRL_BREAK_STAY_IDLE   0x0002
1732 #define ASCV_MSGOUT_BEG         0x0000
1733 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1734 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1735 #define ASCV_BREAK_SAVED_CODE   (ushort)0x0006
1736 #define ASCV_MSGIN_BEG          (ASCV_MSGOUT_BEG+8)
1737 #define ASCV_MSGIN_SDTR_PERIOD  (ASCV_MSGIN_BEG+3)
1738 #define ASCV_MSGIN_SDTR_OFFSET  (ASCV_MSGIN_BEG+4)
1739 #define ASCV_SDTR_DATA_BEG      (ASCV_MSGIN_BEG+8)
1740 #define ASCV_SDTR_DONE_BEG      (ASCV_SDTR_DATA_BEG+8)
1741 #define ASCV_MAX_DVC_QNG_BEG    (ushort)0x0020
1742 #define ASCV_BREAK_ADDR           (ushort)0x0028
1743 #define ASCV_BREAK_NOTIFY_COUNT   (ushort)0x002A
1744 #define ASCV_BREAK_CONTROL        (ushort)0x002C
1745 #define ASCV_BREAK_HIT_COUNT      (ushort)0x002E
1746 
1747 #define ASCV_ASCDVC_ERR_CODE_W  (ushort)0x0030
1748 #define ASCV_MCODE_CHKSUM_W   (ushort)0x0032
1749 #define ASCV_MCODE_SIZE_W     (ushort)0x0034
1750 #define ASCV_STOP_CODE_B      (ushort)0x0036
1751 #define ASCV_DVC_ERR_CODE_B   (ushort)0x0037
1752 #define ASCV_OVERRUN_PADDR_D  (ushort)0x0038
1753 #define ASCV_OVERRUN_BSIZE_D  (ushort)0x003C
1754 #define ASCV_HALTCODE_W       (ushort)0x0040
1755 #define ASCV_CHKSUM_W         (ushort)0x0042
1756 #define ASCV_MC_DATE_W        (ushort)0x0044
1757 #define ASCV_MC_VER_W         (ushort)0x0046
1758 #define ASCV_NEXTRDY_B        (ushort)0x0048
1759 #define ASCV_DONENEXT_B       (ushort)0x0049
1760 #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1761 #define ASCV_SCSIBUSY_B       (ushort)0x004B
1762 #define ASCV_Q_DONE_IN_PROGRESS_B  (ushort)0x004C
1763 #define ASCV_CURCDB_B         (ushort)0x004D
1764 #define ASCV_RCLUN_B          (ushort)0x004E
1765 #define ASCV_BUSY_QHEAD_B     (ushort)0x004F
1766 #define ASCV_DISC1_QHEAD_B    (ushort)0x0050
1767 #define ASCV_DISC_ENABLE_B    (ushort)0x0052
1768 #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1769 #define ASCV_HOSTSCSI_ID_B    (ushort)0x0055
1770 #define ASCV_MCODE_CNTL_B     (ushort)0x0056
1771 #define ASCV_NULL_TARGET_B    (ushort)0x0057
1772 #define ASCV_FREE_Q_HEAD_W    (ushort)0x0058
1773 #define ASCV_DONE_Q_TAIL_W    (ushort)0x005A
1774 #define ASCV_FREE_Q_HEAD_B    (ushort)(ASCV_FREE_Q_HEAD_W+1)
1775 #define ASCV_DONE_Q_TAIL_B    (ushort)(ASCV_DONE_Q_TAIL_W+1)
1776 #define ASCV_HOST_FLAG_B      (ushort)0x005D
1777 #define ASCV_TOTAL_READY_Q_B  (ushort)0x0064
1778 #define ASCV_VER_SERIAL_B     (ushort)0x0065
1779 #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1780 #define ASCV_WTM_FLAG_B       (ushort)0x0068
1781 #define ASCV_RISC_FLAG_B      (ushort)0x006A
1782 #define ASCV_REQ_SG_LIST_QP   (ushort)0x006B
1783 #define ASC_HOST_FLAG_IN_ISR        0x01
1784 #define ASC_HOST_FLAG_ACK_INT       0x02
1785 #define ASC_RISC_FLAG_GEN_INT      0x01
1786 #define ASC_RISC_FLAG_REQ_SG_LIST  0x02
1787 #define IOP_CTRL         (0x0F)
1788 #define IOP_STATUS       (0x0E)
1789 #define IOP_INT_ACK      IOP_STATUS
1790 #define IOP_REG_IFC      (0x0D)
1791 #define IOP_SYN_OFFSET    (0x0B)
1792 #define IOP_EXTRA_CONTROL (0x0D)
1793 #define IOP_REG_PC        (0x0C)
1794 #define IOP_RAM_ADDR      (0x0A)
1795 #define IOP_RAM_DATA      (0x08)
1796 #define IOP_EEP_DATA      (0x06)
1797 #define IOP_EEP_CMD       (0x07)
1798 #define IOP_VERSION       (0x03)
1799 #define IOP_CONFIG_HIGH   (0x04)
1800 #define IOP_CONFIG_LOW    (0x02)
1801 #define IOP_SIG_BYTE      (0x01)
1802 #define IOP_SIG_WORD      (0x00)
1803 #define IOP_REG_DC1      (0x0E)
1804 #define IOP_REG_DC0      (0x0C)
1805 #define IOP_REG_SB       (0x0B)
1806 #define IOP_REG_DA1      (0x0A)
1807 #define IOP_REG_DA0      (0x08)
1808 #define IOP_REG_SC       (0x09)
1809 #define IOP_DMA_SPEED    (0x07)
1810 #define IOP_REG_FLAG     (0x07)
1811 #define IOP_FIFO_H       (0x06)
1812 #define IOP_FIFO_L       (0x04)
1813 #define IOP_REG_ID       (0x05)
1814 #define IOP_REG_QP       (0x03)
1815 #define IOP_REG_IH       (0x02)
1816 #define IOP_REG_IX       (0x01)
1817 #define IOP_REG_AX       (0x00)
1818 #define IFC_REG_LOCK      (0x00)
1819 #define IFC_REG_UNLOCK    (0x09)
1820 #define IFC_WR_EN_FILTER  (0x10)
1821 #define IFC_RD_NO_EEPROM  (0x10)
1822 #define IFC_SLEW_RATE     (0x20)
1823 #define IFC_ACT_NEG       (0x40)
1824 #define IFC_INP_FILTER    (0x80)
1825 #define IFC_INIT_DEFAULT  (IFC_ACT_NEG | IFC_REG_UNLOCK)
1826 #define SC_SEL   (uchar)(0x80)
1827 #define SC_BSY   (uchar)(0x40)
1828 #define SC_ACK   (uchar)(0x20)
1829 #define SC_REQ   (uchar)(0x10)
1830 #define SC_ATN   (uchar)(0x08)
1831 #define SC_IO    (uchar)(0x04)
1832 #define SC_CD    (uchar)(0x02)
1833 #define SC_MSG   (uchar)(0x01)
1834 #define SEC_SCSI_CTL         (uchar)(0x80)
1835 #define SEC_ACTIVE_NEGATE    (uchar)(0x40)
1836 #define SEC_SLEW_RATE        (uchar)(0x20)
1837 #define SEC_ENABLE_FILTER    (uchar)(0x10)
1838 #define ASC_HALT_EXTMSG_IN     (ushort)0x8000
1839 #define ASC_HALT_CHK_CONDITION (ushort)0x8100
1840 #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1841 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX  (ushort)0x8300
1842 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX   (ushort)0x8400
1843 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1844 #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1845 #define ASC_MAX_QNO        0xF8
1846 #define ASC_DATA_SEC_BEG   (ushort)0x0080
1847 #define ASC_DATA_SEC_END   (ushort)0x0080
1848 #define ASC_CODE_SEC_BEG   (ushort)0x0080
1849 #define ASC_CODE_SEC_END   (ushort)0x0080
1850 #define ASC_QADR_BEG       (0x4000)
1851 #define ASC_QADR_USED      (ushort)(ASC_MAX_QNO * 64)
1852 #define ASC_QADR_END       (ushort)0x7FFF
1853 #define ASC_QLAST_ADR      (ushort)0x7FC0
1854 #define ASC_QBLK_SIZE      0x40
1855 #define ASC_BIOS_DATA_QBEG 0xF8
1856 #define ASC_MIN_ACTIVE_QNO 0x01
1857 #define ASC_QLINK_END      0xFF
1858 #define ASC_EEPROM_WORDS   0x10
1859 #define ASC_MAX_MGS_LEN    0x10
1860 #define ASC_BIOS_ADDR_DEF  0xDC00
1861 #define ASC_BIOS_SIZE      0x3800
1862 #define ASC_BIOS_RAM_OFF   0x3800
1863 #define ASC_BIOS_RAM_SIZE  0x800
1864 #define ASC_BIOS_MIN_ADDR  0xC000
1865 #define ASC_BIOS_MAX_ADDR  0xEC00
1866 #define ASC_BIOS_BANK_SIZE 0x0400
1867 #define ASC_MCODE_START_ADDR  0x0080
1868 #define ASC_CFG0_HOST_INT_ON    0x0020
1869 #define ASC_CFG0_BIOS_ON        0x0040
1870 #define ASC_CFG0_VERA_BURST_ON  0x0080
1871 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
1872 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
1873 #define ASC_CFG1_LRAM_8BITS_ON  0x0800
1874 #define ASC_CFG_MSW_CLR_MASK    0x3080
1875 #define CSW_TEST1             (ASC_CS_TYPE)0x8000
1876 #define CSW_AUTO_CONFIG       (ASC_CS_TYPE)0x4000
1877 #define CSW_RESERVED1         (ASC_CS_TYPE)0x2000
1878 #define CSW_IRQ_WRITTEN       (ASC_CS_TYPE)0x1000
1879 #define CSW_33MHZ_SELECTED    (ASC_CS_TYPE)0x0800
1880 #define CSW_TEST2             (ASC_CS_TYPE)0x0400
1881 #define CSW_TEST3             (ASC_CS_TYPE)0x0200
1882 #define CSW_RESERVED2         (ASC_CS_TYPE)0x0100
1883 #define CSW_DMA_DONE          (ASC_CS_TYPE)0x0080
1884 #define CSW_FIFO_RDY          (ASC_CS_TYPE)0x0040
1885 #define CSW_EEP_READ_DONE     (ASC_CS_TYPE)0x0020
1886 #define CSW_HALTED            (ASC_CS_TYPE)0x0010
1887 #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1888 #define CSW_PARITY_ERR        (ASC_CS_TYPE)0x0004
1889 #define CSW_SCSI_RESET_LATCH  (ASC_CS_TYPE)0x0002
1890 #define CSW_INT_PENDING       (ASC_CS_TYPE)0x0001
1891 #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1892 #define CIW_INT_ACK      (ASC_CS_TYPE)0x0100
1893 #define CIW_TEST1        (ASC_CS_TYPE)0x0200
1894 #define CIW_TEST2        (ASC_CS_TYPE)0x0400
1895 #define CIW_SEL_33MHZ    (ASC_CS_TYPE)0x0800
1896 #define CIW_IRQ_ACT      (ASC_CS_TYPE)0x1000
1897 #define CC_CHIP_RESET   (uchar)0x80
1898 #define CC_SCSI_RESET   (uchar)0x40
1899 #define CC_HALT         (uchar)0x20
1900 #define CC_SINGLE_STEP  (uchar)0x10
1901 #define CC_DMA_ABLE     (uchar)0x08
1902 #define CC_TEST         (uchar)0x04
1903 #define CC_BANK_ONE     (uchar)0x02
1904 #define CC_DIAG         (uchar)0x01
1905 #define ASC_1000_ID0W      0x04C1
1906 #define ASC_1000_ID0W_FIX  0x00C1
1907 #define ASC_1000_ID1B      0x25
1908 #define ASC_EISA_BIG_IOP_GAP   (0x1C30-0x0C50)
1909 #define ASC_EISA_SMALL_IOP_GAP (0x0020)
1910 #define ASC_EISA_MIN_IOP_ADDR  (0x0C30)
1911 #define ASC_EISA_MAX_IOP_ADDR  (0xFC50)
1912 #define ASC_EISA_REV_IOP_MASK  (0x0C83)
1913 #define ASC_EISA_PID_IOP_MASK  (0x0C80)
1914 #define ASC_EISA_CFG_IOP_MASK  (0x0C86)
1915 #define ASC_GET_EISA_SLOT(iop)  (PortAddr)((iop) & 0xF000)
1916 #define ASC_EISA_ID_740    0x01745004UL
1917 #define ASC_EISA_ID_750    0x01755004UL
1918 #define INS_HALTINT        (ushort)0x6281
1919 #define INS_HALT           (ushort)0x6280
1920 #define INS_SINT           (ushort)0x6200
1921 #define INS_RFLAG_WTM      (ushort)0x7380
1922 #define ASC_MC_SAVE_CODE_WSIZE  0x500
1923 #define ASC_MC_SAVE_DATA_WSIZE  0x40
1924 
1925 typedef struct asc_mc_saved {
1926     ushort              data[ASC_MC_SAVE_DATA_WSIZE];
1927     ushort              code[ASC_MC_SAVE_CODE_WSIZE];
1928 } ASC_MC_SAVED;
1929 
1930 #define AscGetQDoneInProgress(port)         AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1931 #define AscPutQDoneInProgress(port, val)    AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1932 #define AscGetVarFreeQHead(port)            AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1933 #define AscGetVarDoneQTail(port)            AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1934 #define AscPutVarFreeQHead(port, val)       AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1935 #define AscPutVarDoneQTail(port, val)       AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1936 #define AscGetRiscVarFreeQHead(port)        AscReadLramByte((port), ASCV_NEXTRDY_B)
1937 #define AscGetRiscVarDoneQTail(port)        AscReadLramByte((port), ASCV_DONENEXT_B)
1938 #define AscPutRiscVarFreeQHead(port, val)   AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1939 #define AscPutRiscVarDoneQTail(port, val)   AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1940 #define AscPutMCodeSDTRDoneAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1941 #define AscGetMCodeSDTRDoneAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1942 #define AscPutMCodeInitSDTRAtID(port, id, data)  AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1943 #define AscGetMCodeInitSDTRAtID(port, id)        AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1944 #define AscSynIndexToPeriod(index)        (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1945 #define AscGetChipSignatureByte(port)     (uchar)inp((port)+IOP_SIG_BYTE)
1946 #define AscGetChipSignatureWord(port)     (ushort)inpw((port)+IOP_SIG_WORD)
1947 #define AscGetChipVerNo(port)             (uchar)inp((port)+IOP_VERSION)
1948 #define AscGetChipCfgLsw(port)            (ushort)inpw((port)+IOP_CONFIG_LOW)
1949 #define AscGetChipCfgMsw(port)            (ushort)inpw((port)+IOP_CONFIG_HIGH)
1950 #define AscSetChipCfgLsw(port, data)      outpw((port)+IOP_CONFIG_LOW, data)
1951 #define AscSetChipCfgMsw(port, data)      outpw((port)+IOP_CONFIG_HIGH, data)
1952 #define AscGetChipEEPCmd(port)            (uchar)inp((port)+IOP_EEP_CMD)
1953 #define AscSetChipEEPCmd(port, data)      outp((port)+IOP_EEP_CMD, data)
1954 #define AscGetChipEEPData(port)           (ushort)inpw((port)+IOP_EEP_DATA)
1955 #define AscSetChipEEPData(port, data)     outpw((port)+IOP_EEP_DATA, data)
1956 #define AscGetChipLramAddr(port)          (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1957 #define AscSetChipLramAddr(port, addr)    outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1958 #define AscGetChipLramData(port)          (ushort)inpw((port)+IOP_RAM_DATA)
1959 #define AscSetChipLramData(port, data)    outpw((port)+IOP_RAM_DATA, data)
1960 #define AscGetChipIFC(port)               (uchar)inp((port)+IOP_REG_IFC)
1961 #define AscSetChipIFC(port, data)          outp((port)+IOP_REG_IFC, data)
1962 #define AscGetChipStatus(port)            (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1963 #define AscSetChipStatus(port, cs_val)    outpw((port)+IOP_STATUS, cs_val)
1964 #define AscGetChipControl(port)           (uchar)inp((port)+IOP_CTRL)
1965 #define AscSetChipControl(port, cc_val)   outp((port)+IOP_CTRL, cc_val)
1966 #define AscGetChipSyn(port)               (uchar)inp((port)+IOP_SYN_OFFSET)
1967 #define AscSetChipSyn(port, data)         outp((port)+IOP_SYN_OFFSET, data)
1968 #define AscSetPCAddr(port, data)          outpw((port)+IOP_REG_PC, data)
1969 #define AscGetPCAddr(port)                (ushort)inpw((port)+IOP_REG_PC)
1970 #define AscIsIntPending(port)             (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1971 #define AscGetChipScsiID(port)            ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1972 #define AscGetExtraControl(port)          (uchar)inp((port)+IOP_EXTRA_CONTROL)
1973 #define AscSetExtraControl(port, data)    outp((port)+IOP_EXTRA_CONTROL, data)
1974 #define AscReadChipAX(port)               (ushort)inpw((port)+IOP_REG_AX)
1975 #define AscWriteChipAX(port, data)        outpw((port)+IOP_REG_AX, data)
1976 #define AscReadChipIX(port)               (uchar)inp((port)+IOP_REG_IX)
1977 #define AscWriteChipIX(port, data)        outp((port)+IOP_REG_IX, data)
1978 #define AscReadChipIH(port)               (ushort)inpw((port)+IOP_REG_IH)
1979 #define AscWriteChipIH(port, data)        outpw((port)+IOP_REG_IH, data)
1980 #define AscReadChipQP(port)               (uchar)inp((port)+IOP_REG_QP)
1981 #define AscWriteChipQP(port, data)        outp((port)+IOP_REG_QP, data)
1982 #define AscReadChipFIFO_L(port)           (ushort)inpw((port)+IOP_REG_FIFO_L)
1983 #define AscWriteChipFIFO_L(port, data)    outpw((port)+IOP_REG_FIFO_L, data)
1984 #define AscReadChipFIFO_H(port)           (ushort)inpw((port)+IOP_REG_FIFO_H)
1985 #define AscWriteChipFIFO_H(port, data)    outpw((port)+IOP_REG_FIFO_H, data)
1986 #define AscReadChipDmaSpeed(port)         (uchar)inp((port)+IOP_DMA_SPEED)
1987 #define AscWriteChipDmaSpeed(port, data)  outp((port)+IOP_DMA_SPEED, data)
1988 #define AscReadChipDA0(port)              (ushort)inpw((port)+IOP_REG_DA0)
1989 #define AscWriteChipDA0(port)             outpw((port)+IOP_REG_DA0, data)
1990 #define AscReadChipDA1(port)              (ushort)inpw((port)+IOP_REG_DA1)
1991 #define AscWriteChipDA1(port)             outpw((port)+IOP_REG_DA1, data)
1992 #define AscReadChipDC0(port)              (ushort)inpw((port)+IOP_REG_DC0)
1993 #define AscWriteChipDC0(port)             outpw((port)+IOP_REG_DC0, data)
1994 #define AscReadChipDC1(port)              (ushort)inpw((port)+IOP_REG_DC1)
1995 #define AscWriteChipDC1(port)             outpw((port)+IOP_REG_DC1, data)
1996 #define AscReadChipDvcID(port)            (uchar)inp((port)+IOP_REG_ID)
1997 #define AscWriteChipDvcID(port, data)     outp((port)+IOP_REG_ID, data)
1998 
1999 STATIC int       AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
2000 STATIC int       AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
2001 STATIC void      AscWaitEEPRead(void);
2002 STATIC void      AscWaitEEPWrite(void);
2003 STATIC ushort    AscReadEEPWord(PortAddr, uchar);
2004 STATIC ushort    AscWriteEEPWord(PortAddr, uchar, ushort);
2005 STATIC ushort    AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
2006 STATIC int       AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
2007 STATIC int       AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
2008 STATIC int       AscStartChip(PortAddr);
2009 STATIC int       AscStopChip(PortAddr);
2010 STATIC void      AscSetChipIH(PortAddr, ushort);
2011 STATIC int       AscIsChipHalted(PortAddr);
2012 STATIC void      AscAckInterrupt(PortAddr);
2013 STATIC void      AscDisableInterrupt(PortAddr);
2014 STATIC void      AscEnableInterrupt(PortAddr);
2015 STATIC void      AscSetBank(PortAddr, uchar);
2016 STATIC int       AscResetChipAndScsiBus(ASC_DVC_VAR *);
2017 #ifdef CONFIG_ISA
2018 STATIC ushort    AscGetIsaDmaChannel(PortAddr);
2019 STATIC ushort    AscSetIsaDmaChannel(PortAddr, ushort);
2020 STATIC uchar     AscSetIsaDmaSpeed(PortAddr, uchar);
2021 STATIC uchar     AscGetIsaDmaSpeed(PortAddr);
2022 #endif /* CONFIG_ISA */
2023 STATIC uchar     AscReadLramByte(PortAddr, ushort);
2024 STATIC ushort    AscReadLramWord(PortAddr, ushort);
2025 #if CC_VERY_LONG_SG_LIST
2026 STATIC ASC_DCNT  AscReadLramDWord(PortAddr, ushort);
2027 #endif /* CC_VERY_LONG_SG_LIST */
2028 STATIC void      AscWriteLramWord(PortAddr, ushort, ushort);
2029 STATIC void      AscWriteLramByte(PortAddr, ushort, uchar);
2030 STATIC ASC_DCNT  AscMemSumLramWord(PortAddr, ushort, int);
2031 STATIC void      AscMemWordSetLram(PortAddr, ushort, ushort, int);
2032 STATIC void      AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
2033 STATIC void      AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
2034 STATIC void      AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
2035 STATIC ushort    AscInitAscDvcVar(ASC_DVC_VAR *);
2036 STATIC ushort    AscInitFromEEP(ASC_DVC_VAR *);
2037 STATIC ushort    AscInitFromAscDvcVar(ASC_DVC_VAR *);
2038 STATIC ushort    AscInitMicroCodeVar(ASC_DVC_VAR *);
2039 STATIC int       AscTestExternalLram(ASC_DVC_VAR *);
2040 STATIC uchar     AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
2041 STATIC uchar     AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
2042 STATIC void      AscSetChipSDTR(PortAddr, uchar, uchar);
2043 STATIC uchar     AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
2044 STATIC uchar     AscAllocFreeQueue(PortAddr, uchar);
2045 STATIC uchar     AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
2046 STATIC int       AscHostReqRiscHalt(PortAddr);
2047 STATIC int       AscStopQueueExe(PortAddr);
2048 STATIC int       AscSendScsiQueue(ASC_DVC_VAR *,
2049                     ASC_SCSI_Q * scsiq,
2050                     uchar n_q_required);
2051 STATIC int       AscPutReadyQueue(ASC_DVC_VAR *,
2052                     ASC_SCSI_Q *, uchar);
2053 STATIC int       AscPutReadySgListQueue(ASC_DVC_VAR *,
2054                     ASC_SCSI_Q *, uchar);
2055 STATIC int       AscSetChipSynRegAtID(PortAddr, uchar, uchar);
2056 STATIC int       AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
2057 STATIC ushort    AscInitLram(ASC_DVC_VAR *);
2058 STATIC ushort    AscInitQLinkVar(ASC_DVC_VAR *);
2059 STATIC int       AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
2060 STATIC int       AscIsrChipHalted(ASC_DVC_VAR *);
2061 STATIC uchar     _AscCopyLramScsiDoneQ(PortAddr, ushort,
2062                     ASC_QDONE_INFO *, ASC_DCNT);
2063 STATIC int       AscIsrQDone(ASC_DVC_VAR *);
2064 STATIC int       AscCompareString(uchar *, uchar *, int);
2065 #ifdef CONFIG_ISA
2066 STATIC ushort    AscGetEisaChipCfg(PortAddr);
2067 STATIC ASC_DCNT  AscGetEisaProductID(PortAddr);
2068 STATIC PortAddr  AscSearchIOPortAddrEISA(PortAddr);
2069 STATIC PortAddr  AscSearchIOPortAddr11(PortAddr);
2070 STATIC PortAddr  AscSearchIOPortAddr(PortAddr, ushort);
2071 STATIC void      AscSetISAPNPWaitForKey(void);
2072 #endif /* CONFIG_ISA */
2073 STATIC uchar     AscGetChipScsiCtrl(PortAddr);
2074 STATIC uchar     AscSetChipScsiID(PortAddr, uchar);
2075 STATIC uchar     AscGetChipVersion(PortAddr, ushort);
2076 STATIC ushort    AscGetChipBusType(PortAddr);
2077 STATIC ASC_DCNT  AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
2078 STATIC int       AscFindSignature(PortAddr);
2079 STATIC void      AscToggleIRQAct(PortAddr);
2080 STATIC uchar     AscGetChipIRQ(PortAddr, ushort);
2081 STATIC uchar     AscSetChipIRQ(PortAddr, uchar, ushort);
2082 STATIC ushort    AscGetChipBiosAddress(PortAddr, ushort);
2083 STATIC inline ulong DvcEnterCritical(void);
2084 STATIC inline void DvcLeaveCritical(ulong);
2085 #ifdef CONFIG_PCI
2086 STATIC uchar     DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort);
2087 STATIC void      DvcWritePCIConfigByte(ASC_DVC_VAR *,
2088                     ushort, uchar);
2089 #endif /* CONFIG_PCI */
2090 STATIC ushort      AscGetChipBiosAddress(PortAddr, ushort);
2091 STATIC void      DvcSleepMilliSecond(ASC_DCNT);
2092 STATIC void      DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
2093 STATIC void      DvcPutScsiQ(PortAddr, ushort, uchar *, int);
2094 STATIC void      DvcGetQinfo(PortAddr, ushort, uchar *, int);
2095 STATIC ushort    AscInitGetConfig(ASC_DVC_VAR *);
2096 STATIC ushort    AscInitSetConfig(ASC_DVC_VAR *);
2097 STATIC ushort    AscInitAsc1000Driver(ASC_DVC_VAR *);
2098 STATIC void      AscAsyncFix(ASC_DVC_VAR *, uchar,
2099                     ASC_SCSI_INQUIRY *);
2100 STATIC int       AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
2101 STATIC void      AscInquiryHandling(ASC_DVC_VAR *,
2102                     uchar, ASC_SCSI_INQUIRY *);
2103 STATIC int       AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
2104 STATIC int       AscISR(ASC_DVC_VAR *);
2105 STATIC uint      AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar,
2106                     uchar);
2107 STATIC int       AscSgListToQueue(int);
2108 #ifdef CONFIG_ISA
2109 STATIC void      AscEnableIsaDma(uchar);
2110 #endif /* CONFIG_ISA */
2111 STATIC ASC_DCNT  AscGetMaxDmaCount(ushort);
2112 
2113 
2114 /*
2115  * --- Adv Library Constants and Macros
2116  */
2117 
2118 #define ADV_LIB_VERSION_MAJOR  5
2119 #define ADV_LIB_VERSION_MINOR  14
2120 
2121 /* d_os_dep.h */
2122 #define ADV_OS_LINUX
2123 
2124 /*
2125  * Define Adv Library required special types.
2126  */
2127 
2128 /*
2129  * Portable Data Types
2130  *
2131  * Any instance where a 32-bit long or pointer type is assumed
2132  * for precision or HW defined structures, the following define
2133  * types must be used. In Linux the char, short, and int types
2134  * are all consistent at 8, 16, and 32 bits respectively. Pointers
2135  * and long types are 64 bits on Alpha and UltraSPARC.
2136  */
2137 #define ADV_PADDR __u32         /* Physical address data type. */
2138 #define ADV_VADDR __u32         /* Virtual address data type. */
2139 #define ADV_DCNT  __u32         /* Unsigned Data count type. */
2140 #define ADV_SDCNT __s32         /* Signed Data count type. */
2141 
2142 /*
2143  * These macros are used to convert a virtual address to a
2144  * 32-bit value. This currently can be used on Linux Alpha
2145  * which uses 64-bit virtual address but a 32-bit bus address.
2146  * This is likely to break in the future, but doing this now
2147  * will give us time to change the HW and FW to handle 64-bit
2148  * addresses.
2149  */
2150 #define ADV_VADDR_TO_U32   virt_to_bus
2151 #define ADV_U32_TO_VADDR   bus_to_virt
2152 
2153 #define AdvPortAddr  ulong              /* Virtual memory address size */
2154 
2155 /*
2156  * Define Adv Library required memory access macros.
2157  */
2158 #define ADV_MEM_READB(addr) readb(addr)
2159 #define ADV_MEM_READW(addr) readw(addr)
2160 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
2161 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
2162 #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
2163 
2164 #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
2165 
2166 /*
2167  * For wide  boards a CDB length maximum of 16 bytes
2168  * is supported.
2169  */
2170 #define ADV_MAX_CDB_LEN     16
2171 
2172 /*
2173  * Define total number of simultaneous maximum element scatter-gather
2174  * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
2175  * maximum number of outstanding commands per wide host adapter. Each
2176  * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
2177  * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
2178  * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
2179  * structures or 255 scatter-gather elements.
2180  *
2181  */
2182 #define ADV_TOT_SG_BLOCK        ASC_DEF_MAX_HOST_QNG
2183 
2184 /*
2185  * Define Adv Library required maximum number of scatter-gather
2186  * elements per request.
2187  */
2188 #define ADV_MAX_SG_LIST         255
2189 
2190 /* Number of SG blocks needed. */
2191 #define ADV_NUM_SG_BLOCK \
2192     ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
2193 
2194 /* Total contiguous memory needed for SG blocks. */
2195 #define ADV_SG_TOTAL_MEM_SIZE \
2196     (sizeof(ADV_SG_BLOCK) *  ADV_NUM_SG_BLOCK)
2197 
2198 #define ADV_PAGE_SIZE PAGE_SIZE
2199 
2200 #define ADV_NUM_PAGE_CROSSING \
2201     ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2202 
2203 /* a_condor.h */
2204 #define ADV_PCI_VENDOR_ID               0x10CD
2205 #define ADV_PCI_DEVICE_ID_REV_A         0x2300
2206 #define ADV_PCI_DEVID_38C0800_REV1      0x2500
2207 #define ADV_PCI_DEVID_38C1600_REV1      0x2700
2208 
2209 #define ADV_EEP_DVC_CFG_BEGIN           (0x00)
2210 #define ADV_EEP_DVC_CFG_END             (0x15)
2211 #define ADV_EEP_DVC_CTL_BEGIN           (0x16)  /* location of OEM name */
2212 #define ADV_EEP_MAX_WORD_ADDR           (0x1E)
2213 
2214 #define ADV_EEP_DELAY_MS                100
2215 
2216 #define ADV_EEPROM_BIG_ENDIAN          0x8000   /* EEPROM Bit 15 */
2217 #define ADV_EEPROM_BIOS_ENABLE         0x4000   /* EEPROM Bit 14 */
2218 /*
2219  * For the ASC3550 Bit 13 is Termination Polarity control bit.
2220  * For later ICs Bit 13 controls whether the CIS (Card Information
2221  * Service Section) is loaded from EEPROM.
2222  */
2223 #define ADV_EEPROM_TERM_POL            0x2000   /* EEPROM Bit 13 */
2224 #define ADV_EEPROM_CIS_LD              0x2000   /* EEPROM Bit 13 */
2225 /*
2226  * ASC38C1600 Bit 11
2227  *
2228  * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
2229  * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
2230  * Function 0 will specify INT B.
2231  *
2232  * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
2233  * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
2234  * Function 1 will specify INT A.
2235  */
2236 #define ADV_EEPROM_INTAB               0x0800   /* EEPROM Bit 11 */
2237 
2238 typedef struct adveep_3550_config
2239 {
2240                                 /* Word Offset, Description */
2241 
2242   ushort cfg_lsw;               /* 00 power up initialization */
2243                                 /*  bit 13 set - Term Polarity Control */
2244                                 /*  bit 14 set - BIOS Enable */
2245                                 /*  bit 15 set - Big Endian Mode */
2246   ushort cfg_msw;               /* 01 unused      */
2247   ushort disc_enable;           /* 02 disconnect enable */
2248   ushort wdtr_able;             /* 03 Wide DTR able */
2249   ushort sdtr_able;             /* 04 Synchronous DTR able */
2250   ushort start_motor;           /* 05 send start up motor */
2251   ushort tagqng_able;           /* 06 tag queuing able */
2252   ushort bios_scan;             /* 07 BIOS device control */
2253   ushort scam_tolerant;         /* 08 no scam */
2254 
2255   uchar  adapter_scsi_id;       /* 09 Host Adapter ID */
2256   uchar  bios_boot_delay;       /*    power up wait */
2257 
2258   uchar  scsi_reset_delay;      /* 10 reset delay */
2259   uchar  bios_id_lun;           /*    first boot device scsi id & lun */
2260                                 /*    high nibble is lun */
2261                                 /*    low nibble is scsi id */
2262 
2263   uchar  termination;           /* 11 0 - automatic */
2264                                 /*    1 - low off / high off */
2265                                 /*    2 - low off / high on */
2266                                 /*    3 - low on  / high on */
2267                                 /*    There is no low on  / high off */
2268 
2269   uchar  reserved1;             /*    reserved byte (not used) */
2270 
2271   ushort bios_ctrl;             /* 12 BIOS control bits */
2272                                 /*  bit 0  BIOS don't act as initiator. */
2273                                 /*  bit 1  BIOS > 1 GB support */
2274                                 /*  bit 2  BIOS > 2 Disk Support */
2275                                 /*  bit 3  BIOS don't support removables */
2276                                 /*  bit 4  BIOS support bootable CD */
2277                                 /*  bit 5  BIOS scan enabled */
2278                                 /*  bit 6  BIOS support multiple LUNs */
2279                                 /*  bit 7  BIOS display of message */
2280                                 /*  bit 8  SCAM disabled */
2281                                 /*  bit 9  Reset SCSI bus during init. */
2282                                 /*  bit 10 */
2283                                 /*  bit 11 No verbose initialization. */
2284                                 /*  bit 12 SCSI parity enabled */
2285                                 /*  bit 13 */
2286                                 /*  bit 14 */
2287                                 /*  bit 15 */
2288   ushort  ultra_able;           /* 13 ULTRA speed able */
2289   ushort  reserved2;            /* 14 reserved */
2290   uchar   max_host_qng;         /* 15 maximum host queuing */
2291   uchar   max_dvc_qng;          /*    maximum per device queuing */
2292   ushort  dvc_cntl;             /* 16 control bit for driver */
2293   ushort  bug_fix;              /* 17 control bit for bug fix */
2294   ushort  serial_number_word1;  /* 18 Board serial number word 1 */
2295   ushort  serial_number_word2;  /* 19 Board serial number word 2 */
2296   ushort  serial_number_word3;  /* 20 Board serial number word 3 */
2297   ushort  check_sum;            /* 21 EEP check sum */
2298   uchar   oem_name[16];         /* 22 OEM name */
2299   ushort  dvc_err_code;         /* 30 last device driver error code */
2300   ushort  adv_err_code;         /* 31 last uc and Adv Lib error code */
2301   ushort  adv_err_addr;         /* 32 last uc error address */
2302   ushort  saved_dvc_err_code;   /* 33 saved last dev. driver error code   */
2303   ushort  saved_adv_err_code;   /* 34 saved last uc and Adv Lib error code */
2304   ushort  saved_adv_err_addr;   /* 35 saved last uc error address         */
2305   ushort  num_of_err;           /* 36 number of error */
2306 } ADVEEP_3550_CONFIG;
2307 
2308 typedef struct adveep_38C0800_config
2309 {
2310                                 /* Word Offset, Description */
2311 
2312   ushort cfg_lsw;               /* 00 power up initialization */
2313                                 /*  bit 13 set - Load CIS */
2314                                 /*  bit 14 set - BIOS Enable */
2315                                 /*  bit 15 set - Big Endian Mode */
2316   ushort cfg_msw;               /* 01 unused      */
2317   ushort disc_enable;           /* 02 disconnect enable */
2318   ushort wdtr_able;             /* 03 Wide DTR able */
2319   ushort sdtr_speed1;           /* 04 SDTR Speed TID 0-3 */
2320   ushort start_motor;           /* 05 send start up motor */
2321   ushort tagqng_able;           /* 06 tag queuing able */
2322   ushort bios_scan;             /* 07 BIOS device control */
2323   ushort scam_tolerant;         /* 08 no scam */
2324 
2325   uchar  adapter_scsi_id;       /* 09 Host Adapter ID */
2326   uchar  bios_boot_delay;       /*    power up wait */
2327 
2328   uchar  scsi_reset_delay;      /* 10 reset delay */
2329   uchar  bios_id_lun;           /*    first boot device scsi id & lun */
2330                                 /*    high nibble is lun */
2331                                 /*    low nibble is scsi id */
2332 
2333   uchar  termination_se;        /* 11 0 - automatic */
2334                                 /*    1 - low off / high off */
2335                                 /*    2 - low off / high on */
2336                                 /*    3 - low on  / high on */
2337                                 /*    There is no low on  / high off */
2338 
2339   uchar  termination_lvd;       /* 11 0 - automatic */
2340                                 /*    1 - low off / high off */
2341                                 /*    2 - low off / high on */
2342                                 /*    3 - low on  / high on */
2343                                 /*    There is no low on  / high off */
2344 
2345   ushort bios_ctrl;             /* 12 BIOS control bits */
2346                                 /*  bit 0  BIOS don't act as initiator. */
2347                                 /*  bit 1  BIOS > 1 GB support */
2348                                 /*  bit 2  BIOS > 2 Disk Support */
2349                                 /*  bit 3  BIOS don't support removables */
2350                                 /*  bit 4  BIOS support bootable CD */
2351                                 /*  bit 5  BIOS scan enabled */
2352                                 /*  bit 6  BIOS support multiple LUNs */
2353                                 /*  bit 7  BIOS display of message */
2354                                 /*  bit 8  SCAM disabled */
2355                                 /*  bit 9  Reset SCSI bus during init. */
2356                                 /*  bit 10 */
2357                                 /*  bit 11 No verbose initialization. */
2358                                 /*  bit 12 SCSI parity enabled */
2359                                 /*  bit 13 */
2360                                 /*  bit 14 */
2361                                 /*  bit 15 */
2362   ushort  sdtr_speed2;          /* 13 SDTR speed TID 4-7 */
2363   ushort  sdtr_speed3;          /* 14 SDTR speed TID 8-11 */
2364   uchar   max_host_qng;         /* 15 maximum host queueing */
2365   uchar   max_dvc_qng;          /*    maximum per device queuing */
2366   ushort  dvc_cntl;             /* 16 control bit for driver */
2367   ushort  sdtr_speed4;          /* 17 SDTR speed 4 TID 12-15 */
2368   ushort  serial_number_word1;  /* 18 Board serial number word 1 */
2369   ushort  serial_number_word2;  /* 19 Board serial number word 2 */
2370   ushort  serial_number_word3;  /* 20 Board serial number word 3 */
2371   ushort  check_sum;            /* 21 EEP check sum */
2372   uchar   oem_name[16];         /* 22 OEM name */
2373   ushort  dvc_err_code;         /* 30 last device driver error code */
2374   ushort  adv_err_code;         /* 31 last uc and Adv Lib error code */
2375   ushort  adv_err_addr;         /* 32 last uc error address */
2376   ushort  saved_dvc_err_code;   /* 33 saved last dev. driver error code   */
2377   ushort  saved_adv_err_code;   /* 34 saved last uc and Adv Lib error code */
2378   ushort  saved_adv_err_addr;   /* 35 saved last uc error address         */
2379   ushort  reserved36;           /* 36 reserved */
2380   ushort  reserved37;           /* 37 reserved */
2381   ushort  reserved38;           /* 38 reserved */
2382   ushort  reserved39;           /* 39 reserved */
2383   ushort  reserved40;           /* 40 reserved */
2384   ushort  reserved41;           /* 41 reserved */
2385   ushort  reserved42;           /* 42 reserved */
2386   ushort  reserved43;           /* 43 reserved */
2387   ushort  reserved44;           /* 44 reserved */
2388   ushort  reserved45;           /* 45 reserved */
2389   ushort  reserved46;           /* 46 reserved */
2390   ushort  reserved47;           /* 47 reserved */
2391   ushort  reserved48;           /* 48 reserved */
2392   ushort  reserved49;           /* 49 reserved */
2393   ushort  reserved50;           /* 50 reserved */
2394   ushort  reserved51;           /* 51 reserved */
2395   ushort  reserved52;           /* 52 reserved */
2396   ushort  reserved53;           /* 53 reserved */
2397   ushort  reserved54;           /* 54 reserved */
2398   ushort  reserved55;           /* 55 reserved */
2399   ushort  cisptr_lsw;           /* 56 CIS PTR LSW */
2400   ushort  cisprt_msw;           /* 57 CIS PTR MSW */
2401   ushort  subsysvid;            /* 58 SubSystem Vendor ID */
2402   ushort  subsysid;             /* 59 SubSystem ID */
2403   ushort  reserved60;           /* 60 reserved */
2404   ushort  reserved61;           /* 61 reserved */
2405   ushort  reserved62;           /* 62 reserved */
2406   ushort  reserved63;           /* 63 reserved */
2407 } ADVEEP_38C0800_CONFIG;
2408 
2409 typedef struct adveep_38C1600_config
2410 {
2411                                 /* Word Offset, Description */
2412 
2413   ushort cfg_lsw;               /* 00 power up initialization */
2414                                 /*  bit 11 set - Func. 0 INTB, Func. 1 INTA */
2415                                 /*       clear - Func. 0 INTA, Func. 1 INTB */
2416                                 /*  bit 13 set - Load CIS */
2417                                 /*  bit 14 set - BIOS Enable */
2418                                 /*  bit 15 set - Big Endian Mode */
2419   ushort cfg_msw;               /* 01 unused */
2420   ushort disc_enable;           /* 02 disconnect enable */
2421   ushort wdtr_able;             /* 03 Wide DTR able */
2422   ushort sdtr_speed1;           /* 04 SDTR Speed TID 0-3 */
2423   ushort start_motor;           /* 05 send start up motor */
2424   ushort tagqng_able;           /* 06 tag queuing able */
2425   ushort bios_scan;             /* 07 BIOS device control */
2426   ushort scam_tolerant;         /* 08 no scam */
2427 
2428   uchar  adapter_scsi_id;       /* 09 Host Adapter ID */
2429   uchar  bios_boot_delay;       /*    power up wait */
2430 
2431   uchar  scsi_reset_delay;      /* 10 reset delay */
2432   uchar  bios_id_lun;           /*    first boot device scsi id & lun */
2433                                 /*    high nibble is lun */
2434                                 /*    low nibble is scsi id */
2435 
2436   uchar  termination_se;        /* 11 0 - automatic */
2437                                 /*    1 - low off / high off */
2438                                 /*    2 - low off / high on */
2439                                 /*    3 - low on  / high on */
2440                                 /*    There is no low on  / high off */
2441 
2442   uchar  termination_lvd;       /* 11 0 - automatic */
2443                                 /*    1 - low off / high off */
2444                                 /*    2 - low off / high on */
2445                                 /*    3 - low on  / high on */
2446                                 /*    There is no low on  / high off */
2447 
2448   ushort bios_ctrl;             /* 12 BIOS control bits */
2449                                 /*  bit 0  BIOS don't act as initiator. */
2450                                 /*  bit 1  BIOS > 1 GB support */
2451                                 /*  bit 2  BIOS > 2 Disk Support */
2452                                 /*  bit 3  BIOS don't support removables */
2453                                 /*  bit 4  BIOS support bootable CD */
2454                                 /*  bit 5  BIOS scan enabled */
2455                                 /*  bit 6  BIOS support multiple LUNs */
2456                                 /*  bit 7  BIOS display of message */
2457                                 /*  bit 8  SCAM disabled */
2458                                 /*  bit 9  Reset SCSI bus during init. */
2459                                 /*  bit 10 Basic Integrity Checking disabled */
2460                                 /*  bit 11 No verbose initialization. */
2461                                 /*  bit 12 SCSI parity enabled */
2462                                 /*  bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
2463                                 /*  bit 14 */
2464                                 /*  bit 15 */
2465   ushort  sdtr_speed2;          /* 13 SDTR speed TID 4-7 */
2466   ushort  sdtr_speed3;          /* 14 SDTR speed TID 8-11 */
2467   uchar   max_host_qng;         /* 15 maximum host queueing */
2468   uchar   max_dvc_qng;          /*    maximum per device queuing */
2469   ushort  dvc_cntl;             /* 16 control bit for driver */
2470   ushort  sdtr_speed4;          /* 17 SDTR speed 4 TID 12-15 */
2471   ushort  serial_number_word1;  /* 18 Board serial number word 1 */
2472   ushort  serial_number_word2;  /* 19 Board serial number word 2 */
2473   ushort  serial_number_word3;  /* 20 Board serial number word 3 */
2474   ushort  check_sum;            /* 21 EEP check sum */
2475   uchar   oem_name[16];         /* 22 OEM name */
2476   ushort  dvc_err_code;         /* 30 last device driver error code */
2477   ushort  adv_err_code;         /* 31 last uc and Adv Lib error code */
2478   ushort  adv_err_addr;         /* 32 last uc error address */
2479   ushort  saved_dvc_err_code;   /* 33 saved last dev. driver error code   */
2480   ushort  saved_adv_err_code;   /* 34 saved last uc and Adv Lib error code */
2481   ushort  saved_adv_err_addr;   /* 35 saved last uc error address         */
2482   ushort  reserved36;           /* 36 reserved */
2483   ushort  reserved37;           /* 37 reserved */
2484   ushort  reserved38;           /* 38 reserved */
2485   ushort  reserved39;           /* 39 reserved */
2486   ushort  reserved40;           /* 40 reserved */
2487   ushort  reserved41;           /* 41 reserved */
2488   ushort  reserved42;           /* 42 reserved */
2489   ushort  reserved43;           /* 43 reserved */
2490   ushort  reserved44;           /* 44 reserved */
2491   ushort  reserved45;           /* 45 reserved */
2492   ushort  reserved46;           /* 46 reserved */
2493   ushort  reserved47;           /* 47 reserved */
2494   ushort  reserved48;           /* 48 reserved */
2495   ushort  reserved49;           /* 49 reserved */
2496   ushort  reserved50;           /* 50 reserved */
2497   ushort  reserved51;           /* 51 reserved */
2498   ushort  reserved52;           /* 52 reserved */
2499   ushort  reserved53;           /* 53 reserved */
2500   ushort  reserved54;           /* 54 reserved */
2501   ushort  reserved55;           /* 55 reserved */
2502   ushort  cisptr_lsw;           /* 56 CIS PTR LSW */
2503   ushort  cisprt_msw;           /* 57 CIS PTR MSW */
2504   ushort  subsysvid;            /* 58 SubSystem Vendor ID */
2505   ushort  subsysid;             /* 59 SubSystem ID */
2506   ushort  reserved60;           /* 60 reserved */
2507   ushort  reserved61;           /* 61 reserved */
2508   ushort  reserved62;           /* 62 reserved */
2509   ushort  reserved63;           /* 63 reserved */
2510 } ADVEEP_38C1600_CONFIG;
2511 
2512 /*
2513  * EEPROM Commands
2514  */
2515 #define ASC_EEP_CMD_DONE             0x0200
2516 #define ASC_EEP_CMD_DONE_ERR         0x0001
2517 
2518 /* cfg_word */
2519 #define EEP_CFG_WORD_BIG_ENDIAN      0x8000
2520 
2521 /* bios_ctrl */
2522 #define BIOS_CTRL_BIOS               0x0001
2523 #define BIOS_CTRL_EXTENDED_XLAT      0x0002
2524 #define BIOS_CTRL_GT_2_DISK          0x0004
2525 #define BIOS_CTRL_BIOS_REMOVABLE     0x0008
2526 #define BIOS_CTRL_BOOTABLE_CD        0x0010
2527 #define BIOS_CTRL_MULTIPLE_LUN       0x0040
2528 #define BIOS_CTRL_DISPLAY_MSG        0x0080
2529 #define BIOS_CTRL_NO_SCAM            0x0100
2530 #define BIOS_CTRL_RESET_SCSI_BUS     0x0200
2531 #define BIOS_CTRL_INIT_VERBOSE       0x0800
2532 #define BIOS_CTRL_SCSI_PARITY        0x1000
2533 #define BIOS_CTRL_AIPP_DIS           0x2000
2534 
2535 #define ADV_3550_MEMSIZE   0x2000       /* 8 KB Internal Memory */
2536 #define ADV_3550_IOLEN     0x40         /* I/O Port Range in bytes */
2537 
2538 #define ADV_38C0800_MEMSIZE  0x4000     /* 16 KB Internal Memory */
2539 #define ADV_38C0800_IOLEN    0x100      /* I/O Port Range in bytes */
2540 
2541 /*
2542  * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
2543  * a special 16K Adv Library and Microcode version. After the issue is
2544  * resolved, should restore 32K support.
2545  *
2546  * #define ADV_38C1600_MEMSIZE  0x8000L   * 32 KB Internal Memory *
2547  */
2548 #define ADV_38C1600_MEMSIZE  0x4000   /* 16 KB Internal Memory */
2549 #define ADV_38C1600_IOLEN    0x100     /* I/O Port Range 256 bytes */
2550 #define ADV_38C1600_MEMLEN   0x1000    /* Memory Range 4KB bytes */
2551 
2552 /*
2553  * Byte I/O register address from base of 'iop_base'.
2554  */
2555 #define IOPB_INTR_STATUS_REG    0x00
2556 #define IOPB_CHIP_ID_1          0x01
2557 #define IOPB_INTR_ENABLES       0x02
2558 #define IOPB_CHIP_TYPE_REV      0x03
2559 #define IOPB_RES_ADDR_4         0x04
2560 #define IOPB_RES_ADDR_5         0x05
2561 #define IOPB_RAM_DATA           0x06
2562 #define IOPB_RES_ADDR_7         0x07
2563 #define IOPB_FLAG_REG           0x08
2564 #define IOPB_RES_ADDR_9         0x09
2565 #define IOPB_RISC_CSR           0x0A
2566 #define IOPB_RES_ADDR_B         0x0B
2567 #define IOPB_RES_ADDR_C         0x0C
2568 #define IOPB_RES_ADDR_D         0x0D
2569 #define IOPB_SOFT_OVER_WR       0x0E
2570 #define IOPB_RES_ADDR_F         0x0F
2571 #define IOPB_MEM_CFG            0x10
2572 #define IOPB_RES_ADDR_11        0x11
2573 #define IOPB_GPIO_DATA          0x12
2574 #define IOPB_RES_ADDR_13        0x13
2575 #define IOPB_FLASH_PAGE         0x14
2576 #define IOPB_RES_ADDR_15        0x15
2577 #define IOPB_GPIO_CNTL          0x16
2578 #define IOPB_RES_ADDR_17        0x17
2579 #define IOPB_FLASH_DATA         0x18
2580 #define IOPB_RES_ADDR_19        0x19
2581 #define IOPB_RES_ADDR_1A        0x1A
2582 #define IOPB_RES_ADDR_1B        0x1B
2583 #define IOPB_RES_ADDR_1C        0x1C
2584 #define IOPB_RES_ADDR_1D        0x1D
2585 #define IOPB_RES_ADDR_1E        0x1E
2586 #define IOPB_RES_ADDR_1F        0x1F
2587 #define IOPB_DMA_CFG0           0x20
2588 #define IOPB_DMA_CFG1           0x21
2589 #define IOPB_TICKLE             0x22
2590 #define IOPB_DMA_REG_WR         0x23
2591 #define IOPB_SDMA_STATUS        0x24
2592 #define IOPB_SCSI_BYTE_CNT      0x25
2593 #define IOPB_HOST_BYTE_CNT      0x26
2594 #define IOPB_BYTE_LEFT_TO_XFER  0x27
2595 #define IOPB_BYTE_TO_XFER_0     0x28
2596 #define IOPB_BYTE_TO_XFER_1     0x29
2597 #define IOPB_BYTE_TO_XFER_2     0x2A
2598 #define IOPB_BYTE_TO_XFER_3     0x2B
2599 #define IOPB_ACC_GRP            0x2C
2600 #define IOPB_RES_ADDR_2D        0x2D
2601 #define IOPB_DEV_ID             0x2E
2602 #define IOPB_RES_ADDR_2F        0x2F
2603 #define IOPB_SCSI_DATA          0x30
2604 #define IOPB_RES_ADDR_31        0x31
2605 #define IOPB_RES_ADDR_32        0x32
2606 #define IOPB_SCSI_DATA_HSHK     0x33
2607 #define IOPB_SCSI_CTRL          0x34
2608 #define IOPB_RES_ADDR_35        0x35
2609 #define IOPB_RES_ADDR_36        0x36
2610 #define IOPB_RES_ADDR_37        0x37
2611 #define IOPB_RAM_BIST           0x38
2612 #define IOPB_PLL_TEST           0x39
2613 #define IOPB_PCI_INT_CFG        0x3A
2614 #define IOPB_RES_ADDR_3B        0x3B
2615 #define IOPB_RFIFO_CNT          0x3C
2616 #define IOPB_RES_ADDR_3D        0x3D
2617 #define IOPB_RES_ADDR_3E        0x3E
2618 #define IOPB_RES_ADDR_3F        0x3F
2619 
2620 /*
2621  * Word I/O register address from base of 'iop_base'.
2622  */
2623 #define IOPW_CHIP_ID_0          0x00  /* CID0  */
2624 #define IOPW_CTRL_REG           0x02  /* CC    */
2625 #define IOPW_RAM_ADDR           0x04  /* LA    */
2626 #define IOPW_RAM_DATA           0x06  /* LD    */
2627 #define IOPW_RES_ADDR_08        0x08
2628 #define IOPW_RISC_CSR           0x0A  /* CSR   */
2629 #define IOPW_SCSI_CFG0          0x0C  /* CFG0  */
2630 #define IOPW_SCSI_CFG1          0x0E  /* CFG1  */
2631 #define IOPW_RES_ADDR_10        0x10
2632 #define IOPW_SEL_MASK           0x12  /* SM    */
2633 #define IOPW_RES_ADDR_14        0x14
2634 #define IOPW_FLASH_ADDR         0x16  /* FA    */
2635 #define IOPW_RES_ADDR_18        0x18
2636 #define IOPW_EE_CMD             0x1A  /* EC    */
2637 #define IOPW_EE_DATA            0x1C  /* ED    */
2638 #define IOPW_SFIFO_CNT          0x1E  /* SFC   */
2639 #define IOPW_RES_ADDR_20        0x20
2640 #define IOPW_Q_BASE             0x22  /* QB    */
2641 #define IOPW_QP                 0x24  /* QP    */
2642 #define IOPW_IX                 0x26  /* IX    */
2643 #define IOPW_SP                 0x28  /* SP    */
2644 #define IOPW_PC                 0x2A  /* PC    */
2645 #define IOPW_RES_ADDR_2C        0x2C
2646 #define IOPW_RES_ADDR_2E        0x2E
2647 #define IOPW_SCSI_DATA          0x30  /* SD    */
2648 #define IOPW_SCSI_DATA_HSHK     0x32  /* SDH   */
2649 #define IOPW_SCSI_CTRL          0x34  /* SC    */
2650 #define IOPW_HSHK_CFG           0x36  /* HCFG  */
2651 #define IOPW_SXFR_STATUS        0x36  /* SXS   */
2652 #define IOPW_SXFR_CNTL          0x38  /* SXL   */
2653 #define IOPW_SXFR_CNTH          0x3A  /* SXH   */
2654 #define IOPW_RES_ADDR_3C        0x3C
2655 #define IOPW_RFIFO_DATA         0x3E  /* RFD   */
2656 
2657 /*
2658  * Doubleword I/O register address from base of 'iop_base'.
2659  */
2660 #define IOPDW_RES_ADDR_0         0x00
2661 #define IOPDW_RAM_DATA           0x04
2662 #define IOPDW_RES_ADDR_8         0x08
2663 #define IOPDW_RES_ADDR_C         0x0C
2664 #define IOPDW_RES_ADDR_10        0x10
2665 #define IOPDW_COMMA              0x14
2666 #define IOPDW_COMMB              0x18
2667 #define IOPDW_RES_ADDR_1C        0x1C
2668 #define IOPDW_SDMA_ADDR0         0x20
2669 #define IOPDW_SDMA_ADDR1         0x24
2670 #define IOPDW_SDMA_COUNT         0x28
2671 #define IOPDW_SDMA_ERROR         0x2C
2672 #define IOPDW_RDMA_ADDR0         0x30
2673 #define IOPDW_RDMA_ADDR1         0x34
2674 #define IOPDW_RDMA_COUNT         0x38
2675 #define IOPDW_RDMA_ERROR         0x3C
2676 
2677 #define ADV_CHIP_ID_BYTE         0x25
2678 #define ADV_CHIP_ID_WORD         0x04C1
2679 
2680 #define ADV_SC_SCSI_BUS_RESET    0x2000
2681 
2682 #define ADV_INTR_ENABLE_HOST_INTR                   0x01
2683 #define ADV_INTR_ENABLE_SEL_INTR                    0x02
2684 #define ADV_INTR_ENABLE_DPR_INTR                    0x04
2685 #define ADV_INTR_ENABLE_RTA_INTR                    0x08
2686 #define ADV_INTR_ENABLE_RMA_INTR                    0x10
2687 #define ADV_INTR_ENABLE_RST_INTR                    0x20
2688 #define ADV_INTR_ENABLE_DPE_INTR                    0x40
2689 #define ADV_INTR_ENABLE_GLOBAL_INTR                 0x80
2690 
2691 #define ADV_INTR_STATUS_INTRA            0x01
2692 #define ADV_INTR_STATUS_INTRB            0x02
2693 #define ADV_INTR_STATUS_INTRC            0x04
2694 
2695 #define ADV_RISC_CSR_STOP           (0x0000)
2696 #define ADV_RISC_TEST_COND          (0x2000)
2697 #define ADV_RISC_CSR_RUN            (0x4000)
2698 #define ADV_RISC_CSR_SINGLE_STEP    (0x8000)
2699 
2700 #define ADV_CTRL_REG_HOST_INTR      0x0100
2701 #define ADV_CTRL_REG_SEL_INTR       0x0200
2702 #define ADV_CTRL_REG_DPR_INTR       0x0400
2703 #define ADV_CTRL_REG_RTA_INTR       0x0800
2704 #define ADV_CTRL_REG_RMA_INTR       0x1000
2705 #define ADV_CTRL_REG_RES_BIT14      0x2000
2706 #define ADV_CTRL_REG_DPE_INTR       0x4000
2707 #define ADV_CTRL_REG_POWER_DONE     0x8000
2708 #define ADV_CTRL_REG_ANY_INTR       0xFF00
2709 
2710 #define ADV_CTRL_REG_CMD_RESET             0x00C6
2711 #define ADV_CTRL_REG_CMD_WR_IO_REG         0x00C5
2712 #define ADV_CTRL_REG_CMD_RD_IO_REG         0x00C4
2713 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE  0x00C3
2714 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE  0x00C2
2715 
2716 #define ADV_TICKLE_NOP                      0x00
2717 #define ADV_TICKLE_A                        0x01
2718 #define ADV_TICKLE_B                        0x02
2719 #define ADV_TICKLE_C                        0x03
2720 
2721 #define ADV_SCSI_CTRL_RSTOUT        0x2000
2722 
2723 #define AdvIsIntPending(port) \
2724     (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2725 
2726 /*
2727  * SCSI_CFG0 Register bit definitions
2728  */
2729 #define TIMER_MODEAB    0xC000  /* Watchdog, Second, and Select. Timer Ctrl. */
2730 #define PARITY_EN       0x2000  /* Enable SCSI Parity Error detection */
2731 #define EVEN_PARITY     0x1000  /* Select Even Parity */
2732 #define WD_LONG         0x0800  /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2733 #define QUEUE_128       0x0400  /* Queue Size, 1: 128 byte, 0: 64 byte */
2734 #define PRIM_MODE       0x0100  /* Primitive SCSI mode */
2735 #define SCAM_EN         0x0080  /* Enable SCAM selection */
2736 #define SEL_TMO_LONG    0x0040  /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2737 #define CFRM_ID         0x0020  /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2738 #define OUR_ID_EN       0x0010  /* Enable OUR_ID bits */
2739 #define OUR_ID          0x000F  /* SCSI ID */
2740 
2741 /*
2742  * SCSI_CFG1 Register bit definitions
2743  */
2744 #define BIG_ENDIAN      0x8000  /* Enable Big Endian Mode MIO:15, EEP:15 */
2745 #define TERM_POL        0x2000  /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2746 #define SLEW_RATE       0x1000  /* SCSI output buffer slew rate */
2747 #define FILTER_SEL      0x0C00  /* Filter Period Selection */
2748 #define  FLTR_DISABLE    0x0000  /* Input Filtering Disabled */
2749 #define  FLTR_11_TO_20NS 0x0800  /* Input Filtering 11ns to 20ns */
2750 #define  FLTR_21_TO_39NS 0x0C00  /* Input Filtering 21ns to 39ns */
2751 #define ACTIVE_DBL      0x0200  /* Disable Active Negation */
2752 #define DIFF_MODE       0x0100  /* SCSI differential Mode (Read-Only) */
2753 #define DIFF_SENSE      0x0080  /* 1: No SE cables, 0: SE cable (Read-Only) */
2754 #define TERM_CTL_SEL    0x0040  /* Enable TERM_CTL_H and TERM_CTL_L */
2755 #define TERM_CTL        0x0030  /* External SCSI Termination Bits */
2756 #define  TERM_CTL_H      0x0020  /* Enable External SCSI Upper Termination */
2757 #define  TERM_CTL_L      0x0010  /* Enable External SCSI Lower Termination */
2758 #define CABLE_DETECT    0x000F  /* External SCSI Cable Connection Status */
2759 
2760 /*
2761  * Addendum for ASC-38C0800 Chip
2762  *
2763  * The ASC-38C1600 Chip uses the same definitions except that the
2764  * bus mode override bits [12:10] have been moved to byte register
2765  * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
2766  * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
2767  * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
2768  * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
2769  * and [1:0]. Bits [14], [7:6], [3:2] are unused.
2770  */
2771 #define DIS_TERM_DRV    0x4000  /* 1: Read c_det[3:0], 0: cannot read */
2772 #define HVD_LVD_SE      0x1C00  /* Device Detect Bits */
2773 #define  HVD             0x1000  /* HVD Device Detect */
2774 #define  LVD             0x0800  /* LVD Device Detect */
2775 #define  SE              0x0400  /* SE Device Detect */
2776 #define TERM_LVD        0x00C0  /* LVD Termination Bits */
2777 #define  TERM_LVD_HI     0x0080  /* Enable LVD Upper Termination */
2778 #define  TERM_LVD_LO     0x0040  /* Enable LVD Lower Termination */
2779 #define TERM_SE         0x0030  /* SE Termination Bits */
2780 #define  TERM_SE_HI      0x0020  /* Enable SE Upper Termination */
2781 #define  TERM_SE_LO      0x0010  /* Enable SE Lower Termination */
2782 #define C_DET_LVD       0x000C  /* LVD Cable Detect Bits */
2783 #define  C_DET3          0x0008  /* Cable Detect for LVD External Wide */
2784 #define  C_DET2          0x0004  /* Cable Detect for LVD Internal Wide */
2785 #define C_DET_SE        0x0003  /* SE Cable Detect Bits */
2786 #define  C_DET1          0x0002  /* Cable Detect for SE Internal Wide */
2787 #define  C_DET0          0x0001  /* Cable Detect for SE Internal Narrow */
2788 
2789 
2790 #define CABLE_ILLEGAL_A 0x7
2791     /* x 0 0 0  | on  on | Illegal (all 3 connectors are used) */
2792 
2793 #define CABLE_ILLEGAL_B 0xB
2794     /* 0 x 0 0  | on  on | Illegal (all 3 connectors are used) */
2795 
2796 /*
2797  * MEM_CFG Register bit definitions
2798  */
2799 #define BIOS_EN         0x40    /* BIOS Enable MIO:14,EEP:14 */
2800 #define FAST_EE_CLK     0x20    /* Diagnostic Bit */
2801 #define RAM_SZ          0x1C    /* Specify size of RAM to RISC */
2802 #define  RAM_SZ_2KB      0x00    /* 2 KB */
2803 #define  RAM_SZ_4KB      0x04    /* 4 KB */
2804 #define  RAM_SZ_8KB      0x08    /* 8 KB */
2805 #define  RAM_SZ_16KB     0x0C    /* 16 KB */
2806 #define  RAM_SZ_32KB     0x10    /* 32 KB */
2807 #define  RAM_SZ_64KB     0x14    /* 64 KB */
2808 
2809 /*
2810  * DMA_CFG0 Register bit definitions
2811  *
2812  * This register is only accessible to the host.
2813  */
2814 #define BC_THRESH_ENB   0x80    /* PCI DMA Start Conditions */
2815 #define FIFO_THRESH     0x70    /* PCI DMA FIFO Threshold */
2816 #define  FIFO_THRESH_16B  0x00   /* 16 bytes */
2817 #define  FIFO_THRESH_32B  0x20   /* 32 bytes */
2818 #define  FIFO_THRESH_48B  0x30   /* 48 bytes */
2819 #define  FIFO_THRESH_64B  0x40   /* 64 bytes */
2820 #define  FIFO_THRESH_80B  0x50   /* 80 bytes (default) */
2821 #define  FIFO_THRESH_96B  0x60   /* 96 bytes */
2822 #define  FIFO_THRESH_112B 0x70   /* 112 bytes */
2823 #define START_CTL       0x0C    /* DMA start conditions */
2824 #define  START_CTL_TH    0x00    /* Wait threshold level (default) */
2825 #define  START_CTL_ID    0x04    /* Wait SDMA/SBUS idle */
2826 #define  START_CTL_THID  0x08    /* Wait threshold and SDMA/SBUS idle */
2827 #define  START_CTL_EMFU  0x0C    /* Wait SDMA FIFO empty/full */
2828 #define READ_CMD        0x03    /* Memory Read Method */
2829 #define  READ_CMD_MR     0x00    /* Memory Read */
2830 #define  READ_CMD_MRL    0x02    /* Memory Read Long */
2831 #define  READ_CMD_MRM    0x03    /* Memory Read Multiple (default) */
2832 
2833 /*
2834  * ASC-38C0800 RAM BIST Register bit definitions
2835  */
2836 #define RAM_TEST_MODE         0x80
2837 #define PRE_TEST_MODE         0x40
2838 #define NORMAL_MODE           0x00
2839 #define RAM_TEST_DONE         0x10
2840 #define RAM_TEST_STATUS       0x0F
2841 #define  RAM_TEST_HOST_ERROR   0x08
2842 #define  RAM_TEST_INTRAM_ERROR 0x04
2843 #define  RAM_TEST_RISC_ERROR   0x02
2844 #define  RAM_TEST_SCSI_ERROR   0x01
2845 #define  RAM_TEST_SUCCESS      0x00
2846 #define PRE_TEST_VALUE        0x05
2847 #define NORMAL_VALUE          0x00
2848 
2849 /*
2850  * ASC38C1600 Definitions
2851  *
2852  * IOPB_PCI_INT_CFG Bit Field Definitions
2853  */
2854 
2855 #define INTAB_LD        0x80    /* Value loaded from EEPROM Bit 11. */
2856 
2857 /*
2858  * Bit 1 can be set to change the interrupt for the Function to operate in
2859  * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
2860  * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
2861  * mode, otherwise the operating mode is undefined.
2862  */
2863 #define TOTEMPOLE       0x02
2864 
2865 /*
2866  * Bit 0 can be used to change the Int Pin for the Function. The value is
2867  * 0 by default for both Functions with Function 0 using INT A and Function
2868  * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
2869  * INT A is used.
2870  *
2871  * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
2872  * value specified in the PCI Configuration Space.
2873  */
2874 #define INTAB           0x01
2875 
2876 /* a_advlib.h */
2877 
2878 /*
2879  * Adv Library Status Definitions
2880  */
2881 #define ADV_TRUE        1
2882 #define ADV_FALSE       0
2883 #define ADV_NOERROR     1
2884 #define ADV_SUCCESS     1
2885 #define ADV_BUSY        0
2886 #define ADV_ERROR       (-1)
2887 
2888 
2889 /*
2890  * ADV_DVC_VAR 'warn_code' values
2891  */
2892 #define ASC_WARN_BUSRESET_ERROR         0x0001 /* SCSI Bus Reset error */
2893 #define ASC_WARN_EEPROM_CHKSUM          0x0002 /* EEP check sum error */
2894 #define ASC_WARN_EEPROM_TERMINATION     0x0004 /* EEP termination bad field */
2895 #define ASC_WARN_SET_PCI_CONFIG_SPACE   0x0080 /* PCI config space set error */
2896 #define ASC_WARN_ERROR                  0xFFFF /* ADV_ERROR return */
2897 
2898 #define ADV_MAX_TID                     15 /* max. target identifier */
2899 #define ADV_MAX_LUN                     7  /* max. logical unit number */
2900 
2901 /*
2902  * Error code values are set in ADV_DVC_VAR 'err_code'.
2903  */
2904 #define ASC_IERR_WRITE_EEPROM       0x0001 /* write EEPROM error */
2905 #define ASC_IERR_MCODE_CHKSUM       0x0002 /* micro code check sum error */
2906 #define ASC_IERR_NO_CARRIER         0x0004 /* No more carrier memory. */
2907 #define ASC_IERR_START_STOP_CHIP    0x0008 /* start/stop chip failed */
2908 #define ASC_IERR_CHIP_VERSION       0x0040 /* wrong chip version */
2909 #define ASC_IERR_SET_SCSI_ID        0x0080 /* set SCSI ID failed */
2910 #define ASC_IERR_HVD_DEVICE         0x0100 /* HVD attached to LVD connector. */
2911 #define ASC_IERR_BAD_SIGNATURE      0x0200 /* signature not found */
2912 #define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
2913 #define ASC_IERR_SINGLE_END_DEVICE  0x0800 /* Single-end used w/differential */
2914 #define ASC_IERR_REVERSED_CABLE     0x1000 /* Narrow flat cable reversed */
2915 #define ASC_IERR_BIST_PRE_TEST      0x2000 /* BIST pre-test error */
2916 #define ASC_IERR_BIST_RAM_TEST      0x4000 /* BIST RAM test error */
2917 #define ASC_IERR_BAD_CHIPTYPE       0x8000 /* Invalid 'chip_type' setting. */
2918 
2919 /*
2920  * Fixed locations of microcode operating variables.
2921  */
2922 #define ASC_MC_CODE_BEGIN_ADDR          0x0028 /* microcode start address */
2923 #define ASC_MC_CODE_END_ADDR            0x002A /* microcode end address */
2924 #define ASC_MC_CODE_CHK_SUM             0x002C /* microcode code checksum */
2925 #define ASC_MC_VERSION_DATE             0x0038 /* microcode version */
2926 #define ASC_MC_VERSION_NUM              0x003A /* microcode number */
2927 #define ASC_MC_BIOSMEM                  0x0040 /* BIOS RISC Memory Start */
2928 #define ASC_MC_BIOSLEN                  0x0050 /* BIOS RISC Memory Length */
2929 #define ASC_MC_BIOS_SIGNATURE           0x0058 /* BIOS Signature 0x55AA */
2930 #define ASC_MC_BIOS_VERSION             0x005A /* BIOS Version (2 bytes) */
2931 #define ASC_MC_SDTR_SPEED1              0x0090 /* SDTR Speed for TID 0-3 */
2932 #define ASC_MC_SDTR_SPEED2              0x0092 /* SDTR Speed for TID 4-7 */
2933 #define ASC_MC_SDTR_SPEED3              0x0094 /* SDTR Speed for TID 8-11 */
2934 #define ASC_MC_SDTR_SPEED4              0x0096 /* SDTR Speed for TID 12-15 */
2935 #define ASC_MC_CHIP_TYPE                0x009A
2936 #define ASC_MC_INTRB_CODE               0x009B
2937 #define ASC_MC_WDTR_ABLE                0x009C
2938 #define ASC_MC_SDTR_ABLE                0x009E
2939 #define ASC_MC_TAGQNG_ABLE              0x00A0
2940 #define ASC_MC_DISC_ENABLE              0x00A2
2941 #define ASC_MC_IDLE_CMD_STATUS          0x00A4
2942 #define ASC_MC_IDLE_CMD                 0x00A6
2943 #define ASC_MC_IDLE_CMD_PARAMETER       0x00A8
2944 #define ASC_MC_DEFAULT_SCSI_CFG0        0x00AC
2945 #define ASC_MC_DEFAULT_SCSI_CFG1        0x00AE
2946 #define ASC_MC_DEFAULT_MEM_CFG          0x00B0
2947 #define ASC_MC_DEFAULT_SEL_MASK         0x00B2
2948 #define ASC_MC_SDTR_DONE                0x00B6
2949 #define ASC_MC_NUMBER_OF_QUEUED_CMD     0x00C0
2950 #define ASC_MC_NUMBER_OF_MAX_CMD        0x00D0
2951 #define ASC_MC_DEVICE_HSHK_CFG_TABLE    0x0100
2952 #define ASC_MC_CONTROL_FLAG             0x0122 /* Microcode control flag. */
2953 #define ASC_MC_WDTR_DONE                0x0124
2954 #define ASC_MC_CAM_MODE_MASK            0x015E /* CAM mode TID bitmask. */
2955 #define ASC_MC_ICQ                      0x0160
2956 #define ASC_MC_IRQ                      0x0164
2957 #define ASC_MC_PPR_ABLE                 0x017A
2958 
2959 /*
2960  * BIOS LRAM variable absolute offsets.
2961  */
2962 #define BIOS_CODESEG    0x54
2963 #define BIOS_CODELEN    0x56
2964 #define BIOS_SIGNATURE  0x58
2965 #define BIOS_VERSION    0x5A
2966 
2967 /*
2968  * Microcode Control Flags
2969  *
2970  * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2971  * and handled by the microcode.
2972  */
2973 #define CONTROL_FLAG_IGNORE_PERR        0x0001 /* Ignore DMA Parity Errors */
2974 #define CONTROL_FLAG_ENABLE_AIPP        0x0002 /* Enabled AIPP checking. */
2975 
2976 /*
2977  * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2978  */
2979 #define HSHK_CFG_WIDE_XFR       0x8000
2980 #define HSHK_CFG_RATE           0x0F00
2981 #define HSHK_CFG_OFFSET         0x001F
2982 
2983 #define ASC_DEF_MAX_HOST_QNG    0xFD /* Max. number of host commands (253) */
2984 #define ASC_DEF_MIN_HOST_QNG    0x10 /* Min. number of host commands (16) */
2985 #define ASC_DEF_MAX_DVC_QNG     0x3F /* Max. number commands per device (63) */
2986 #define ASC_DEF_MIN_DVC_QNG     0x04 /* Min. number commands per device (4) */
2987 
2988 #define ASC_QC_DATA_CHECK  0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2989 #define ASC_QC_DATA_OUT    0x02 /* Data out DMA transfer. */
2990 #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2991 #define ASC_QC_NO_OVERRUN  0x08 /* Don't report overrun. */
2992 #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2993 
2994 #define ASC_QSC_NO_DISC     0x01 /* Don't allow disconnect for request. */
2995 #define ASC_QSC_NO_TAGMSG   0x02 /* Don't allow tag queuing for request. */
2996 #define ASC_QSC_NO_SYNC     0x04 /* Don't use Synch. transfer on request. */
2997 #define ASC_QSC_NO_WIDE     0x08 /* Don't use Wide transfer on request. */
2998 #define ASC_QSC_REDO_DTR    0x10 /* Renegotiate WDTR/SDTR before request. */
2999 /*
3000  * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
3001  * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
3002  */
3003 #define ASC_QSC_HEAD_TAG    0x40 /* Use Head Tag Message (0x21). */
3004 #define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
3005 
3006 /*
3007  * All fields here are accessed by the board microcode and need to be
3008  * little-endian.
3009  */
3010 typedef struct adv_carr_t
3011 {
3012     ADV_VADDR   carr_va;       /* Carrier Virtual Address */
3013     ADV_PADDR   carr_pa;       /* Carrier Physical Address */
3014     ADV_VADDR   areq_vpa;      /* ASC_SCSI_REQ_Q Virtual or Physical Address */
3015     /*
3016      * next_vpa [31:4]            Carrier Virtual or Physical Next Pointer
3017      *
3018      * next_vpa [3:1]             Reserved Bits
3019      * next_vpa [0]               Done Flag set in Response Queue.
3020      */
3021     ADV_VADDR   next_vpa;
3022 } ADV_CARR_T;
3023 
3024 /*
3025  * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
3026  */
3027 #define ASC_NEXT_VPA_MASK       0xFFFFFFF0
3028 
3029 #define ASC_RQ_DONE             0x00000001
3030 #define ASC_RQ_GOOD             0x00000002
3031 #define ASC_CQ_STOPPER          0x00000000
3032 
3033 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
3034 
3035 #define ADV_CARRIER_NUM_PAGE_CROSSING \
3036     (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
3037         (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
3038 
3039 #define ADV_CARRIER_BUFSIZE \
3040     ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
3041 
3042 /*
3043  * ASC_SCSI_REQ_Q 'a_flag' definitions
3044  *
3045  * The Adv Library should limit use to the lower nibble (4 bits) of
3046  * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
3047  */
3048 #define ADV_POLL_REQUEST                0x01   /* poll for request completion */
3049 #define ADV_SCSIQ_DONE                  0x02   /* request done */
3050 #define ADV_DONT_RETRY                  0x08   /* don't do retry */
3051 
3052 #define ADV_CHIP_ASC3550          0x01   /* Ultra-Wide IC */
3053 #define ADV_CHIP_ASC38C0800       0x02   /* Ultra2-Wide/LVD IC */
3054 #define ADV_CHIP_ASC38C1600       0x03   /* Ultra3-Wide/LVD2 IC */
3055 
3056 /*
3057  * Adapter temporary configuration structure
3058  *
3059  * This structure can be discarded after initialization. Don't add
3060  * fields here needed after initialization.
3061  *
3062  * Field naming convention:
3063  *
3064  *  *_enable indicates the field enables or disables a feature. The
3065  *  value of the field is never reset.
3066  */
3067 typedef struct adv_dvc_cfg {
3068   ushort disc_enable;       /* enable disconnection */
3069   uchar  chip_version;      /* chip version */
3070   uchar  termination;       /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
3071   ushort pci_device_id;     /* PCI device code number */
3072   ushort lib_version;       /* Adv Library version number */
3073   ushort control_flag;      /* Microcode Control Flag */
3074   ushort mcode_date;        /* Microcode date */
3075   ushort mcode_version;     /* Microcode version */
3076   ushort pci_slot_info;     /* high byte device/function number */
3077                             /* bits 7-3 device num., bits 2-0 function num. */
3078                             /* low byte bus num. */
3079   ushort serial1;           /* EEPROM serial number word 1 */
3080   ushort serial2;           /* EEPROM serial number word 2 */
3081   ushort serial3;           /* EEPROM serial number word 3 */
3082 } ADV_DVC_CFG;
3083 
3084 struct adv_dvc_var;
3085 struct adv_scsi_req_q;
3086 
3087 typedef void (* ADV_ISR_CALLBACK)
3088     (struct adv_dvc_var *, struct adv_scsi_req_q *);
3089 
3090 typedef void (* ADV_ASYNC_CALLBACK)
3091     (struct adv_dvc_var *, uchar);
3092 
3093 /*
3094  * Adapter operation variable structure.
3095  *
3096  * One structure is required per host adapter.
3097  *
3098  * Field naming convention:
3099  *
3100  *  *_able indicates both whether a feature should be enabled or disabled
3101  *  and whether a device isi capable of the feature. At initialization
3102  *  this field may be set, but later if a device is found to be incapable
3103  *  of the feature, the field is cleared.
3104  */
3105 typedef struct adv_dvc_var {
3106   AdvPortAddr iop_base;   /* I/O port address */
3107   ushort err_code;        /* fatal error code */
3108   ushort bios_ctrl;       /* BIOS control word, EEPROM word 12 */
3109   ADV_ISR_CALLBACK isr_callback;
3110   ADV_ASYNC_CALLBACK async_callback;
3111   ushort wdtr_able;       /* try WDTR for a device */
3112   ushort sdtr_able;       /* try SDTR for a device */
3113   ushort ultra_able;      /* try SDTR Ultra speed for a device */
3114   ushort sdtr_speed1;     /* EEPROM SDTR Speed for TID 0-3   */
3115   ushort sdtr_speed2;     /* EEPROM SDTR Speed for TID 4-7   */
3116   ushort sdtr_speed3;     /* EEPROM SDTR Speed for TID 8-11  */
3117   ushort sdtr_speed4;     /* EEPROM SDTR Speed for TID 12-15 */
3118   ushort tagqng_able;     /* try tagged queuing with a device */
3119   ushort ppr_able;        /* PPR message capable per TID bitmask. */
3120   uchar  max_dvc_qng;     /* maximum number of tagged commands per device */
3121   ushort start_motor;     /* start motor command allowed */
3122   uchar  scsi_reset_wait; /* delay in seconds after scsi bus reset */
3123   uchar  chip_no;         /* should be assigned by caller */
3124   uchar  max_host_qng;    /* maximum number of Q'ed command allowed */
3125   uchar  irq_no;          /* IRQ number */
3126   ushort no_scam;         /* scam_tolerant of EEPROM */
3127   struct asc_board *drv_ptr; /* driver pointer to private structure */
3128   uchar  chip_scsi_id;    /* chip SCSI target ID */
3129   uchar  chip_type;
3130   uchar  bist_err_code;
3131   ADV_CARR_T *carrier_buf;
3132   ADV_CARR_T *carr_freelist; /* Carrier free list. */
3133   ADV_CARR_T *icq_sp;  /* Initiator command queue stopper pointer. */
3134   ADV_CARR_T *irq_sp;  /* Initiator response queue stopper pointer. */
3135   ushort carr_pending_cnt;    /* Count of pending carriers. */
3136  /*
3137   * Note: The following fields will not be used after initialization. The
3138   * driver may discard the buffer after initialization is done.
3139   */
3140   ADV_DVC_CFG *cfg; /* temporary configuration structure  */
3141 } ADV_DVC_VAR;
3142 
3143 #define NO_OF_SG_PER_BLOCK              15
3144 
3145 typedef struct asc_sg_block {
3146     uchar reserved1;
3147     uchar reserved2;
3148     uchar reserved3;
3149     uchar sg_cnt;                     /* Valid entries in block. */
3150     ADV_PADDR sg_ptr;                 /* Pointer to next sg block. */
3151     struct  {
3152         ADV_PADDR sg_addr;                  /* SG element address. */
3153         ADV_DCNT  sg_count;                 /* SG element count. */
3154     } sg_list[NO_OF_SG_PER_BLOCK];
3155 } ADV_SG_BLOCK;
3156 
3157 /*
3158  * ADV_SCSI_REQ_Q - microcode request structure
3159  *
3160  * All fields in this structure up to byte 60 are used by the microcode.
3161  * The microcode makes assumptions about the size and ordering of fields
3162  * in this structure. Do not change the structure definition here without
3163  * coordinating the change with the microcode.
3164  *
3165  * All fields accessed by microcode must be maintained in little_endian
3166  * order.
3167  */
3168 typedef struct adv_scsi_req_q {
3169     uchar       cntl;           /* Ucode flags and state (ASC_MC_QC_*). */
3170     uchar       target_cmd;
3171     uchar       target_id;      /* Device target identifier. */
3172     uchar       target_lun;     /* Device target logical unit number. */
3173     ADV_PADDR   data_addr;      /* Data buffer physical address. */
3174     ADV_DCNT    data_cnt;       /* Data count. Ucode sets to residual. */
3175     ADV_PADDR   sense_addr;
3176     ADV_PADDR   carr_pa;
3177     uchar       mflag;
3178     uchar       sense_len;
3179     uchar       cdb_len;        /* SCSI CDB length. Must <= 16 bytes. */
3180     uchar       scsi_cntl;
3181     uchar       done_status;    /* Completion status. */
3182     uchar       scsi_status;    /* SCSI status byte. */
3183     uchar       host_status;    /* Ucode host status. */
3184     uchar       sg_working_ix;
3185     uchar       cdb[12];        /* SCSI CDB bytes 0-11. */
3186     ADV_PADDR   sg_real_addr;   /* SG list physical address. */
3187     ADV_PADDR   scsiq_rptr;
3188     uchar       cdb16[4];       /* SCSI CDB bytes 12-15. */
3189     ADV_VADDR   scsiq_ptr;
3190     ADV_VADDR   carr_va;
3191     /*
3192      * End of microcode structure - 60 bytes. The rest of the structure
3193      * is used by the Adv Library and ignored by the microcode.
3194      */
3195     ADV_VADDR   srb_ptr;
3196     ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
3197     char        *vdata_addr;   /* Data buffer virtual address. */
3198     uchar       a_flag;
3199     uchar       pad[2];        /* Pad out to a word boundary. */
3200 } ADV_SCSI_REQ_Q;
3201 
3202 /*
3203  * Microcode idle loop commands
3204  */
3205 #define IDLE_CMD_COMPLETED           0
3206 #define IDLE_CMD_STOP_CHIP           0x0001
3207 #define IDLE_CMD_STOP_CHIP_SEND_INT  0x0002
3208 #define IDLE_CMD_SEND_INT            0x0004
3209 #define IDLE_CMD_ABORT               0x0008
3210 #define IDLE_CMD_DEVICE_RESET        0x0010
3211 #define IDLE_CMD_SCSI_RESET_START    0x0020 /* Assert SCSI Bus Reset */
3212 #define IDLE_CMD_SCSI_RESET_END      0x0040 /* Deassert SCSI Bus Reset */
3213 #define IDLE_CMD_SCSIREQ             0x0080
3214 
3215 #define IDLE_CMD_STATUS_SUCCESS      0x0001
3216 #define IDLE_CMD_STATUS_FAILURE      0x0002
3217 
3218 /*
3219  * AdvSendIdleCmd() flag definitions.
3220  */
3221 #define ADV_NOWAIT     0x01
3222 
3223 /*
3224  * Wait loop time out values.
3225  */
3226 #define SCSI_WAIT_10_SEC             10UL    /* 10 seconds */
3227 #define SCSI_WAIT_100_MSEC           100UL   /* 100 milliseconds */
3228 #define SCSI_US_PER_MSEC             1000    /* microseconds per millisecond */
3229 #define SCSI_MS_PER_SEC              1000UL  /* milliseconds per second */
3230 #define SCSI_MAX_RETRY               10      /* retry count */
3231 
3232 #define ADV_ASYNC_RDMA_FAILURE          0x01 /* Fatal RDMA failure. */
3233 #define ADV_ASYNC_SCSI_BUS_RESET_DET    0x02 /* Detected SCSI Bus Reset. */
3234 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
3235 #define ADV_RDMA_IN_CARR_AND_Q_INVALID  0x04 /* RDMAed-in data invalid. */
3236 
3237 
3238 #define ADV_HOST_SCSI_BUS_RESET      0x80 /* Host Initiated SCSI Bus Reset. */
3239 
3240 /*
3241  * Device drivers must define the following functions.
3242  */
3243 STATIC inline ulong DvcEnterCritical(void);
3244 STATIC inline void  DvcLeaveCritical(ulong);
3245 STATIC void  DvcSleepMilliSecond(ADV_DCNT);
3246 STATIC uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
3247 STATIC void  DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
3248 STATIC ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
3249                 uchar *, ASC_SDCNT *, int);
3250 STATIC void  DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
3251 
3252 /*
3253  * Adv Library functions available to drivers.
3254  */
3255 STATIC int     AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3256 STATIC int     AdvISR(ADV_DVC_VAR *);
3257 STATIC int     AdvInitGetConfig(ADV_DVC_VAR *);
3258 STATIC int     AdvInitAsc3550Driver(ADV_DVC_VAR *);
3259 STATIC int     AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
3260 STATIC int     AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
3261 STATIC int     AdvResetChipAndSB(ADV_DVC_VAR *);
3262 STATIC int     AdvResetSB(ADV_DVC_VAR *asc_dvc);
3263 
3264 /*
3265  * Internal Adv Library functions.
3266  */
3267 STATIC int    AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
3268 STATIC void   AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3269 STATIC int    AdvInitFrom3550EEP(ADV_DVC_VAR *);
3270 STATIC int    AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
3271 STATIC int    AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
3272 STATIC ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3273 STATIC void   AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3274 STATIC ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3275 STATIC void   AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3276 STATIC ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3277 STATIC void   AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3278 STATIC void   AdvWaitEEPCmd(AdvPortAddr);
3279 STATIC ushort AdvReadEEPWord(AdvPortAddr, int);
3280 
3281 /*
3282  * PCI Bus Definitions
3283  */
3284 #define AscPCICmdRegBits_BusMastering     0x0007
3285 #define AscPCICmdRegBits_ParErrRespCtrl   0x0040
3286 
3287 /* Read byte from a register. */
3288 #define AdvReadByteRegister(iop_base, reg_off) \
3289      (ADV_MEM_READB((iop_base) + (reg_off)))
3290 
3291 /* Write byte to a register. */
3292 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
3293      (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3294 
3295 /* Read word (2 bytes) from a register. */
3296 #define AdvReadWordRegister(iop_base, reg_off) \
3297      (ADV_MEM_READW((iop_base) + (reg_off)))
3298 
3299 /* Write word (2 bytes) to a register. */
3300 #define AdvWriteWordRegister(iop_base, reg_off, word) \
3301      (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
3302 
3303 /* Write dword (4 bytes) to a register. */
3304 #define AdvWriteDWordRegister(iop_base, reg_off, dword) \
3305      (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
3306 
3307 /* Read byte from LRAM. */
3308 #define AdvReadByteLram(iop_base, addr, byte) \
3309 do { \
3310     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3311     (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3312 } while (0)
3313 
3314 /* Write byte to LRAM. */
3315 #define AdvWriteByteLram(iop_base, addr, byte) \
3316     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3317      ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3318 
3319 /* Read word (2 bytes) from LRAM. */
3320 #define AdvReadWordLram(iop_base, addr, word) \
3321 do { \
3322     ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3323     (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3324 } while (0)
3325 
3326 /* Write word (2 bytes) to LRAM. */
3327 #define AdvWriteWordLram(iop_base, addr, word) \
3328     (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3329      ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3330 
3331 /* Write little-endian double word (4 bytes) to LRAM */
3332 /* Because of unspecified C language ordering don't use auto-increment. */
3333 #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
3334     ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3335       ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3336                      cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3337      (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3338       ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3339                      cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3340 
3341 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
3342 #define AdvReadWordAutoIncLram(iop_base) \
3343      (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3344 
3345 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
3346 #define AdvWriteWordAutoIncLram(iop_base, word) \
3347      (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3348 
3349 
3350 /*
3351  * Define macro to check for Condor signature.
3352  *
3353  * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3354  * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3355  */
3356 #define AdvFindSignature(iop_base) \
3357     (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3358     ADV_CHIP_ID_BYTE) && \
3359      (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3360     ADV_CHIP_ID_WORD)) ?  ADV_TRUE : ADV_FALSE)
3361 
3362 /*
3363  * Define macro to Return the version number of the chip at 'iop_base'.
3364  *
3365  * The second parameter 'bus_type' is currently unused.
3366  */
3367 #define AdvGetChipVersion(iop_base, bus_type) \
3368     AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3369 
3370 /*
3371  * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3372  * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3373  *
3374  * If the request has not yet been sent to the device it will simply be
3375  * aborted from RISC memory. If the request is disconnected it will be
3376  * aborted on reselection by sending an Abort Message to the target ID.
3377  *
3378  * Return value:
3379  *      ADV_TRUE(1) - Queue was successfully aborted.
3380  *      ADV_FALSE(0) - Queue was not found on the active queue list.
3381  */
3382 #define AdvAbortQueue(asc_dvc, scsiq) \
3383         AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3384                        (ADV_DCNT) (scsiq))
3385 
3386 /*
3387  * Send a Bus Device Reset Message to the specified target ID.
3388  *
3389  * All outstanding commands will be purged if sending the
3390  * Bus Device Reset Message is successful.
3391  *
3392  * Return Value:
3393  *      ADV_TRUE(1) - All requests on the target are purged.
3394  *      ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3395  *                     are not purged.
3396  */
3397 #define AdvResetDevice(asc_dvc, target_id) \
3398         AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3399                     (ADV_DCNT) (target_id))
3400 
3401 /*
3402  * SCSI Wide Type definition.
3403  */
3404 #define ADV_SCSI_BIT_ID_TYPE   ushort
3405 
3406 /*
3407  * AdvInitScsiTarget() 'cntl_flag' options.
3408  */
3409 #define ADV_SCAN_LUN           0x01
3410 #define ADV_CAPINFO_NOLUN      0x02
3411 
3412 /*
3413  * Convert target id to target id bit mask.
3414  */
3415 #define ADV_TID_TO_TIDMASK(tid)   (0x01 << ((tid) & ADV_MAX_TID))
3416 
3417 /*
3418  * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3419  */
3420 
3421 #define QD_NO_STATUS         0x00       /* Request not completed yet. */
3422 #define QD_NO_ERROR          0x01
3423 #define QD_ABORTED_BY_HOST   0x02
3424 #define QD_WITH_ERROR        0x04
3425 
3426 #define QHSTA_NO_ERROR              0x00
3427 #define QHSTA_M_SEL_TIMEOUT         0x11
3428 #define QHSTA_M_DATA_OVER_RUN       0x12
3429 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3430 #define QHSTA_M_QUEUE_ABORTED       0x15
3431 #define QHSTA_M_SXFR_SDMA_ERR       0x16 /* SXFR_STATUS SCSI DMA Error */
3432 #define QHSTA_M_SXFR_SXFR_PERR      0x17 /* SXFR_STATUS SCSI Bus Parity Error */
3433 #define QHSTA_M_RDMA_PERR           0x18 /* RISC PCI DMA parity error */
3434 #define QHSTA_M_SXFR_OFF_UFLW       0x19 /* SXFR_STATUS Offset Underflow */
3435 #define QHSTA_M_SXFR_OFF_OFLW       0x20 /* SXFR_STATUS Offset Overflow */
3436 #define QHSTA_M_SXFR_WD_TMO         0x21 /* SXFR_STATUS Watchdog Timeout */
3437 #define QHSTA_M_SXFR_DESELECTED     0x22 /* SXFR_STATUS Deselected */
3438 /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
3439 #define QHSTA_M_SXFR_XFR_OFLW       0x12 /* SXFR_STATUS Transfer Overflow */
3440 #define QHSTA_M_SXFR_XFR_PH_ERR     0x24 /* SXFR_STATUS Transfer Phase Error */
3441 #define QHSTA_M_SXFR_UNKNOWN_ERROR  0x25 /* SXFR_STATUS Unknown Error */
3442 #define QHSTA_M_SCSI_BUS_RESET      0x30 /* Request aborted from SBR */
3443 #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
3444 #define QHSTA_M_BUS_DEVICE_RESET    0x32 /* Request aborted from BDR */
3445 #define QHSTA_M_DIRECTION_ERR       0x35 /* Data Phase mismatch */
3446 #define QHSTA_M_DIRECTION_ERR_HUNG  0x36 /* Data Phase mismatch and bus hang */
3447 #define QHSTA_M_WTM_TIMEOUT         0x41
3448 #define QHSTA_M_BAD_CMPL_STATUS_IN  0x42
3449 #define QHSTA_M_NO_AUTO_REQ_SENSE   0x43
3450 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
3451 #define QHSTA_M_INVALID_DEVICE      0x45 /* Bad target ID */
3452 #define QHSTA_M_FROZEN_TIDQ         0x46 /* TID Queue frozen. */
3453 #define QHSTA_M_SGBACKUP_ERROR      0x47 /* Scatter-Gather backup error */
3454 
3455 
3456 /*
3457  * Default EEPROM Configuration structure defined in a_init.c.
3458  */
3459 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
3460 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
3461 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
3462 
3463 /*
3464  * DvcGetPhyAddr() flag arguments
3465  */
3466 #define ADV_IS_SCSIQ_FLAG       0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
3467 #define ADV_ASCGETSGLIST_VADDR  0x02 /* 'addr' is AscGetSGList() virtual addr */
3468 #define ADV_IS_SENSE_FLAG       0x04 /* 'addr' is sense virtual pointer */
3469 #define ADV_IS_DATA_FLAG        0x08 /* 'addr' is data virtual pointer */
3470 #define ADV_IS_SGLIST_FLAG      0x10 /* 'addr' is sglist virtual pointer */
3471 #define ADV_IS_CARRIER_FLAG     0x20 /* 'addr' is ADV_CARR_T pointer */
3472 
3473 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
3474 #define ADV_8BALIGN(addr)      (((ulong) (addr) + 0x7) & ~0x7)
3475 #define ADV_16BALIGN(addr)     (((ulong) (addr) + 0xF) & ~0xF)
3476 #define ADV_32BALIGN(addr)     (((ulong) (addr) + 0x1F) & ~0x1F)
3477 
3478 /*
3479  * Total contiguous memory needed for driver SG blocks.
3480  *
3481  * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3482  * number of scatter-gather elements the driver supports in a
3483  * single request.
3484  */
3485 
3486 #define ADV_SG_LIST_MAX_BYTE_SIZE \
3487          (sizeof(ADV_SG_BLOCK) * \
3488           ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3489 
3490 /*
3491  * Inquiry data structure and bitfield macros
3492  *
3493  * Using bitfields to access the subchar data isn't portable across
3494  * endianness, so instead mask and shift. Only quantities of more
3495  * than 1 bit are shifted, since the others are just tested for true
3496  * or false.
3497  */
3498 
3499 #define ADV_INQ_DVC_TYPE(inq)       ((inq)->periph & 0x1f)
3500 #define ADV_INQ_QUALIFIER(inq)      (((inq)->periph & 0xe0) >> 5)
3501 #define ADV_INQ_DVC_TYPE_MOD(inq)   ((inq)->devtype & 0x7f)
3502 #define ADV_INQ_REMOVABLE(inq)      ((inq)->devtype & 0x80)
3503 #define ADV_INQ_ANSI_VER(inq)       ((inq)->ver & 0x07)
3504 #define ADV_INQ_ECMA_VER(inq)       (((inq)->ver & 0x38) >> 3)
3505 #define ADV_INQ_ISO_VER(inq)        (((inq)->ver & 0xc0) >> 6)
3506 #define ADV_INQ_RESPONSE_FMT(inq)   ((inq)->byte3 & 0x0f)
3507 #define ADV_INQ_TERM_IO(inq)        ((inq)->byte3 & 0x40)
3508 #define ADV_INQ_ASYNC_NOTIF(inq)    ((inq)->byte3 & 0x80)
3509 #define ADV_INQ_SOFT_RESET(inq)     ((inq)->flags & 0x01)
3510 #define ADV_INQ_CMD_QUEUE(inq)      ((inq)->flags & 0x02)
3511 #define ADV_INQ_LINK_CMD(inq)       ((inq)->flags & 0x08)
3512 #define ADV_INQ_SYNC(inq)           ((inq)->flags & 0x10)
3513 #define ADV_INQ_WIDE16(inq)         ((inq)->flags & 0x20)
3514 #define ADV_INQ_WIDE32(inq)         ((inq)->flags & 0x40)
3515 #define ADV_INQ_REL_ADDR(inq)       ((inq)->flags & 0x80)
3516 #define ADV_INQ_INFO_UNIT(inq)      ((inq)->info & 0x01)
3517 #define ADV_INQ_QUICK_ARB(inq)      ((inq)->info & 0x02)
3518 #define ADV_INQ_CLOCKING(inq)       (((inq)->info & 0x0c) >> 2)
3519 
3520 typedef struct {
3521   uchar periph;                 /* peripheral device type [0:4] */
3522                                 /* peripheral qualifier [5:7] */
3523   uchar devtype;                /* device type modifier (for SCSI I) [0:6] */
3524                                 /* RMB - removable medium bit [7] */
3525   uchar ver;                    /* ANSI approved version [0:2] */
3526                                 /* ECMA version [3:5] */
3527                                 /* ISO version [6:7] */
3528   uchar byte3;                  /* response data format [0:3] */
3529                                 /* 0 SCSI 1 */
3530                                 /* 1 CCS */
3531                                 /* 2 SCSI-2 */
3532                                 /* 3-F reserved */
3533                                 /* reserved [4:5] */
3534                                 /* terminate I/O process bit (see 5.6.22) [6] */
3535                                 /* asynch. event notification (processor) [7] */
3536   uchar add_len;                /* additional length */
3537   uchar res1;                   /* reserved */
3538   uchar res2;                   /* reserved */
3539   uchar flags;                  /* soft reset implemented [0] */
3540                                 /* command queuing [1] */
3541                                 /* reserved [2] */
3542                                 /* linked command for this logical unit [3] */
3543                                 /* synchronous data transfer [4] */
3544                                 /* wide bus 16 bit data transfer [5] */
3545                                 /* wide bus 32 bit data transfer [6] */
3546                                 /* relative addressing mode [7] */
3547   uchar vendor_id[8];           /* vendor identification */
3548   uchar product_id[16];         /* product identification */
3549   uchar product_rev_level[4];   /* product revision level */
3550   uchar vendor_specific[20];    /* vendor specific */
3551   uchar info;                   /* information unit supported [0] */
3552                                 /* quick arbitrate supported [1] */
3553                                 /* clocking field [2:3] */
3554                                 /* reserved [4:7] */
3555   uchar res3;                   /* reserved */
3556 } ADV_SCSI_INQUIRY; /* 58 bytes */
3557 
3558 
3559 /*
3560  * --- Driver Constants and Macros
3561  */
3562 
3563 #define ASC_NUM_BOARD_SUPPORTED 16
3564 #define ASC_NUM_IOPORT_PROBE    4
3565 #define ASC_NUM_BUS             4
3566 
3567 /* Reference Scsi_Host hostdata */
3568 #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3569 
3570 /* asc_board_t flags */
3571 #define ASC_HOST_IN_RESET       0x01
3572 #define ASC_IS_WIDE_BOARD       0x04    /* AdvanSys Wide Board */
3573 #define ASC_SELECT_QUEUE_DEPTHS 0x08
3574 
3575 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3576 #define ASC_WIDE_BOARD(boardp)   ((boardp)->flags & ASC_IS_WIDE_BOARD)
3577 
3578 #define NO_ISA_DMA              0xff        /* No ISA DMA Channel Used */
3579 
3580 /*
3581  * If the Linux kernel version supports freeing initialization code
3582  * and data after loading, define macros for this purpose. These macros
3583  * are not used when the driver is built as a module, cf. linux/init.h.
3584  */
3585 #if ASC_LINUX_KERNEL24
3586 #define ASC_INITFUNC(type, func)        type __init func
3587 #elif ASC_LINUX_KERNEL22
3588 #define ASC_INITFUNC(type, func)        __initfunc(type func)
3589 #endif
3590 #define ASC_INITDATA                    __initdata
3591 #define ASC_INIT                        __init
3592 
3593 #define ASC_INFO_SIZE           128            /* advansys_info() line size */
3594 
3595 #ifdef CONFIG_PROC_FS
3596 /* /proc/scsi/advansys/[0...] related definitions */
3597 #define ASC_PRTBUF_SIZE         2048
3598 #define ASC_PRTLINE_SIZE        160
3599 
3600 #define ASC_PRT_NEXT() \
3601     if (cp) { \
3602         totlen += len; \
3603         leftlen -= len; \
3604         if (leftlen == 0) { \
3605             return totlen; \
3606         } \
3607         cp += len; \
3608     }
3609 
3610 #define ASC_MIN(a, b) (((a) < (b)) ? (a) : (b))
3611 #endif /* CONFIG_PROC_FS */
3612 
3613 /*
3614  * XXX - Release and acquire the io_request_lock. These macros are needed
3615  * because the 2.4 kernel SCSI mid-level driver holds the 'io_request_lock'
3616  * on entry to SCSI low-level drivers.
3617  *
3618  * These definitions and all code that uses code should be removed when the
3619  * SCSI mid-level driver no longer holds the 'io_request_lock' on entry to
3620  * SCSI low-level driver detect, queuecommand, and reset entrypoints.
3621  *
3622  * The interrupt flags values doesn't matter in the macros because the
3623  * SCSI mid-level will save and restore the flags values before and after
3624  * calling advansys_detect, advansys_queuecommand, and advansys_reset where
3625  * these macros are used. We do want interrupts enabled after the lock is
3626  * released so an explicit sti() is done. The driver only needs interrupts
3627  * disabled when it acquires the per board lock.
3628  */
3629 #define ASC_UNLOCK_IO_REQUEST_LOCK \
3630     { \
3631         ulong flags; /* flags value not needed, cf. comment above. */ \
3632         save_flags(flags); \
3633         spin_unlock_irqrestore(&io_request_lock, flags); \
3634         sti(); /* enable interrupts */ \
3635     }
3636 
3637 #define ASC_LOCK_IO_REQUEST_LOCK \
3638     { \
3639         ulong flags; /* flags value not needed, cf. comment above. */ \
3640         spin_lock_irqsave(&io_request_lock, flags); \
3641     }
3642 
3643 /* Asc Library return codes */
3644 #define ASC_TRUE        1
3645 #define ASC_FALSE       0
3646 #define ASC_NOERROR     1
3647 #define ASC_BUSY        0
3648 #define ASC_ERROR       (-1)
3649 
3650 /* Scsi_Cmnd function return codes */
3651 #define STATUS_BYTE(byte)   (byte)
3652 #define MSG_BYTE(byte)      ((byte) << 8)
3653 #define HOST_BYTE(byte)     ((byte) << 16)
3654 #define DRIVER_BYTE(byte)   ((byte) << 24)
3655 
3656 /*
3657  * The following definitions and macros are OS independent interfaces to
3658  * the queue functions:
3659  *  REQ - SCSI request structure
3660  *  REQP - pointer to SCSI request structure
3661  *  REQPTID(reqp) - reqp's target id
3662  *  REQPNEXT(reqp) - reqp's next pointer
3663  *  REQPNEXTP(reqp) - pointer to reqp's next pointer
3664  *  REQPTIME(reqp) - reqp's time stamp value
3665  *  REQTIMESTAMP() - system time stamp value
3666  */
3667 typedef Scsi_Cmnd            REQ, *REQP;
3668 #define REQPNEXT(reqp)       ((REQP) ((reqp)->host_scribble))
3669 #define REQPNEXTP(reqp)      ((REQP *) &((reqp)->host_scribble))
3670 #define REQPTID(reqp)        ((reqp)->target)
3671 #define REQPTIME(reqp)       ((reqp)->SCp.this_residual)
3672 #define REQTIMESTAMP()       (jiffies)
3673 
3674 #define REQTIMESTAT(function, ascq, reqp, tid) \
3675 { \
3676     /*
3677      * If the request time stamp is less than the system time stamp, then \
3678      * maybe the system time stamp wrapped. Set the request time to zero.\
3679      */ \
3680     if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3681         REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3682     } else { \
3683         /* Indicate an error occurred with the assertion. */ \
3684         ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3685         REQPTIME(reqp) = 0; \
3686     } \
3687     /* Handle first minimum time case without external initialization. */ \
3688     if (((ascq)->q_tot_cnt[tid] == 1) ||  \
3689         (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3690             (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3691             ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3692                 (function), (tid), (ascq)->q_min_tim[tid]); \
3693         } \
3694     if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3695         (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3696         ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3697             (function), tid, (ascq)->q_max_tim[tid]); \
3698     } \
3699     (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3700     /* Reset the time stamp field. */ \
3701     REQPTIME(reqp) = 0; \
3702 }
3703 
3704 /* asc_enqueue() flags */
3705 #define ASC_FRONT       1
3706 #define ASC_BACK        2
3707 
3708 /* asc_dequeue_list() argument */
3709 #define ASC_TID_ALL        (-1)
3710 
3711 /* Return non-zero, if the queue is empty. */
3712 #define ASC_QUEUE_EMPTY(ascq)    ((ascq)->q_tidmask == 0)
3713 
3714 /* PCI configuration declarations */
3715 
3716 #define PCI_BASE_CLASS_PREDEFINED               0x00
3717 #define PCI_BASE_CLASS_MASS_STORAGE             0x01
3718 #define PCI_BASE_CLASS_NETWORK                  0x02
3719 #define PCI_BASE_CLASS_DISPLAY                  0x03
3720 #define PCI_BASE_CLASS_MULTIMEDIA               0x04
3721 #define PCI_BASE_CLASS_MEMORY_CONTROLLER        0x05
3722 #define PCI_BASE_CLASS_BRIDGE_DEVICE            0x06
3723 
3724 /* MASS STORAGE */
3725 #define PCI_SUB_CLASS_SCSI_CONTROLLER           0x00
3726 #define PCI_SUB_CLASS_IDE_CONTROLLER            0x01
3727 #define PCI_SUB_CLASS_FLOPPY_DISK_CONTROLLER    0x02
3728 #define PCI_SUB_CLASS_IPI_BUS_CONTROLLER        0x03
3729 #define PCI_SUB_CLASS_OTHER_MASS_CONTROLLER     0x80
3730 
3731 /* NETWORK CONTROLLER */
3732 #define PCI_SUB_CLASS_ETHERNET_CONTROLLER       0x00
3733 #define PCI_SUB_CLASS_TOKEN_RING_CONTROLLER     0x01
3734 #define PCI_SUB_CLASS_FDDI_CONTROLLER           0x02
3735 #define PCI_SUB_CLASS_OTHER_NETWORK_CONTROLLER  0x80
3736 
3737 /* DISPLAY CONTROLLER */
3738 #define PCI_SUB_CLASS_VGA_CONTROLLER            0x00
3739 #define PCI_SUB_CLASS_XGA_CONTROLLER            0x01
3740 #define PCI_SUB_CLASS_OTHER_DISPLAY_CONTROLLER  0x80
3741 
3742 /* MULTIMEDIA CONTROLLER */
3743 #define PCI_SUB_CLASS_VIDEO_DEVICE              0x00
3744 #define PCI_SUB_CLASS_AUDIO_DEVICE              0x01
3745 #define PCI_SUB_CLASS_OTHER_MULTIMEDIA_DEVICE   0x80
3746 
3747 /* MEMORY CONTROLLER */
3748 #define PCI_SUB_CLASS_RAM_CONTROLLER            0x00
3749 #define PCI_SUB_CLASS_FLASH_CONTROLLER          0x01
3750 #define PCI_SUB_CLASS_OTHER_MEMORY_CONTROLLER   0x80
3751 
3752 /* BRIDGE CONTROLLER */
3753 #define PCI_SUB_CLASS_HOST_BRIDGE_CONTROLLER    0x00
3754 #define PCI_SUB_CLASS_ISA_BRIDGE_CONTROLLER     0x01
3755 #define PCI_SUB_CLASS_EISA_BRIDGE_CONTROLLER    0x02
3756 #define PCI_SUB_CLASS_MC_BRIDGE_CONTROLLER      0x03
3757 #define PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER    0x04
3758 #define PCI_SUB_CLASS_PCMCIA_BRIDGE_CONTROLLER  0x05
3759 #define PCI_SUB_CLASS_OTHER_BRIDGE_CONTROLLER   0x80
3760 
3761 #define PCI_MAX_SLOT            0x1F
3762 #define PCI_MAX_BUS             0xFF
3763 #define PCI_IOADDRESS_MASK      0xFFFE
3764 #define ASC_PCI_VENDORID        0x10CD
3765 #define ASC_PCI_DEVICE_ID_CNT   6       /* PCI Device ID count. */
3766 #define ASC_PCI_DEVICE_ID_1100  0x1100
3767 #define ASC_PCI_DEVICE_ID_1200  0x1200
3768 #define ASC_PCI_DEVICE_ID_1300  0x1300
3769 #define ASC_PCI_DEVICE_ID_2300  0x2300  /* ASC-3550 */
3770 #define ASC_PCI_DEVICE_ID_2500  0x2500  /* ASC-38C0800 */
3771 #define ASC_PCI_DEVICE_ID_2700  0x2700  /* ASC-38C1600 */
3772 
3773 /* PCI IO Port Addresses to generate special cycle */
3774 
3775 #define PCI_CONFIG_ADDRESS_MECH1          0x0CF8
3776 #define PCI_CONFIG_DATA_MECH1             0x0CFC
3777 
3778 #define PCI_CONFIG_FORWARD_REGISTER       0x0CFA    /* 0=type 0; 1=type 1; */
3779 
3780 #define PCI_CONFIG_BUS_NUMBER_MASK        0x00FF0000
3781 #define PCI_CONFIG_DEVICE_FUNCTION_MASK   0x0000FF00
3782 #define PCI_CONFIG_REGISTER_NUMBER_MASK   0x000000F8
3783 
3784 #define PCI_DEVICE_FOUND                0x0000
3785 #define PCI_DEVICE_NOT_FOUND            0xffff
3786 
3787 #define SUBCLASS_OFFSET         0x0A
3788 #define CLASSCODE_OFFSET        0x0B
3789 #define VENDORID_OFFSET         0x00
3790 #define DEVICEID_OFFSET         0x02
3791 
3792 #ifndef ADVANSYS_STATS
3793 #define ASC_STATS(shp, counter)
3794 #define ASC_STATS_ADD(shp, counter, count)
3795 #else /* ADVANSYS_STATS */
3796 #define ASC_STATS(shp, counter) \
3797     (ASC_BOARDP(shp)->asc_stats.counter++)
3798 
3799 #define ASC_STATS_ADD(shp, counter, count) \
3800     (ASC_BOARDP(shp)->asc_stats.counter += (count))
3801 #endif /* ADVANSYS_STATS */
3802 
3803 #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3804 
3805 /* If the result wraps when calculating tenths, return 0. */
3806 #define ASC_TENTHS(num, den) \
3807     (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3808     0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3809 
3810 /*
3811  * Display a message to the console.
3812  */
3813 #define ASC_PRINT(s) \
3814     { \
3815         printk("advansys: "); \
3816         printk(s); \
3817     }
3818 
3819 #define ASC_PRINT1(s, a1) \
3820     { \
3821         printk("advansys: "); \
3822         printk((s), (a1)); \
3823     }
3824 
3825 #define ASC_PRINT2(s, a1, a2) \
3826     { \
3827         printk("advansys: "); \
3828         printk((s), (a1), (a2)); \
3829     }
3830 
3831 #define ASC_PRINT3(s, a1, a2, a3) \
3832     { \
3833         printk("advansys: "); \
3834         printk((s), (a1), (a2), (a3)); \
3835     }
3836 
3837 #define ASC_PRINT4(s, a1, a2, a3, a4) \
3838     { \
3839         printk("advansys: "); \
3840         printk((s), (a1), (a2), (a3), (a4)); \
3841     }
3842 
3843 
3844 #ifndef ADVANSYS_DEBUG
3845 
3846 #define ASC_DBG(lvl, s)
3847 #define ASC_DBG1(lvl, s, a1)
3848 #define ASC_DBG2(lvl, s, a1, a2)
3849 #define ASC_DBG3(lvl, s, a1, a2, a3)
3850 #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3851 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3852 #define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3853 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3854 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3855 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3856 #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3857 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
3858 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
3859 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
3860 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3861 
3862 #else /* ADVANSYS_DEBUG */
3863 
3864 /*
3865  * Debugging Message Levels:
3866  * 0: Errors Only
3867  * 1: High-Level Tracing
3868  * 2-N: Verbose Tracing
3869  */
3870 
3871 #define ASC_DBG(lvl, s) \
3872     { \
3873         if (asc_dbglvl >= (lvl)) { \
3874             printk(s); \
3875         } \
3876     }
3877 
3878 #define ASC_DBG1(lvl, s, a1) \
3879     { \
3880         if (asc_dbglvl >= (lvl)) { \
3881             printk((s), (a1)); \
3882         } \
3883     }
3884 
3885 #define ASC_DBG2(lvl, s, a1, a2) \
3886     { \
3887         if (asc_dbglvl >= (lvl)) { \
3888             printk((s), (a1), (a2)); \
3889         } \
3890     }
3891 
3892 #define ASC_DBG3(lvl, s, a1, a2, a3) \
3893     { \
3894         if (asc_dbglvl >= (lvl)) { \
3895             printk((s), (a1), (a2), (a3)); \
3896         } \
3897     }
3898 
3899 #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3900     { \
3901         if (asc_dbglvl >= (lvl)) { \
3902             printk((s), (a1), (a2), (a3), (a4)); \
3903         } \
3904     }
3905 
3906 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3907     { \
3908         if (asc_dbglvl >= (lvl)) { \
3909             asc_prt_scsi_host(s); \
3910         } \
3911     }
3912 
3913 #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3914     { \
3915         if (asc_dbglvl >= (lvl)) { \
3916             asc_prt_scsi_cmnd(s); \
3917         } \
3918     }
3919 
3920 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3921     { \
3922         if (asc_dbglvl >= (lvl)) { \
3923             asc_prt_asc_scsi_q(scsiqp); \
3924         } \
3925     }
3926 
3927 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3928     { \
3929         if (asc_dbglvl >= (lvl)) { \
3930             asc_prt_asc_qdone_info(qdone); \
3931         } \
3932     }
3933 
3934 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3935     { \
3936         if (asc_dbglvl >= (lvl)) { \
3937             asc_prt_adv_scsi_req_q(scsiqp); \
3938         } \
3939     }
3940 
3941 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3942     { \
3943         if (asc_dbglvl >= (lvl)) { \
3944             asc_prt_hex((name), (start), (length)); \
3945         } \
3946     }
3947 
3948 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3949         ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3950 
3951 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3952         ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3953 
3954 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3955         ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3956 #endif /* ADVANSYS_DEBUG */
3957 
3958 #ifndef ADVANSYS_ASSERT
3959 #define ASC_ASSERT(a)
3960 #else /* ADVANSYS_ASSERT */
3961 
3962 #define ASC_ASSERT(a) \
3963     { \
3964         if (!(a)) { \
3965             printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3966                 __FILE__, __LINE__); \
3967         } \
3968     }
3969 
3970 #endif /* ADVANSYS_ASSERT */
3971 
3972 
3973 /*
3974  * --- Driver Structures
3975  */
3976 
3977 #ifdef ADVANSYS_STATS
3978 
3979 /* Per board statistics structure */
3980 struct asc_stats {
3981     /* Driver Entrypoint Statistics */
3982     ADV_DCNT queuecommand;    /* # calls to advansys_queuecommand() */
3983     ADV_DCNT reset;           /* # calls to advansys_eh_bus_reset() */
3984     ADV_DCNT biosparam;       /* # calls to advansys_biosparam() */
3985     ADV_DCNT interrupt;       /* # advansys_interrupt() calls */
3986     ADV_DCNT callback;        /* # calls to asc/adv_isr_callback() */
3987     ADV_DCNT done;            /* # calls to request's scsi_done function */
3988     ADV_DCNT build_error;     /* # asc/adv_build_req() ASC_ERROR returns. */
3989     ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
3990     ADV_DCNT adv_build_nosg;  /* # adv_build_req() adv_sgblk_t alloc. fail. */
3991     /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3992     ADV_DCNT exe_noerror;     /* # ASC_NOERROR returns. */
3993     ADV_DCNT exe_busy;        /* # ASC_BUSY returns. */
3994     ADV_DCNT exe_error;       /* # ASC_ERROR returns. */
3995     ADV_DCNT exe_unknown;     /* # unknown returns. */
3996     /* Data Transfer Statistics */
3997     ADV_DCNT cont_cnt;        /* # non-scatter-gather I/O requests received */
3998     ADV_DCNT cont_xfer;       /* # contiguous transfer 512-bytes */
3999     ADV_DCNT sg_cnt;          /* # scatter-gather I/O requests received */
4000     ADV_DCNT sg_elem;         /* # scatter-gather elements */
4001     ADV_DCNT sg_xfer;         /* # scatter-gather transfer 512-bytes */
4002 };
4003 #endif /* ADVANSYS_STATS */
4004 
4005 /*
4006  * Request queuing structure
4007  */
4008 typedef struct asc_queue {
4009     ADV_SCSI_BIT_ID_TYPE  q_tidmask;                /* queue mask */
4010     REQP                  q_first[ADV_MAX_TID+1];   /* first queued request */
4011     REQP                  q_last[ADV_MAX_TID+1];    /* last queued request */
4012 #ifdef ADVANSYS_STATS
4013     short                 q_cur_cnt[ADV_MAX_TID+1]; /* current queue count */
4014     short                 q_max_cnt[ADV_MAX_TID+1]; /* maximum queue count */
4015     ADV_DCNT              q_tot_cnt[ADV_MAX_TID+1]; /* total enqueue count */
4016     ADV_DCNT              q_tot_tim[ADV_MAX_TID+1]; /* total time queued */
4017     ushort                q_max_tim[ADV_MAX_TID+1]; /* maximum time queued */
4018     ushort                q_min_tim[ADV_MAX_TID+1]; /* minimum time queued */
4019 #endif /* ADVANSYS_STATS */
4020 } asc_queue_t;
4021 
4022 /*
4023  * Adv Library Request Structures
4024  *
4025  * The following two structures are used to process Wide Board requests.
4026  *
4027  * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
4028  * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
4029  * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
4030  * Mid-Level SCSI request structure.
4031  *
4032  * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
4033  * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
4034  * up to 255 scatter-gather elements may be used per request or
4035  * ADV_SCSI_REQ_Q.
4036  *
4037  * Both structures must be 32 byte aligned.
4038  */
4039 typedef struct adv_sgblk {
4040     ADV_SG_BLOCK        sg_block;     /* Sgblock structure. */
4041     uchar               align[32];    /* Sgblock structure padding. */
4042     struct adv_sgblk    *next_sgblkp; /* Next scatter-gather structure. */
4043 } adv_sgblk_t;
4044 
4045 typedef struct adv_req {
4046     ADV_SCSI_REQ_Q      scsi_req_q;   /* Adv Library request structure. */
4047     uchar               align[32];    /* Request structure padding. */
4048     Scsi_Cmnd           *cmndp;       /* Mid-Level SCSI command pointer. */
4049     adv_sgblk_t         *sgblkp;      /* Adv Library scatter-gather pointer. */
4050     struct adv_req      *next_reqp;   /* Next Request Structure. */
4051 } adv_req_t;
4052 
4053 /*
4054  * Structure allocated for each board.
4055  *
4056  * This structure is allocated by scsi_register() at the end
4057  * of the 'Scsi_Host' structure starting at the 'hostdata'
4058  * field. It is guaranteed to be allocated from DMA-able memory.
4059  */
4060 typedef struct asc_board {
4061     int                  id;                    /* Board Id */
4062     uint                 flags;                 /* Board flags */
4063     union {
4064         ASC_DVC_VAR      asc_dvc_var;           /* Narrow board */
4065         ADV_DVC_VAR      adv_dvc_var;           /* Wide board */
4066     } dvc_var;
4067     union {
4068         ASC_DVC_CFG      asc_dvc_cfg;           /* Narrow board */
4069         ADV_DVC_CFG      adv_dvc_cfg;           /* Wide board */
4070     } dvc_cfg;
4071     ushort               asc_n_io_port;         /* Number I/O ports. */
4072     asc_queue_t          active;                /* Active command queue */
4073     asc_queue_t          waiting;               /* Waiting command queue */
4074     asc_queue_t          done;                  /* Done command queue */
4075     ADV_SCSI_BIT_ID_TYPE init_tidmask;          /* Target init./valid mask */
4076     Scsi_Device          *device[ADV_MAX_TID+1]; /* Mid-Level Scsi Device */
4077     ushort               reqcnt[ADV_MAX_TID+1]; /* Starvation request count */
4078     ADV_SCSI_BIT_ID_TYPE queue_full;            /* Queue full mask */
4079     ushort               queue_full_cnt[ADV_MAX_TID+1]; /* Queue full count */
4080     union {
4081         ASCEEP_CONFIG         asc_eep;          /* Narrow EEPROM config. */
4082         ADVEEP_3550_CONFIG    adv_3550_eep;     /* 3550 EEPROM config. */
4083         ADVEEP_38C0800_CONFIG adv_38C0800_eep;  /* 38C0800 EEPROM config. */
4084         ADVEEP_38C1600_CONFIG adv_38C1600_eep;  /* 38C1600 EEPROM config. */
4085     } eep_config;
4086     ulong                last_reset;            /* Saved last reset time */
4087     spinlock_t lock;                            /* Board spinlock */
4088 #ifdef CONFIG_PROC_FS
4089     /* /proc/scsi/advansys/[0...] */
4090     char                 *prtbuf;               /* /proc print buffer */
4091 #endif /* CONFIG_PROC_FS */
4092 #ifdef ADVANSYS_STATS
4093     struct asc_stats     asc_stats;             /* Board statistics */
4094 #endif /* ADVANSYS_STATS */
4095     /*
4096      * The following fields are used only for Narrow Boards.
4097      */
4098     /* The following three structures must be in DMA-able memory. */
4099     ASC_SCSI_REQ_Q       scsireqq;
4100     ASC_CAP_INFO         cap_info;
4101     ASC_SCSI_INQUIRY     inquiry;
4102     uchar                sdtr_data[ASC_MAX_TID+1]; /* SDTR information */
4103     /*
4104      * The following fields are used only for Wide Boards.
4105      */
4106     void                 *ioremap_addr;         /* I/O Memory remap address. */
4107     ushort               ioport;                /* I/O Port address. */
4108     ADV_CARR_T           *orig_carrp;           /* ADV_CARR_T memory block. */
4109     adv_req_t            *orig_reqp;            /* adv_req_t memory block. */
4110     adv_req_t            *adv_reqp;             /* Request structures. */
4111     adv_sgblk_t          *adv_sgblkp;           /* Scatter-gather structures. */
4112     ushort               bios_signature;        /* BIOS Signature. */
4113     ushort               bios_version;          /* BIOS Version. */
4114     ushort               bios_codeseg;          /* BIOS Code Segment. */
4115     ushort               bios_codelen;          /* BIOS Code Segment Length. */
4116 } asc_board_t;
4117 
4118 /*
4119  * PCI configuration structures
4120  */
4121 typedef struct _PCI_DATA_
4122 {
4123     uchar    type;
4124     uchar    bus;
4125     uchar    slot;
4126     uchar    func;
4127     uchar    offset;
4128 } PCI_DATA;
4129 
4130 typedef struct _PCI_DEVICE_
4131 {
4132     ushort   vendorID;
4133     ushort   deviceID;
4134     ushort   slotNumber;
4135     ushort   slotFound;
4136     uchar    busNumber;
4137     uchar    maxBusNumber;
4138     uchar    devFunc;
4139     ushort   startSlot;
4140     ushort   endSlot;
4141     uchar    bridge;
4142     uchar    type;
4143 } PCI_DEVICE;
4144 
4145 typedef struct _PCI_CONFIG_SPACE_
4146 {
4147     ushort   vendorID;
4148     ushort   deviceID;
4149     ushort   command;
4150     ushort   status;
4151     uchar    revision;
4152     uchar    classCode[3];
4153     uchar    cacheSize;
4154     uchar    latencyTimer;
4155     uchar    headerType;
4156     uchar    bist;
4157     ADV_PADDR baseAddress[6];
4158     ushort   reserved[4];
4159     ADV_PADDR optionRomAddr;
4160     ushort   reserved2[4];
4161     uchar    irqLine;
4162     uchar    irqPin;
4163     uchar    minGnt;
4164     uchar    maxLatency;
4165 } PCI_CONFIG_SPACE;
4166 
4167 
4168 /*
4169  * --- Driver Data
4170  */
4171 
4172 /* Note: All driver global data should be initialized. */
4173 
4174 #if ASC_LINUX_KERNEL22
4175 #ifdef CONFIG_PROC_FS
4176 struct proc_dir_entry proc_scsi_advansys =
4177 {
4178     PROC_SCSI_ADVANSYS,              /* unsigned short low_ino */
4179     8,                               /* unsigned short namelen */
4180     "advansys",                      /* const char *name */
4181     S_IFDIR | S_IRUGO | S_IXUGO,     /* mode_t mode */
4182     2                                /* nlink_t nlink */
4183 };
4184 #endif /* CONFIG_PROC_FS */
4185 #endif /* ASC_LINUX_KERNEL22 */
4186 
4187 /* Number of boards detected in system. */
4188 STATIC int asc_board_count = 0;
4189 STATIC struct Scsi_Host    *asc_host[ASC_NUM_BOARD_SUPPORTED] = { 0 };
4190 
4191 /* Overrun buffer used by all narrow boards. */
4192 STATIC uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
4193 
4194 /*
4195  * Global structures required to issue a command.
4196  */
4197 STATIC ASC_SCSI_Q asc_scsi_q = { { 0 } };
4198 STATIC ASC_SG_HEAD asc_sg_head = { 0 };
4199 
4200 /* List of supported bus types. */
4201 STATIC ushort asc_bus[ASC_NUM_BUS] ASC_INITDATA = {
4202     ASC_IS_ISA,
4203     ASC_IS_VL,
4204     ASC_IS_EISA,
4205     ASC_IS_PCI,
4206 };
4207 
4208 /*
4209  * Used with the LILO 'advansys' option to eliminate or
4210  * limit I/O port probing at boot time, cf. advansys_setup().
4211  */
4212 STATIC int asc_iopflag = ASC_FALSE;
4213 STATIC int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
4214 
4215 #ifdef ADVANSYS_DEBUG
4216 STATIC char *
4217 asc_bus_name[ASC_NUM_BUS] = {
4218     "ASC_IS_ISA",
4219     "ASC_IS_VL",
4220     "ASC_IS_EISA",
4221     "ASC_IS_PCI",
4222 };
4223 
4224 STATIC int          asc_dbglvl = 3;
4225 #endif /* ADVANSYS_DEBUG */
4226 
4227 /* Declaration for Asc Library internal data referenced by driver. */
4228 STATIC PortAddr     _asc_def_iop_base[];
4229 
4230 
4231 /*
4232  * --- Driver Function Prototypes
4233  *
4234  * advansys.h contains function prototypes for functions global to Linux.
4235  */
4236 
4237 STATIC void       advansys_interrupt(int, void *, struct pt_regs *);
4238 STATIC void       advansys_select_queue_depths(struct Scsi_Host *,
4239                                                Scsi_Device *);
4240 STATIC void       asc_scsi_done_list(Scsi_Cmnd *);
4241 STATIC int        asc_execute_scsi_cmnd(Scsi_Cmnd *);
4242 STATIC int        asc_build_req(asc_board_t *, Scsi_Cmnd *);
4243 STATIC int        adv_build_req(asc_board_t *, Scsi_Cmnd *, ADV_SCSI_REQ_Q **);
4244 STATIC int        adv_get_sglist(asc_board_t *, adv_req_t *, Scsi_Cmnd *);
4245 STATIC void       asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
4246 STATIC void       adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
4247 STATIC void       adv_async_callback(ADV_DVC_VAR *, uchar);
4248 STATIC void       asc_enqueue(asc_queue_t *, REQP, int);
4249 STATIC REQP       asc_dequeue(asc_queue_t *, int);
4250 STATIC REQP       asc_dequeue_list(asc_queue_t *, REQP *, int);
4251 STATIC int        asc_rmqueue(asc_queue_t *, REQP);
4252 STATIC void       asc_execute_queue(asc_queue_t *);
4253 #ifdef CONFIG_PROC_FS
4254 STATIC int        asc_proc_copy(off_t, off_t, char *, int , char *, int);
4255 STATIC int        asc_prt_board_devices(struct Scsi_Host *, char *, int);
4256 STATIC int        asc_prt_adv_bios(struct Scsi_Host *, char *, int);
4257 STATIC int        asc_get_eeprom_string(ushort *serialnum, uchar *cp);
4258 STATIC int        asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
4259 STATIC int        asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
4260 STATIC int        asc_prt_driver_conf(struct Scsi_Host *, char *, int);
4261 STATIC int        asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
4262 STATIC int        asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
4263 STATIC int        asc_prt_line(char *, int, char *fmt, ...);
4264 #endif /* CONFIG_PROC_FS */
4265 
4266 /* Declaration for Asc Library internal functions referenced by driver. */
4267 STATIC int          AscFindSignature(PortAddr);
4268 STATIC ushort       AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
4269 
4270 /* Statistics function prototypes. */
4271 #ifdef ADVANSYS_STATS
4272 #ifdef CONFIG_PROC_FS
4273 STATIC int          asc_prt_board_stats(struct Scsi_Host *, char *, int);
4274 STATIC int          asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
4275 #endif /* CONFIG_PROC_FS */
4276 #endif /* ADVANSYS_STATS */
4277 
4278 /* Debug function prototypes. */
4279 #ifdef ADVANSYS_DEBUG
4280 STATIC void         asc_prt_scsi_host(struct Scsi_Host *);
4281 STATIC void         asc_prt_scsi_cmnd(Scsi_Cmnd *);
4282 STATIC void         asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
4283 STATIC void         asc_prt_asc_dvc_var(ASC_DVC_VAR *);
4284 STATIC void         asc_prt_asc_scsi_q(ASC_SCSI_Q *);
4285 STATIC void         asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
4286 STATIC void         asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
4287 STATIC void         asc_prt_adv_dvc_var(ADV_DVC_VAR *);
4288 STATIC void         asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
4289 STATIC void         asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
4290 STATIC void         asc_prt_hex(char *f, uchar *, int);
4291 #endif /* ADVANSYS_DEBUG */
4292 
4293 
4294 /*
4295  * --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
4296  */
4297 
4298 #ifdef CONFIG_PROC_FS
4299 /*
4300  * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
4301  *
4302  * *buffer: I/O buffer
4303  * **start: if inout == FALSE pointer into buffer where user read should start
4304  * offset: current offset into a /proc/scsi/advansys/[0...] file
4305  * length: length of buffer
4306  * hostno: Scsi_Host host_no
4307  * inout: TRUE - user is writing; FALSE - user is reading
4308  *
4309  * Return the number of bytes read from or written to a
4310  * /proc/scsi/advansys/[0...] file.
4311  *
4312  * Note: This function uses the per board buffer 'prtbuf' which is
4313  * allocated when the board is initialized in advansys_detect(). The
4314  * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
4315  * used to write to the buffer. The way asc_proc_copy() is written
4316  * if 'prtbuf' is too small it will not be overwritten. Instead the
4317  * user just won't get all the available statistics.
4318  */
4319 int
advansys_proc_info(char * buffer,char ** start,off_t offset,int length,int hostno,int inout)4320 advansys_proc_info(char *buffer, char **start, off_t offset, int length,
4321                    int hostno, int inout)
4322 {
4323     struct Scsi_Host    *shp;
4324     asc_board_t         *boardp;
4325     int                 i;
4326     char                *cp;
4327     int                 cplen;
4328     int                 cnt;
4329     int                 totcnt;
4330     int                 leftlen;
4331     char                *curbuf;
4332     off_t               advoffset;
4333     Scsi_Device         *scd;
4334 #ifdef ADVANSYS_STATS
4335     int                 tgt_id;
4336 #endif /* ADVANSYS_STATS */
4337 
4338     ASC_DBG(1, "advansys_proc_info: begin\n");
4339 
4340     /*
4341      * User write not supported.
4342      */
4343     if (inout == TRUE) {
4344         return(-ENOSYS);
4345     }
4346 
4347     /*
4348      * User read of /proc/scsi/advansys/[0...] file.
4349      */
4350 
4351     /* Find the specified board. */
4352     for (i = 0; i < asc_board_count; i++) {
4353         if (asc_host[i]->host_no == hostno) {
4354             break;
4355         }
4356     }
4357     if (i == asc_board_count) {
4358         return(-ENOENT);
4359     }
4360 
4361     shp = asc_host[i];
4362     boardp = ASC_BOARDP(shp);
4363 
4364     /* Copy read data starting at the beginning of the buffer. */
4365     *start = buffer;
4366     curbuf = buffer;
4367     advoffset = 0;
4368     totcnt = 0;
4369     leftlen = length;
4370 
4371     /*
4372      * Get board configuration information.
4373      *
4374      * advansys_info() returns the board string from its own static buffer.
4375      */
4376     cp = (char *) advansys_info(shp);
4377     strcat(cp, "\n");
4378     cplen = strlen(cp);
4379     /* Copy board information. */
4380     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4381     totcnt += cnt;
4382     leftlen -= cnt;
4383     if (leftlen == 0) {
4384         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4385         return totcnt;
4386     }
4387     advoffset += cplen;
4388     curbuf += cnt;
4389 
4390     /*
4391      * Display Wide Board BIOS Information.
4392      */
4393     if (ASC_WIDE_BOARD(boardp)) {
4394         cp = boardp->prtbuf;
4395         cplen = asc_prt_adv_bios(shp, cp, ASC_PRTBUF_SIZE);
4396         ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4397         cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4398         totcnt += cnt;
4399         leftlen -= cnt;
4400         if (leftlen == 0) {
4401             ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4402             return totcnt;
4403         }
4404         advoffset += cplen;
4405         curbuf += cnt;
4406     }
4407 
4408     /*
4409      * Display driver information for each device attached to the board.
4410      */
4411     cp = boardp->prtbuf;
4412     cplen = asc_prt_board_devices(shp, cp, ASC_PRTBUF_SIZE);
4413     ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4414     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4415     totcnt += cnt;
4416     leftlen -= cnt;
4417     if (leftlen == 0) {
4418         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4419         return totcnt;
4420     }
4421     advoffset += cplen;
4422     curbuf += cnt;
4423 
4424     /*
4425      * Display target driver information for each device attached
4426      * to the board.
4427      */
4428     for (scd = shp->host_queue; scd; scd = scd->next)
4429     {
4430         if (scd->host == shp) {
4431             cp = boardp->prtbuf;
4432             /*
4433              * Note: If proc_print_scsidevice() writes more than
4434              * ASC_PRTBUF_SIZE bytes, it will overrun 'prtbuf'.
4435              */
4436             proc_print_scsidevice(scd, cp, &cplen, 0);
4437             ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4438             cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4439             totcnt += cnt;
4440             leftlen -= cnt;
4441             if (leftlen == 0) {
4442                 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4443                 return totcnt;
4444             }
4445             advoffset += cplen;
4446             curbuf += cnt;
4447         }
4448     }
4449 
4450     /*
4451      * Display EEPROM configuration for the board.
4452      */
4453     cp = boardp->prtbuf;
4454     if (ASC_NARROW_BOARD(boardp)) {
4455         cplen = asc_prt_asc_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4456     } else {
4457         cplen = asc_prt_adv_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4458     }
4459     ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4460     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4461     totcnt += cnt;
4462     leftlen -= cnt;
4463     if (leftlen == 0) {
4464         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4465         return totcnt;
4466     }
4467     advoffset += cplen;
4468     curbuf += cnt;
4469 
4470     /*
4471      * Display driver configuration and information for the board.
4472      */
4473     cp = boardp->prtbuf;
4474     cplen = asc_prt_driver_conf(shp, cp, ASC_PRTBUF_SIZE);
4475     ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4476     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4477     totcnt += cnt;
4478     leftlen -= cnt;
4479     if (leftlen == 0) {
4480         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4481         return totcnt;
4482     }
4483     advoffset += cplen;
4484     curbuf += cnt;
4485 
4486 #ifdef ADVANSYS_STATS
4487     /*
4488      * Display driver statistics for the board.
4489      */
4490     cp = boardp->prtbuf;
4491     cplen = asc_prt_board_stats(shp, cp, ASC_PRTBUF_SIZE);
4492     ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4493     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4494     totcnt += cnt;
4495     leftlen -= cnt;
4496     if (leftlen == 0) {
4497         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4498         return totcnt;
4499     }
4500     advoffset += cplen;
4501     curbuf += cnt;
4502 
4503     /*
4504      * Display driver statistics for each target.
4505      */
4506     for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
4507       cp = boardp->prtbuf;
4508       cplen = asc_prt_target_stats(shp, tgt_id, cp, ASC_PRTBUF_SIZE);
4509       ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4510       cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4511       totcnt += cnt;
4512       leftlen -= cnt;
4513       if (leftlen == 0) {
4514         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4515         return totcnt;
4516       }
4517       advoffset += cplen;
4518       curbuf += cnt;
4519     }
4520 #endif /* ADVANSYS_STATS */
4521 
4522     /*
4523      * Display Asc Library dynamic configuration information
4524      * for the board.
4525      */
4526     cp = boardp->prtbuf;
4527     if (ASC_NARROW_BOARD(boardp)) {
4528         cplen = asc_prt_asc_board_info(shp, cp, ASC_PRTBUF_SIZE);
4529     } else {
4530         cplen = asc_prt_adv_board_info(shp, cp, ASC_PRTBUF_SIZE);
4531     }
4532     ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4533     cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4534     totcnt += cnt;
4535     leftlen -= cnt;
4536     if (leftlen == 0) {
4537         ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4538         return totcnt;
4539     }
4540     advoffset += cplen;
4541     curbuf += cnt;
4542 
4543     ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4544 
4545     return totcnt;
4546 }
4547 #endif /* CONFIG_PROC_FS */
4548 
4549 /*
4550  * advansys_detect()
4551  *
4552  * Detect function for AdvanSys adapters.
4553  *
4554  * Argument is a pointer to the host driver's scsi_hosts entry.
4555  *
4556  * Return number of adapters found.
4557  *
4558  * Note: Because this function is called during system initialization
4559  * it must not call SCSI mid-level functions including scsi_malloc()
4560  * and scsi_free().
4561  */
ASC_INITFUNC(int,advansys_detect (Scsi_Host_Template * tpnt))4562 ASC_INITFUNC(
4563 int,
4564 advansys_detect(Scsi_Host_Template *tpnt)
4565 )
4566 {
4567     static int          detect_called = ASC_FALSE;
4568     int                 iop;
4569     int                 bus;
4570     struct Scsi_Host    *shp = NULL;
4571     asc_board_t         *boardp = NULL;
4572     ASC_DVC_VAR         *asc_dvc_varp = NULL;
4573     ADV_DVC_VAR         *adv_dvc_varp = NULL;
4574     adv_sgblk_t         *sgp = NULL;
4575     int                 ioport = 0;
4576     int                 share_irq = FALSE;
4577     int                 iolen = 0;
4578 #ifdef CONFIG_PCI
4579     int                 pci_init_search = 0;
4580     struct pci_dev      *pci_devicep[ASC_NUM_BOARD_SUPPORTED];
4581     int                 pci_card_cnt_max = 0;
4582     int                 pci_card_cnt = 0;
4583     struct pci_dev      *pci_devp = NULL;
4584     int                 pci_device_id_cnt = 0;
4585     unsigned int        pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
4586                                     ASC_PCI_DEVICE_ID_1100,
4587                                     ASC_PCI_DEVICE_ID_1200,
4588                                     ASC_PCI_DEVICE_ID_1300,
4589                                     ASC_PCI_DEVICE_ID_2300,
4590                                     ASC_PCI_DEVICE_ID_2500,
4591                                     ASC_PCI_DEVICE_ID_2700
4592                         };
4593     ADV_PADDR           pci_memory_address;
4594 #endif /* CONFIG_PCI */
4595     int                 warn_code, err_code;
4596     int                 ret;
4597 
4598     if (detect_called == ASC_FALSE) {
4599         detect_called = ASC_TRUE;
4600     } else {
4601         printk("AdvanSys SCSI: advansys_detect() multiple calls ignored\n");
4602         return 0;
4603     }
4604 
4605     ASC_DBG(1, "advansys_detect: begin\n");
4606 
4607     /*
4608      * XXX - Remove this comment and the next line when SCSI mid-level
4609      * no longer acquires 'io_request_lock' before calling the SCSI
4610      * low-level detect entrypoint.
4611      */
4612     ASC_UNLOCK_IO_REQUEST_LOCK
4613 
4614 #if ASC_LINUX_KERNEL24
4615     tpnt->proc_name = "advansys";
4616 #elif ASC_LINUX_KERNEL22
4617     tpnt->proc_dir = &proc_scsi_advansys;
4618 #endif
4619 
4620     asc_board_count = 0;
4621 
4622     /*
4623      * If I/O port probing has been modified, then verify and
4624      * clean-up the 'asc_ioport' list.
4625      */
4626     if (asc_iopflag == ASC_TRUE) {
4627         for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
4628             ASC_DBG2(1, "advansys_detect: asc_ioport[%d] 0x%x\n",
4629                 ioport, asc_ioport[ioport]);
4630             if (asc_ioport[ioport] != 0) {
4631                 for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX; iop++) {
4632                     if (_asc_def_iop_base[iop] == asc_ioport[ioport]) {
4633                         break;
4634                     }
4635                 }
4636                 if (iop == ASC_IOADR_TABLE_MAX_IX) {
4637                     printk(
4638 "AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
4639                         asc_ioport[ioport]);
4640                     asc_ioport[ioport] = 0;
4641                 }
4642             }
4643         }
4644         ioport = 0;
4645     }
4646 
4647     for (bus = 0; bus < ASC_NUM_BUS; bus++) {
4648 
4649         ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
4650             bus, asc_bus_name[bus]);
4651         iop = 0;
4652 
4653         while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) {
4654 
4655             ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
4656                 asc_board_count);
4657 
4658             switch (asc_bus[bus]) {
4659             case ASC_IS_ISA:
4660             case ASC_IS_VL:
4661 #ifdef CONFIG_ISA
4662                 if (asc_iopflag == ASC_FALSE) {
4663                     iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4664                 } else {
4665                     /*
4666                      * ISA and VL I/O port scanning has either been
4667                      * eliminated or limited to selected ports on
4668                      * the LILO command line, /etc/lilo.conf, or
4669                      * by setting variables when the module was loaded.
4670                      */
4671                     ASC_DBG(1, "advansys_detect: I/O port scanning modified\n");
4672                 ioport_try_again:
4673                     iop = 0;
4674                     for (; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
4675                         if ((iop = asc_ioport[ioport]) != 0) {
4676                             break;
4677                         }
4678                     }
4679                     if (iop) {
4680                         ASC_DBG1(1,
4681                                 "advansys_detect: probing I/O port 0x%x...\n",
4682                             iop);
4683                         if (check_region(iop, ASC_IOADR_GAP) != 0) {
4684                             printk(
4685 "AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop);
4686                             /* Don't try this I/O port twice. */
4687                             asc_ioport[ioport] = 0;
4688                             goto ioport_try_again;
4689                         } else if (AscFindSignature(iop) == ASC_FALSE) {
4690                             printk(
4691 "AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop);
4692                             /* Don't try this I/O port twice. */
4693                             asc_ioport[ioport] = 0;
4694                             goto ioport_try_again;
4695                         } else {
4696                             /*
4697                              * If this isn't an ISA board, then it must be
4698                              * a VL board. If currently looking an ISA
4699                              * board is being looked for then try for
4700                              * another ISA board in 'asc_ioport'.
4701                              */
4702                             if (asc_bus[bus] == ASC_IS_ISA &&
4703                                 (AscGetChipVersion(iop, ASC_IS_ISA) &
4704                                  ASC_CHIP_VER_ISA_BIT) == 0) {
4705                                  /*
4706                                   * Don't clear 'asc_ioport[ioport]'. Try
4707                                   * this board again for VL. Increment
4708                                   * 'ioport' past this board.
4709                                   */
4710                                  ioport++;
4711                                  goto ioport_try_again;
4712                             }
4713                         }
4714                         /*
4715                          * This board appears good, don't try the I/O port
4716                          * again by clearing its value. Increment 'ioport'
4717                          * for the next iteration.
4718                          */
4719                         asc_ioport[ioport++] = 0;
4720                     }
4721                 }
4722 #endif /* CONFIG_ISA */
4723                 break;
4724 
4725             case ASC_IS_EISA:
4726 #ifdef CONFIG_ISA
4727                 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4728 #endif /* CONFIG_ISA */
4729                 break;
4730 
4731             case ASC_IS_PCI:
4732 #ifdef CONFIG_PCI
4733                 if (pci_init_search == 0) {
4734                     int i, j;
4735 
4736                     pci_init_search = 1;
4737 
4738                     /* Find all PCI cards. */
4739                     while (pci_device_id_cnt < ASC_PCI_DEVICE_ID_CNT) {
4740                         if ((pci_devp = pci_find_device(ASC_PCI_VENDORID,
4741                             pci_device_id[pci_device_id_cnt], pci_devp)) ==
4742                             NULL) {
4743                             pci_device_id_cnt++;
4744                         } else {
4745 #if ASC_LINUX_KERNEL24
4746                             if (pci_enable_device(pci_devp) == 0) {
4747                                 pci_devicep[pci_card_cnt_max++] = pci_devp;
4748                             }
4749 #elif ASC_LINUX_KERNEL22
4750                             pci_devicep[pci_card_cnt_max++] = pci_devp;
4751 #endif
4752                         }
4753                     }
4754 
4755                     /*
4756                      * Sort PCI cards in ascending order by PCI Bus, Slot,
4757                      * and Device Number.
4758                      */
4759                     for (i = 0; i < pci_card_cnt_max - 1; i++)
4760                     {
4761                         for (j = i + 1; j < pci_card_cnt_max; j++) {
4762                             if ((pci_devicep[j]->bus->number <
4763                                  pci_devicep[i]->bus->number) ||
4764                                 ((pci_devicep[j]->bus->number ==
4765                                   pci_devicep[i]->bus->number) &&
4766                                   (pci_devicep[j]->devfn <
4767                                    pci_devicep[i]->devfn))) {
4768                                 pci_devp = pci_devicep[i];
4769                                 pci_devicep[i] = pci_devicep[j];
4770                                 pci_devicep[j] = pci_devp;
4771                             }
4772                         }
4773                     }
4774 
4775                     pci_card_cnt = 0;
4776                 } else {
4777                     pci_card_cnt++;
4778                 }
4779 
4780                 if (pci_card_cnt == pci_card_cnt_max) {
4781                     iop = 0;
4782                 } else {
4783                     pci_devp = pci_devicep[pci_card_cnt];
4784 
4785                     ASC_DBG2(2,
4786                         "advansys_detect: devfn %d, bus number %d\n",
4787                         pci_devp->devfn, pci_devp->bus->number);
4788 #if ASC_LINUX_KERNEL24
4789                     iop = pci_resource_start(pci_devp, 0);
4790 #elif ASC_LINUX_KERNEL22
4791                     iop = pci_devp->base_address[0] & PCI_IOADDRESS_MASK;
4792 #endif
4793                     ASC_DBG2(1,
4794                         "advansys_detect: vendorID %X, deviceID %X\n",
4795                         pci_devp->vendor, pci_devp->device);
4796                     ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
4797                         iop, pci_devp->irq);
4798                 }
4799 #endif /* CONFIG_PCI */
4800                 break;
4801 
4802             default:
4803                 ASC_PRINT1("advansys_detect: unknown bus type: %d\n",
4804                     asc_bus[bus]);
4805                 break;
4806             }
4807             ASC_DBG1(1, "advansys_detect: iop 0x%x\n", iop);
4808 
4809             /*
4810              * Adapter not found, try next bus type.
4811              */
4812             if (iop == 0) {
4813                 break;
4814             }
4815 
4816             /*
4817              * Adapter found.
4818              *
4819              * Register the adapter, get its configuration, and
4820              * initialize it.
4821              */
4822             ASC_DBG(2, "advansys_detect: scsi_register()\n");
4823             shp = scsi_register(tpnt, sizeof(asc_board_t));
4824 
4825             if (shp == NULL) {
4826                 continue;
4827             }
4828 #ifdef CONFIG_PCI
4829 	    scsi_set_pci_device(shp, pci_devp);
4830 #endif
4831 
4832             /* Save a pointer to the Scsi_host of each board found. */
4833             asc_host[asc_board_count++] = shp;
4834 
4835             /* Initialize private per board data */
4836             boardp = ASC_BOARDP(shp);
4837             memset(boardp, 0, sizeof(asc_board_t));
4838             boardp->id = asc_board_count - 1;
4839 
4840             /* Initialize spinlock. */
4841             boardp->lock = SPIN_LOCK_UNLOCKED;
4842 
4843             /*
4844              * Handle both narrow and wide boards.
4845              *
4846              * If a Wide board was detected, set the board structure
4847              * wide board flag. Set-up the board structure based on
4848              * the board type.
4849              */
4850 #ifdef CONFIG_PCI
4851             if (asc_bus[bus] == ASC_IS_PCI &&
4852                 (pci_devp->device == ASC_PCI_DEVICE_ID_2300 ||
4853                  pci_devp->device == ASC_PCI_DEVICE_ID_2500 ||
4854                  pci_devp->device == ASC_PCI_DEVICE_ID_2700))
4855             {
4856                 boardp->flags |= ASC_IS_WIDE_BOARD;
4857             }
4858 #endif /* CONFIG_PCI */
4859 
4860             if (ASC_NARROW_BOARD(boardp)) {
4861                 ASC_DBG(1, "advansys_detect: narrow board\n");
4862                 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4863                 asc_dvc_varp->bus_type = asc_bus[bus];
4864                 asc_dvc_varp->drv_ptr = boardp;
4865                 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
4866                 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
4867                 asc_dvc_varp->iop_base = iop;
4868                 asc_dvc_varp->isr_callback = asc_isr_callback;
4869             } else {
4870                 ASC_DBG(1, "advansys_detect: wide board\n");
4871                 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4872                 adv_dvc_varp->drv_ptr = boardp;
4873                 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
4874                 adv_dvc_varp->isr_callback = adv_isr_callback;
4875                 adv_dvc_varp->async_callback = adv_async_callback;
4876 #ifdef CONFIG_PCI
4877                 if (pci_devp->device == ASC_PCI_DEVICE_ID_2300)
4878                 {
4879                     ASC_DBG(1, "advansys_detect: ASC-3550\n");
4880                     adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
4881                 } else if (pci_devp->device == ASC_PCI_DEVICE_ID_2500)
4882                 {
4883                     ASC_DBG(1, "advansys_detect: ASC-38C0800\n");
4884                     adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
4885                 } else
4886                 {
4887                     ASC_DBG(1, "advansys_detect: ASC-38C1600\n");
4888                     adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
4889                 }
4890 #endif /* CONFIG_PCI */
4891 
4892                 /*
4893                  * Map the board's registers into virtual memory for
4894                  * PCI slave access. Only memory accesses are used to
4895                  * access the board's registers.
4896                  *
4897                  * Note: The PCI register base address is not always
4898                  * page aligned, but the address passed to ioremap()
4899                  * must be page aligned. It is guaranteed that the
4900                  * PCI register base address will not cross a page
4901                  * boundary.
4902                  */
4903                 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
4904                 {
4905                     iolen = ADV_3550_IOLEN;
4906                 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
4907                 {
4908                     iolen = ADV_38C0800_IOLEN;
4909                 } else
4910                 {
4911                     iolen = ADV_38C1600_IOLEN;
4912                 }
4913 #ifdef CONFIG_PCI
4914 #if ASC_LINUX_KERNEL24
4915                 pci_memory_address = pci_resource_start(pci_devp, 1);
4916 #elif ASC_LINUX_KERNEL22
4917                 pci_memory_address = pci_devp->base_address[1];
4918 #endif
4919                 ASC_DBG1(1, "advansys_detect: pci_memory_address: 0x%lx\n",
4920                     (ulong) pci_memory_address);
4921                 if ((boardp->ioremap_addr =
4922                     ioremap(pci_memory_address & PAGE_MASK,
4923                          PAGE_SIZE)) == 0) {
4924                    ASC_PRINT3(
4925 "advansys_detect: board %d: ioremap(%x, %d) returned NULL\n",
4926                        boardp->id, pci_memory_address, iolen);
4927                    scsi_unregister(shp);
4928                    asc_board_count--;
4929                    continue;
4930                 }
4931                 ASC_DBG1(1, "advansys_detect: ioremap_addr: 0x%lx\n",
4932                     (ulong) boardp->ioremap_addr);
4933                 adv_dvc_varp->iop_base = (AdvPortAddr)
4934                     (boardp->ioremap_addr +
4935                      (pci_memory_address - (pci_memory_address & PAGE_MASK)));
4936                 ASC_DBG1(1, "advansys_detect: iop_base: 0x%lx\n",
4937                     adv_dvc_varp->iop_base);
4938 #endif /* CONFIG_PCI */
4939 
4940                 /*
4941                  * Even though it isn't used to access wide boards, other
4942                  * than for the debug line below, save I/O Port address so
4943                  * that it can be reported.
4944                  */
4945                 boardp->ioport = iop;
4946 
4947                 ASC_DBG2(1,
4948 "advansys_detect: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
4949                     (ushort) inp(iop + 1), (ushort) inpw(iop));
4950             }
4951 
4952 #ifdef CONFIG_PROC_FS
4953             /*
4954              * Allocate buffer for printing information from
4955              * /proc/scsi/advansys/[0...].
4956              */
4957             if ((boardp->prtbuf =
4958                 kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) {
4959                 ASC_PRINT3(
4960 "advansys_detect: board %d: kmalloc(%d, %d) returned NULL\n",
4961                     boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC);
4962                 scsi_unregister(shp);
4963                 asc_board_count--;
4964                 continue;
4965             }
4966 #endif /* CONFIG_PROC_FS */
4967 
4968             if (ASC_NARROW_BOARD(boardp)) {
4969                 /*
4970                  * Set the board bus type and PCI IRQ before
4971                  * calling AscInitGetConfig().
4972                  */
4973                 switch (asc_dvc_varp->bus_type) {
4974 #ifdef CONFIG_ISA
4975                 case ASC_IS_ISA:
4976                     shp->unchecked_isa_dma = TRUE;
4977                     share_irq = FALSE;
4978                     break;
4979                 case ASC_IS_VL:
4980                     shp->unchecked_isa_dma = FALSE;
4981                     share_irq = FALSE;
4982                     break;
4983                 case ASC_IS_EISA:
4984                     shp->unchecked_isa_dma = FALSE;
4985                     share_irq = TRUE;
4986                     break;
4987 #endif /* CONFIG_ISA */
4988 #ifdef CONFIG_PCI
4989                 case ASC_IS_PCI:
4990                     shp->irq = asc_dvc_varp->irq_no = pci_devp->irq;
4991                     asc_dvc_varp->cfg->pci_device_id = pci_devp->device;
4992                     asc_dvc_varp->cfg->pci_slot_info =
4993                         ASC_PCI_MKID(pci_devp->bus->number,
4994                             PCI_SLOT(pci_devp->devfn),
4995                             PCI_FUNC(pci_devp->devfn));
4996                     shp->unchecked_isa_dma = FALSE;
4997                     share_irq = TRUE;
4998                     break;
4999 #endif /* CONFIG_PCI */
5000                 default:
5001                     ASC_PRINT2(
5002 "advansys_detect: board %d: unknown adapter type: %d\n",
5003                         boardp->id, asc_dvc_varp->bus_type);
5004                     shp->unchecked_isa_dma = TRUE;
5005                     share_irq = FALSE;
5006                     break;
5007                 }
5008             } else {
5009                 /*
5010                  * For Wide boards set PCI information before calling
5011                  * AdvInitGetConfig().
5012                  */
5013 #ifdef CONFIG_PCI
5014                 shp->irq = adv_dvc_varp->irq_no = pci_devp->irq;
5015                 adv_dvc_varp->cfg->pci_device_id = pci_devp->device;
5016                 adv_dvc_varp->cfg->pci_slot_info =
5017                     ASC_PCI_MKID(pci_devp->bus->number,
5018                         PCI_SLOT(pci_devp->devfn),
5019                         PCI_FUNC(pci_devp->devfn));
5020                 shp->unchecked_isa_dma = FALSE;
5021                 share_irq = TRUE;
5022 #endif /* CONFIG_PCI */
5023             }
5024 
5025             /*
5026              * Read the board configuration.
5027              */
5028             if (ASC_NARROW_BOARD(boardp)) {
5029                  /*
5030                   * NOTE: AscInitGetConfig() may change the board's
5031                   * bus_type value. The asc_bus[bus] value should no
5032                   * longer be used. If the bus_type field must be
5033                   * referenced only use the bit-wise AND operator "&".
5034                   */
5035                 ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
5036                 switch(ret = AscInitGetConfig(asc_dvc_varp)) {
5037                 case 0:    /* No error */
5038                     break;
5039                 case ASC_WARN_IO_PORT_ROTATE:
5040                     ASC_PRINT1(
5041 "AscInitGetConfig: board %d: I/O port address modified\n",
5042                         boardp->id);
5043                     break;
5044                 case ASC_WARN_AUTO_CONFIG:
5045                     ASC_PRINT1(
5046 "AscInitGetConfig: board %d: I/O port increment switch enabled\n",
5047                         boardp->id);
5048                     break;
5049                 case ASC_WARN_EEPROM_CHKSUM:
5050                     ASC_PRINT1(
5051 "AscInitGetConfig: board %d: EEPROM checksum error\n",
5052                         boardp->id);
5053                     break;
5054                 case ASC_WARN_IRQ_MODIFIED:
5055                     ASC_PRINT1(
5056 "AscInitGetConfig: board %d: IRQ modified\n",
5057                         boardp->id);
5058                     break;
5059                 case ASC_WARN_CMD_QNG_CONFLICT:
5060                     ASC_PRINT1(
5061 "AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
5062                         boardp->id);
5063                     break;
5064                 default:
5065                     ASC_PRINT2(
5066 "AscInitGetConfig: board %d: unknown warning: 0x%x\n",
5067                         boardp->id, ret);
5068                     break;
5069                 }
5070                 if ((err_code = asc_dvc_varp->err_code) != 0) {
5071                     ASC_PRINT3(
5072 "AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
5073                         boardp->id, asc_dvc_varp->init_state,
5074                         asc_dvc_varp->err_code);
5075                 }
5076             } else {
5077                 ASC_DBG(2, "advansys_detect: AdvInitGetConfig()\n");
5078                 if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
5079                     ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n",
5080                         boardp->id, ret);
5081                 }
5082                 if ((err_code = adv_dvc_varp->err_code) != 0) {
5083                     ASC_PRINT2(
5084 "AdvInitGetConfig: board %d error: err_code 0x%x\n",
5085                         boardp->id, adv_dvc_varp->err_code);
5086                 }
5087             }
5088 
5089             if (err_code != 0) {
5090 #ifdef CONFIG_PROC_FS
5091                 kfree(boardp->prtbuf);
5092 #endif /* CONFIG_PROC_FS */
5093                 scsi_unregister(shp);
5094                 asc_board_count--;
5095                 continue;
5096             }
5097 
5098             /*
5099              * Save the EEPROM configuration so that it can be displayed
5100              * from /proc/scsi/advansys/[0...].
5101              */
5102             if (ASC_NARROW_BOARD(boardp)) {
5103 
5104                 ASCEEP_CONFIG *ep;
5105 
5106                 /*
5107                  * Set the adapter's target id bit in the 'init_tidmask' field.
5108                  */
5109                 boardp->init_tidmask |=
5110                     ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
5111 
5112                 /*
5113                  * Save EEPROM settings for the board.
5114                  */
5115                 ep = &boardp->eep_config.asc_eep;
5116 
5117                 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
5118                 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
5119                 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
5120                 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
5121                 ep->start_motor = asc_dvc_varp->start_motor;
5122                 ep->cntl = asc_dvc_varp->dvc_cntl;
5123                 ep->no_scam = asc_dvc_varp->no_scam;
5124                 ep->max_total_qng = asc_dvc_varp->max_total_qng;
5125                 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
5126                 /* 'max_tag_qng' is set to the same value for every device. */
5127                 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
5128                 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
5129                 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
5130                 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
5131                 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
5132                 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
5133                 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
5134 
5135                /*
5136                 * Modify board configuration.
5137                 */
5138                 ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n");
5139                 switch (ret = AscInitSetConfig(asc_dvc_varp)) {
5140                 case 0:    /* No error. */
5141                     break;
5142                 case ASC_WARN_IO_PORT_ROTATE:
5143                     ASC_PRINT1(
5144 "AscInitSetConfig: board %d: I/O port address modified\n",
5145                         boardp->id);
5146                     break;
5147                 case ASC_WARN_AUTO_CONFIG:
5148                     ASC_PRINT1(
5149 "AscInitSetConfig: board %d: I/O port increment switch enabled\n",
5150                         boardp->id);
5151                     break;
5152                 case ASC_WARN_EEPROM_CHKSUM:
5153                     ASC_PRINT1(
5154 "AscInitSetConfig: board %d: EEPROM checksum error\n",
5155                         boardp->id);
5156                     break;
5157                 case ASC_WARN_IRQ_MODIFIED:
5158                     ASC_PRINT1(
5159 "AscInitSetConfig: board %d: IRQ modified\n",
5160                         boardp->id);
5161                     break;
5162                 case ASC_WARN_CMD_QNG_CONFLICT:
5163                     ASC_PRINT1(
5164 "AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
5165                         boardp->id);
5166                     break;
5167                 default:
5168                     ASC_PRINT2(
5169 "AscInitSetConfig: board %d: unknown warning: 0x%x\n",
5170                         boardp->id, ret);
5171                     break;
5172                 }
5173                 if (asc_dvc_varp->err_code != 0) {
5174                     ASC_PRINT3(
5175 "AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
5176                         boardp->id, asc_dvc_varp->init_state,
5177                         asc_dvc_varp->err_code);
5178 #ifdef CONFIG_PROC_FS
5179                     kfree(boardp->prtbuf);
5180 #endif /* CONFIG_PROC_FS */
5181                     scsi_unregister(shp);
5182                     asc_board_count--;
5183                     continue;
5184                 }
5185 
5186                 /*
5187                  * Finish initializing the 'Scsi_Host' structure.
5188                  */
5189                 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
5190                 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
5191                     shp->irq = asc_dvc_varp->irq_no;
5192                 }
5193             } else {
5194                 ADVEEP_3550_CONFIG      *ep_3550;
5195                 ADVEEP_38C0800_CONFIG   *ep_38C0800;
5196                 ADVEEP_38C1600_CONFIG   *ep_38C1600;
5197 
5198                 /*
5199                  * Save Wide EEP Configuration Information.
5200                  */
5201                 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5202                 {
5203                     ep_3550 = &boardp->eep_config.adv_3550_eep;
5204 
5205                     ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
5206                     ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
5207                     ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
5208                     ep_3550->termination = adv_dvc_varp->cfg->termination;
5209                     ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
5210                     ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
5211                     ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
5212                     ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
5213                     ep_3550->ultra_able = adv_dvc_varp->ultra_able;
5214                     ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
5215                     ep_3550->start_motor = adv_dvc_varp->start_motor;
5216                     ep_3550->scsi_reset_delay = adv_dvc_varp->scsi_reset_wait;
5217                     ep_3550->serial_number_word1 =
5218                         adv_dvc_varp->cfg->serial1;
5219                     ep_3550->serial_number_word2 =
5220                         adv_dvc_varp->cfg->serial2;
5221                     ep_3550->serial_number_word3 =
5222                         adv_dvc_varp->cfg->serial3;
5223                 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
5224                 {
5225                     ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
5226 
5227                     ep_38C0800->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
5228                     ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
5229                     ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
5230                     ep_38C0800->termination_lvd =
5231                         adv_dvc_varp->cfg->termination;
5232                     ep_38C0800->disc_enable = adv_dvc_varp->cfg->disc_enable;
5233                     ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
5234                     ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
5235                     ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
5236                     ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
5237                     ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
5238                     ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
5239                     ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
5240                     ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
5241                     ep_38C0800->start_motor = adv_dvc_varp->start_motor;
5242                     ep_38C0800->scsi_reset_delay =
5243                         adv_dvc_varp->scsi_reset_wait;
5244                     ep_38C0800->serial_number_word1 =
5245                         adv_dvc_varp->cfg->serial1;
5246                     ep_38C0800->serial_number_word2 =
5247                         adv_dvc_varp->cfg->serial2;
5248                     ep_38C0800->serial_number_word3 =
5249                         adv_dvc_varp->cfg->serial3;
5250                 } else
5251                 {
5252                     ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
5253 
5254                     ep_38C1600->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
5255                     ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
5256                     ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
5257                     ep_38C1600->termination_lvd =
5258                         adv_dvc_varp->cfg->termination;
5259                     ep_38C1600->disc_enable = adv_dvc_varp->cfg->disc_enable;
5260                     ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
5261                     ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
5262                     ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
5263                     ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
5264                     ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
5265                     ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
5266                     ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
5267                     ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
5268                     ep_38C1600->start_motor = adv_dvc_varp->start_motor;
5269                     ep_38C1600->scsi_reset_delay =
5270                         adv_dvc_varp->scsi_reset_wait;
5271                     ep_38C1600->serial_number_word1 =
5272                         adv_dvc_varp->cfg->serial1;
5273                     ep_38C1600->serial_number_word2 =
5274                         adv_dvc_varp->cfg->serial2;
5275                     ep_38C1600->serial_number_word3 =
5276                         adv_dvc_varp->cfg->serial3;
5277                 }
5278 
5279                 /*
5280                  * Set the adapter's target id bit in the 'init_tidmask' field.
5281                  */
5282                 boardp->init_tidmask |=
5283                     ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
5284 
5285                 /*
5286                  * Finish initializing the 'Scsi_Host' structure.
5287                  */
5288                 shp->irq = adv_dvc_varp->irq_no;
5289             }
5290 
5291             /*
5292              * Channels are numbered beginning with 0. For AdvanSys one host
5293              * structure supports one channel. Multi-channel boards have a
5294              * separate host structure for each channel.
5295              */
5296             shp->max_channel = 0;
5297             if (ASC_NARROW_BOARD(boardp)) {
5298                 shp->max_id = ASC_MAX_TID + 1;
5299                 shp->max_lun = ASC_MAX_LUN + 1;
5300 
5301                 shp->io_port = asc_dvc_varp->iop_base;
5302                 boardp->asc_n_io_port = ASC_IOADR_GAP;
5303                 shp->this_id = asc_dvc_varp->cfg->chip_scsi_id;
5304 
5305                 /* Set maximum number of queues the adapter can handle. */
5306                 shp->can_queue = asc_dvc_varp->max_total_qng;
5307             } else {
5308                 shp->max_id = ADV_MAX_TID + 1;
5309                 shp->max_lun = ADV_MAX_LUN + 1;
5310 
5311                 /*
5312                  * Save the I/O Port address and length even though
5313                  * I/O ports are not used to access Wide boards.
5314                  * Instead the Wide boards are accessed with
5315                  * PCI Memory Mapped I/O.
5316                  */
5317                 shp->io_port = iop;
5318                 boardp->asc_n_io_port = iolen;
5319 
5320                 shp->this_id = adv_dvc_varp->chip_scsi_id;
5321 
5322                 /* Set maximum number of queues the adapter can handle. */
5323                 shp->can_queue = adv_dvc_varp->max_host_qng;
5324             }
5325 
5326             /*
5327              * 'n_io_port' currently is one byte.
5328              *
5329              * Set a value to 'n_io_port', but never referenced it because
5330              * it may be truncated.
5331              */
5332             shp->n_io_port = boardp->asc_n_io_port <= 255 ?
5333                 boardp->asc_n_io_port : 255;
5334 
5335             /*
5336              * Following v1.3.89, 'cmd_per_lun' is no longer needed
5337              * and should be set to zero.
5338              *
5339              * But because of a bug introduced in v1.3.89 if the driver is
5340              * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
5341              * SCSI function 'allocate_device' will panic. To allow the driver
5342              * to work as a module in these kernels set 'cmd_per_lun' to 1.
5343              */
5344 #ifdef MODULE
5345             shp->cmd_per_lun = 1;
5346 #else /* MODULE */
5347             shp->cmd_per_lun = 0;
5348 #endif /* MODULE */
5349             /*
5350              * Use the host 'select_queue_depths' function to determine
5351              * the number of commands to queue per device.
5352              */
5353             shp->select_queue_depths = advansys_select_queue_depths;
5354 
5355             /*
5356              * Set the maximum number of scatter-gather elements the
5357              * adapter can handle.
5358              */
5359             if (ASC_NARROW_BOARD(boardp)) {
5360                 /*
5361                  * Allow two commands with 'sg_tablesize' scatter-gather
5362                  * elements to be executed simultaneously. This value is
5363                  * the theoretical hardware limit. It may be decreased
5364                  * below.
5365                  */
5366                 shp->sg_tablesize =
5367                     (((asc_dvc_varp->max_total_qng - 2) / 2) *
5368                     ASC_SG_LIST_PER_Q) + 1;
5369             } else {
5370                 shp->sg_tablesize = ADV_MAX_SG_LIST;
5371             }
5372 
5373             /*
5374              * The value of 'sg_tablesize' can not exceed the SCSI
5375              * mid-level driver definition of SG_ALL. SG_ALL also
5376              * must not be exceeded, because it is used to define the
5377              * size of the scatter-gather table in 'struct asc_sg_head'.
5378              */
5379             if (shp->sg_tablesize > SG_ALL) {
5380                 shp->sg_tablesize = SG_ALL;
5381             }
5382 
5383             ASC_DBG1(1, "advansys_detect: sg_tablesize: %d\n",
5384                 shp->sg_tablesize);
5385 
5386             /* BIOS start address. */
5387             if (ASC_NARROW_BOARD(boardp)) {
5388 #if ASC_LINUX_KERNEL24
5389                 shp->base =
5390 #elif ASC_LINUX_KERNEL22
5391                 shp->base = (char *)
5392 #endif
5393                         ((ulong) AscGetChipBiosAddress(
5394                             asc_dvc_varp->iop_base,
5395                             asc_dvc_varp->bus_type));
5396             } else {
5397                 /*
5398                  * Fill-in BIOS board variables. The Wide BIOS saves
5399                  * information in LRAM that is used by the driver.
5400                  */
5401                 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_SIGNATURE,
5402                     boardp->bios_signature);
5403                 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_VERSION,
5404                     boardp->bios_version);
5405                 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODESEG,
5406                     boardp->bios_codeseg);
5407                 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODELEN,
5408                     boardp->bios_codelen);
5409 
5410                 ASC_DBG2(1,
5411                     "advansys_detect: bios_signature 0x%x, bios_version 0x%x\n",
5412                     boardp->bios_signature, boardp->bios_version);
5413 
5414                 ASC_DBG2(1,
5415                     "advansys_detect: bios_codeseg 0x%x, bios_codelen 0x%x\n",
5416                     boardp->bios_codeseg, boardp->bios_codelen);
5417 
5418                 /*
5419                  * If the BIOS saved a valid signature, then fill in
5420                  * the BIOS code segment base address.
5421                  */
5422                 if (boardp->bios_signature == 0x55AA) {
5423                     /*
5424                      * Convert x86 realmode code segment to a linear
5425                      * address by shifting left 4.
5426                      */
5427                     shp->base =
5428 #if ASC_LINUX_KERNEL22
5429                         (char *)
5430 #endif
5431                         ((ulong) boardp->bios_codeseg << 4);
5432                 } else {
5433                     shp->base = 0;
5434                 }
5435             }
5436 
5437             /*
5438              * Register Board Resources - I/O Port, DMA, IRQ
5439              */
5440 
5441             /*
5442              * Register I/O port range.
5443              *
5444              * For Wide boards the I/O ports are not used to access
5445              * the board, but request the region anyway.
5446              *
5447              * 'shp->n_io_port' is not referenced, because it may be truncated.
5448              */
5449             ASC_DBG2(2,
5450                 "advansys_detect: request_region port 0x%lx, len 0x%x\n",
5451                 (ulong) shp->io_port, boardp->asc_n_io_port);
5452 #if ASC_LINUX_KERNEL24
5453             if (request_region(shp->io_port, boardp->asc_n_io_port,
5454                                "advansys") == NULL) {
5455                 ASC_PRINT3(
5456 "advansys_detect: board %d: request_region() failed, port 0x%lx, len 0x%x\n",
5457                     boardp->id, (ulong) shp->io_port, boardp->asc_n_io_port);
5458 #ifdef CONFIG_PROC_FS
5459                 kfree(boardp->prtbuf);
5460 #endif /* CONFIG_PROC_FS */
5461                 scsi_unregister(shp);
5462                 asc_board_count--;
5463                 continue;
5464             }
5465 #elif ASC_LINUX_KERNEL22
5466             request_region(shp->io_port, boardp->asc_n_io_port, "advansys");
5467 #endif
5468 
5469             /* Register DMA Channel for Narrow boards. */
5470             shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
5471 #ifdef CONFIG_ISA
5472             if (ASC_NARROW_BOARD(boardp)) {
5473                 /* Register DMA channel for ISA bus. */
5474                 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5475                     shp->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
5476                     if ((ret =
5477                          request_dma(shp->dma_channel, "advansys")) != 0) {
5478                         ASC_PRINT3(
5479 "advansys_detect: board %d: request_dma() %d failed %d\n",
5480                             boardp->id, shp->dma_channel, ret);
5481                         release_region(shp->io_port, boardp->asc_n_io_port);
5482 #ifdef CONFIG_PROC_FS
5483                         kfree(boardp->prtbuf);
5484 #endif /* CONFIG_PROC_FS */
5485                         scsi_unregister(shp);
5486                         asc_board_count--;
5487                         continue;
5488                     }
5489                     AscEnableIsaDma(shp->dma_channel);
5490                 }
5491             }
5492 #endif /* CONFIG_ISA */
5493 
5494             /* Register IRQ Number. */
5495             ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
5496            /*
5497             * If request_irq() fails with the SA_INTERRUPT flag set,
5498             * then try again without the SA_INTERRUPT flag set. This
5499             * allows IRQ sharing to work even with other drivers that
5500             * do not set the SA_INTERRUPT flag.
5501             *
5502             * If SA_INTERRUPT is not set, then interrupts are enabled
5503             * before the driver interrupt function is called.
5504             */
5505             if (((ret = request_irq(shp->irq, advansys_interrupt,
5506                             SA_INTERRUPT | (share_irq == TRUE ? SA_SHIRQ : 0),
5507                             "advansys", boardp)) != 0) &&
5508                 ((ret = request_irq(shp->irq, advansys_interrupt,
5509                             (share_irq == TRUE ? SA_SHIRQ : 0),
5510                             "advansys", boardp)) != 0))
5511             {
5512                 if (ret == -EBUSY) {
5513                     ASC_PRINT2(
5514 "advansys_detect: board %d: request_irq(): IRQ 0x%x already in use.\n",
5515                         boardp->id, shp->irq);
5516                 } else if (ret == -EINVAL) {
5517                     ASC_PRINT2(
5518 "advansys_detect: board %d: request_irq(): IRQ 0x%x not valid.\n",
5519                         boardp->id, shp->irq);
5520                 } else {
5521                     ASC_PRINT3(
5522 "advansys_detect: board %d: request_irq(): IRQ 0x%x failed with %d\n",
5523                         boardp->id, shp->irq, ret);
5524                 }
5525                 release_region(shp->io_port, boardp->asc_n_io_port);
5526                 iounmap(boardp->ioremap_addr);
5527                 if (shp->dma_channel != NO_ISA_DMA) {
5528                     free_dma(shp->dma_channel);
5529                 }
5530 #ifdef CONFIG_PROC_FS
5531                 kfree(boardp->prtbuf);
5532 #endif /* CONFIG_PROC_FS */
5533                 scsi_unregister(shp);
5534                 asc_board_count--;
5535                 continue;
5536             }
5537 
5538             /*
5539              * Initialize board RISC chip and enable interrupts.
5540              */
5541             if (ASC_NARROW_BOARD(boardp)) {
5542                 ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n");
5543                 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
5544                 err_code = asc_dvc_varp->err_code;
5545 
5546                 if (warn_code || err_code) {
5547                     ASC_PRINT4(
5548 "advansys_detect: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
5549                         boardp->id, asc_dvc_varp->init_state,
5550                         warn_code, err_code);
5551                 }
5552             } else {
5553                 ADV_CARR_T      *carrp;
5554                 int             req_cnt = 0;
5555                 adv_req_t       *reqp = NULL;
5556                 int             sg_cnt = 0;
5557 
5558                 /*
5559                  * Allocate buffer carrier structures. The total size
5560                  * is about 4 KB, so allocate all at once.
5561                  */
5562                 carrp =
5563                     (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC);
5564                 ASC_DBG1(1, "advansys_detect: carrp 0x%lx\n", (ulong) carrp);
5565 
5566                 if (carrp == NULL) {
5567                     goto kmalloc_error;
5568                 }
5569 
5570                 /*
5571                  * Allocate up to 'max_host_qng' request structures for
5572                  * the Wide board. The total size is about 16 KB, so
5573                  * allocate all at once. If the allocation fails decrement
5574                  * and try again.
5575                  */
5576                 for (req_cnt = adv_dvc_varp->max_host_qng;
5577                     req_cnt > 0; req_cnt--) {
5578 
5579                     reqp = (adv_req_t *)
5580                         kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC);
5581 
5582                     ASC_DBG3(1,
5583                         "advansys_detect: reqp 0x%lx, req_cnt %d, bytes %lu\n",
5584                         (ulong) reqp, req_cnt,
5585                         (ulong) sizeof(adv_req_t) * req_cnt);
5586 
5587                     if (reqp != NULL) {
5588                         break;
5589                     }
5590                 }
5591                 if (reqp == NULL)
5592                 {
5593                     goto kmalloc_error;
5594                 }
5595 
5596                 /*
5597                  * Allocate up to ADV_TOT_SG_BLOCK request structures for
5598                  * the Wide board. Each structure is about 136 bytes.
5599                  */
5600                 boardp->adv_sgblkp = NULL;
5601                 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
5602 
5603                     sgp = (adv_sgblk_t *)
5604                         kmalloc(sizeof(adv_sgblk_t), GFP_ATOMIC);
5605 
5606                     if (sgp == NULL) {
5607                         break;
5608                     }
5609 
5610                     sgp->next_sgblkp = boardp->adv_sgblkp;
5611                     boardp->adv_sgblkp = sgp;
5612 
5613                 }
5614                 ASC_DBG3(1,
5615                     "advansys_detect: sg_cnt %d * %u = %u bytes\n",
5616                     sg_cnt, sizeof(adv_sgblk_t),
5617                     (unsigned) (sizeof(adv_sgblk_t) * sg_cnt));
5618 
5619                 /*
5620                  * If no request structures or scatter-gather structures could
5621                  * be allocated, then return an error. Otherwise continue with
5622                  * initialization.
5623                  */
5624     kmalloc_error:
5625                 if (carrp == NULL)
5626                 {
5627                     ASC_PRINT1(
5628 "advansys_detect: board %d error: failed to kmalloc() carrier buffer.\n",
5629                         boardp->id);
5630                     err_code = ADV_ERROR;
5631                 } else if (reqp == NULL) {
5632                     kfree(carrp);
5633                     ASC_PRINT1(
5634 "advansys_detect: board %d error: failed to kmalloc() adv_req_t buffer.\n",
5635                         boardp->id);
5636                     err_code = ADV_ERROR;
5637                 } else if (boardp->adv_sgblkp == NULL) {
5638                     kfree(carrp);
5639                     kfree(reqp);
5640                     ASC_PRINT1(
5641 "advansys_detect: board %d error: failed to kmalloc() adv_sgblk_t buffers.\n",
5642                         boardp->id);
5643                     err_code = ADV_ERROR;
5644                 } else {
5645 
5646                     /* Save carrier buffer pointer. */
5647                     boardp->orig_carrp = carrp;
5648 
5649                     /*
5650                      * Save original pointer for kfree() in case the
5651                      * driver is built as a module and can be unloaded.
5652                      */
5653                     boardp->orig_reqp = reqp;
5654 
5655                     adv_dvc_varp->carrier_buf = carrp;
5656 
5657                     /*
5658                      * Point 'adv_reqp' to the request structures and
5659                      * link them together.
5660                      */
5661                     req_cnt--;
5662                     reqp[req_cnt].next_reqp = NULL;
5663                     for (; req_cnt > 0; req_cnt--) {
5664                         reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
5665                     }
5666                     boardp->adv_reqp = &reqp[0];
5667 
5668                     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5669                     {
5670                         ASC_DBG(2,
5671                             "advansys_detect: AdvInitAsc3550Driver()\n");
5672                         warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
5673                     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5674                         ASC_DBG(2,
5675                             "advansys_detect: AdvInitAsc38C0800Driver()\n");
5676                         warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
5677                     } else {
5678                         ASC_DBG(2,
5679                             "advansys_detect: AdvInitAsc38C1600Driver()\n");
5680                         warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
5681                     }
5682                     err_code = adv_dvc_varp->err_code;
5683 
5684                     if (warn_code || err_code) {
5685                         ASC_PRINT3(
5686 "advansys_detect: board %d error: warn 0x%x, error 0x%x\n",
5687                             boardp->id, warn_code, err_code);
5688                     }
5689                 }
5690             }
5691 
5692             if (err_code != 0) {
5693                 release_region(shp->io_port, boardp->asc_n_io_port);
5694                 if (ASC_WIDE_BOARD(boardp)) {
5695                     iounmap(boardp->ioremap_addr);
5696                     if (boardp->orig_carrp) {
5697                         kfree(boardp->orig_carrp);
5698                         boardp->orig_carrp = NULL;
5699                     }
5700                     if (boardp->orig_reqp) {
5701                         kfree(boardp->orig_reqp);
5702                         boardp->orig_reqp = boardp->adv_reqp = NULL;
5703                     }
5704                     while ((sgp = boardp->adv_sgblkp) != NULL)
5705                     {
5706                         boardp->adv_sgblkp = sgp->next_sgblkp;
5707                         kfree(sgp);
5708                     }
5709                 }
5710                 if (shp->dma_channel != NO_ISA_DMA) {
5711                     free_dma(shp->dma_channel);
5712                 }
5713 #ifdef CONFIG_PROC_FS
5714                 kfree(boardp->prtbuf);
5715 #endif /* CONFIG_PROC_FS */
5716                 free_irq(shp->irq, boardp);
5717                 scsi_unregister(shp);
5718                 asc_board_count--;
5719                 continue;
5720             }
5721             ASC_DBG_PRT_SCSI_HOST(2, shp);
5722         }
5723     }
5724 
5725     /*
5726      * XXX - Remove this comment and the next line when SCSI mid-level
5727      * no longer acquires 'io_request_lock' before calling the SCSI
5728      * low-level detect entrypoint.
5729      */
5730     ASC_LOCK_IO_REQUEST_LOCK
5731 
5732     ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count);
5733     return asc_board_count;
5734 }
5735 
5736 /*
5737  * advansys_release()
5738  *
5739  * Release resources allocated for a single AdvanSys adapter.
5740  */
5741 int
advansys_release(struct Scsi_Host * shp)5742 advansys_release(struct Scsi_Host *shp)
5743 {
5744     asc_board_t    *boardp;
5745 
5746     ASC_DBG(1, "advansys_release: begin\n");
5747     boardp = ASC_BOARDP(shp);
5748     free_irq(shp->irq, boardp);
5749     if (shp->dma_channel != NO_ISA_DMA) {
5750         ASC_DBG(1, "advansys_release: free_dma()\n");
5751         free_dma(shp->dma_channel);
5752     }
5753     release_region(shp->io_port, boardp->asc_n_io_port);
5754     if (ASC_WIDE_BOARD(boardp)) {
5755         adv_sgblk_t    *sgp = NULL;
5756 
5757         iounmap(boardp->ioremap_addr);
5758         if (boardp->orig_carrp) {
5759             kfree(boardp->orig_carrp);
5760             boardp->orig_carrp = NULL;
5761         }
5762         if (boardp->orig_reqp) {
5763             kfree(boardp->orig_reqp);
5764             boardp->orig_reqp = boardp->adv_reqp = NULL;
5765         }
5766         while ((sgp = boardp->adv_sgblkp) != NULL)
5767         {
5768             boardp->adv_sgblkp = sgp->next_sgblkp;
5769             kfree(sgp);
5770         }
5771     }
5772 #ifdef CONFIG_PROC_FS
5773     ASC_ASSERT(boardp->prtbuf != NULL);
5774     kfree(boardp->prtbuf);
5775 #endif /* CONFIG_PROC_FS */
5776     scsi_unregister(shp);
5777     ASC_DBG(1, "advansys_release: end\n");
5778     return 0;
5779 }
5780 
5781 /*
5782  * advansys_info()
5783  *
5784  * Return suitable for printing on the console with the argument
5785  * adapter's configuration information.
5786  *
5787  * Note: The information line should not exceed ASC_INFO_SIZE bytes,
5788  * otherwise the static 'info' array will be overrun.
5789  */
5790 const char *
advansys_info(struct Scsi_Host * shp)5791 advansys_info(struct Scsi_Host *shp)
5792 {
5793     static char     info[ASC_INFO_SIZE];
5794     asc_board_t     *boardp;
5795     ASC_DVC_VAR     *asc_dvc_varp;
5796     ADV_DVC_VAR     *adv_dvc_varp;
5797     char            *busname;
5798     int             iolen;
5799     char            *widename = NULL;
5800 
5801     boardp = ASC_BOARDP(shp);
5802     if (ASC_NARROW_BOARD(boardp)) {
5803         asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5804         ASC_DBG(1, "advansys_info: begin\n");
5805         if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5806             if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == ASC_IS_ISAPNP) {
5807                 busname = "ISA PnP";
5808             } else {
5809                 busname = "ISA";
5810             }
5811             /* Don't reference 'shp->n_io_port'; It may be truncated. */
5812             sprintf(info,
5813 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
5814                 ASC_VERSION, busname,
5815                 (ulong) shp->io_port,
5816                 (ulong) shp->io_port + boardp->asc_n_io_port - 1,
5817                 shp->irq, shp->dma_channel);
5818         } else {
5819             if (asc_dvc_varp->bus_type & ASC_IS_VL) {
5820                 busname = "VL";
5821             } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
5822                 busname = "EISA";
5823             } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
5824                 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
5825                     == ASC_IS_PCI_ULTRA) {
5826                     busname = "PCI Ultra";
5827                 } else {
5828                     busname = "PCI";
5829                 }
5830             } else {
5831                 busname = "?";
5832                 ASC_PRINT2( "advansys_info: board %d: unknown bus type %d\n",
5833                     boardp->id, asc_dvc_varp->bus_type);
5834             }
5835             /* Don't reference 'shp->n_io_port'; It may be truncated. */
5836             sprintf(info,
5837                 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
5838                 ASC_VERSION, busname,
5839                 (ulong) shp->io_port,
5840                 (ulong) shp->io_port + boardp->asc_n_io_port - 1,
5841                 shp->irq);
5842         }
5843     } else {
5844         /*
5845          * Wide Adapter Information
5846          *
5847          * Memory-mapped I/O is used instead of I/O space to access
5848          * the adapter, but display the I/O Port range. The Memory
5849          * I/O address is displayed through the driver /proc file.
5850          */
5851         adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5852         if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5853         {
5854             iolen = ADV_3550_IOLEN;
5855             widename = "Ultra-Wide";
5856         } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
5857         {
5858             iolen = ADV_38C0800_IOLEN;
5859             widename = "Ultra2-Wide";
5860         } else
5861         {
5862             iolen = ADV_38C1600_IOLEN;
5863             widename = "Ultra3-Wide";
5864         }
5865         sprintf(info, "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
5866             ASC_VERSION,
5867             widename,
5868             (ulong) adv_dvc_varp->iop_base,
5869             (ulong) adv_dvc_varp->iop_base + iolen - 1,
5870             shp->irq);
5871     }
5872     ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
5873     ASC_DBG(1, "advansys_info: end\n");
5874     return info;
5875 }
5876 
5877 /*
5878  * advansys_queuecommand() - interrupt-driven I/O entrypoint.
5879  *
5880  * This function always returns 0. Command return status is saved
5881  * in the 'scp' result field.
5882  */
5883 int
advansys_queuecommand(Scsi_Cmnd * scp,void (* done)(Scsi_Cmnd *))5884 advansys_queuecommand(Scsi_Cmnd *scp, void (*done)(Scsi_Cmnd *))
5885 {
5886     struct Scsi_Host    *shp;
5887     asc_board_t         *boardp;
5888     ulong               flags;
5889     Scsi_Cmnd           *done_scp;
5890 
5891     shp = scp->host;
5892     boardp = ASC_BOARDP(shp);
5893     ASC_STATS(shp, queuecommand);
5894 
5895     /*
5896      * XXX - Remove this comment and the next line when SCSI mid-level
5897      * no longer acquires 'io_request_lock' before calling the SCSI
5898      * low-level queuecommand entrypoint.
5899      */
5900     ASC_UNLOCK_IO_REQUEST_LOCK
5901 
5902     spin_lock_irqsave(&boardp->lock, flags);
5903 
5904     /*
5905      * Block new commands while handling a reset or abort request.
5906      */
5907     if (boardp->flags & ASC_HOST_IN_RESET) {
5908         ASC_DBG1(1,
5909             "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
5910             (ulong) scp);
5911         scp->result = HOST_BYTE(DID_RESET);
5912 
5913         /*
5914          * Add blocked requests to the board's 'done' queue. The queued
5915          * requests will be completed at the end of the abort or reset
5916          * handling.
5917          */
5918         asc_enqueue(&boardp->done, scp, ASC_BACK);
5919         spin_unlock_irqrestore(&boardp->lock, flags);
5920         return 0;
5921     }
5922 
5923     /*
5924      * Attempt to execute any waiting commands for the board.
5925      */
5926     if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
5927         ASC_DBG(1,
5928             "advansys_queuecommand: before asc_execute_queue() waiting\n");
5929         asc_execute_queue(&boardp->waiting);
5930     }
5931 
5932     /*
5933      * Save the function pointer to Linux mid-level 'done' function
5934      * and attempt to execute the command.
5935      *
5936      * If ASC_NOERROR is returned the request has been added to the
5937      * board's 'active' queue and will be completed by the interrupt
5938      * handler.
5939      *
5940      * If ASC_BUSY is returned add the request to the board's per
5941      * target waiting list. This is the first time the request has
5942      * been tried. Add it to the back of the waiting list. It will be
5943      * retried later.
5944      *
5945      * If an error occurred, the request will have been placed on the
5946      * board's 'done' queue and must be completed before returning.
5947      */
5948     scp->scsi_done = done;
5949     switch (asc_execute_scsi_cmnd(scp)) {
5950     case ASC_NOERROR:
5951         break;
5952     case ASC_BUSY:
5953         asc_enqueue(&boardp->waiting, scp, ASC_BACK);
5954         break;
5955     case ASC_ERROR:
5956     default:
5957         done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
5958         /* Interrupts could be enabled here. */
5959         asc_scsi_done_list(done_scp);
5960         break;
5961     }
5962 
5963     spin_unlock_irqrestore(&boardp->lock, flags);
5964 
5965     /*
5966      * XXX - Remove this comment and the next line when SCSI mid-level
5967      * no longer acquires 'io_request_lock' before calling the SCSI
5968      * low-level queuecommand entrypoint.
5969      */
5970     ASC_LOCK_IO_REQUEST_LOCK
5971 
5972     return 0;
5973 }
5974 
5975 /*
5976  * advansys_reset()
5977  *
5978  * Reset the bus associated with the command 'scp'.
5979  *
5980  * This function runs its own thread. Interrupts must be blocked but
5981  * sleeping is allowed and no locking other than for host structures is
5982  * required. Returns SUCCESS or FAILED.
5983  */
5984 int
advansys_reset(Scsi_Cmnd * scp)5985 advansys_reset(Scsi_Cmnd *scp)
5986 {
5987     struct Scsi_Host     *shp;
5988     asc_board_t          *boardp;
5989     ASC_DVC_VAR          *asc_dvc_varp;
5990     ADV_DVC_VAR          *adv_dvc_varp;
5991     ulong                flags;
5992     Scsi_Cmnd            *done_scp = NULL, *last_scp = NULL;
5993     Scsi_Cmnd            *tscp, *new_last_scp;
5994     int                  status;
5995     int                  ret = SUCCESS;
5996 
5997     ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong) scp);
5998 
5999 #ifdef ADVANSYS_STATS
6000     if (scp->host != NULL) {
6001         ASC_STATS(scp->host, reset);
6002     }
6003 #endif /* ADVANSYS_STATS */
6004 
6005     if ((shp = scp->host) == NULL) {
6006         scp->result = HOST_BYTE(DID_ERROR);
6007         return FAILED;
6008     }
6009 
6010     boardp = ASC_BOARDP(shp);
6011 
6012     ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
6013         boardp->id);
6014     /*
6015      * Check for re-entrancy.
6016      */
6017     spin_lock_irqsave(&boardp->lock, flags);
6018     if (boardp->flags & ASC_HOST_IN_RESET) {
6019         spin_unlock_irqrestore(&boardp->lock, flags);
6020         return FAILED;
6021     }
6022     boardp->flags |= ASC_HOST_IN_RESET;
6023     spin_unlock_irqrestore(&boardp->lock, flags);
6024 
6025     /*
6026      * XXX - Remove this comment and the next line when SCSI mid-level
6027      * no longer acquires 'io_request_lock' before calling the SCSI
6028      * low-level reset entrypoint.
6029      */
6030     ASC_UNLOCK_IO_REQUEST_LOCK
6031 
6032     if (ASC_NARROW_BOARD(boardp)) {
6033         /*
6034          * Narrow Board
6035          */
6036         asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6037 
6038         /*
6039          * Reset the chip and SCSI bus.
6040          */
6041         ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
6042         status = AscInitAsc1000Driver(asc_dvc_varp);
6043 
6044         /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
6045         if (asc_dvc_varp->err_code) {
6046             ASC_PRINT2(
6047                 "advansys_reset: board %d: SCSI bus reset error: 0x%x\n",
6048                 boardp->id, asc_dvc_varp->err_code);
6049             ret = FAILED;
6050         } else if (status) {
6051             ASC_PRINT2(
6052                 "advansys_reset: board %d: SCSI bus reset warning: 0x%x\n",
6053                 boardp->id, status);
6054         } else {
6055             ASC_PRINT1(
6056                 "advansys_reset: board %d: SCSI bus reset successful.\n",
6057                 boardp->id);
6058         }
6059 
6060         ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
6061 
6062         /*
6063          * Acquire the board lock.
6064          */
6065         spin_lock_irqsave(&boardp->lock, flags);
6066 
6067     } else {
6068         /*
6069          * Wide Board
6070          *
6071          * If the suggest reset bus flags are set, then reset the bus.
6072          * Otherwise only reset the device.
6073          */
6074         adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6075 
6076         /*
6077          * Reset the target's SCSI bus.
6078          */
6079         ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
6080         switch (AdvResetChipAndSB(adv_dvc_varp)) {
6081         case ASC_TRUE:
6082             ASC_PRINT1("advansys_reset: board %d: SCSI bus reset successful.\n",
6083                 boardp->id);
6084             break;
6085         case ASC_FALSE:
6086         default:
6087             ASC_PRINT1("advansys_reset: board %d: SCSI bus reset error.\n",
6088                 boardp->id);
6089             ret = FAILED;
6090             break;
6091         }
6092         /*
6093          * Acquire the board lock and ensure all requests completed by the
6094          * microcode have been processed by calling AdvISR().
6095          */
6096         spin_lock_irqsave(&boardp->lock, flags);
6097         (void) AdvISR(adv_dvc_varp);
6098     }
6099 
6100     /* Board lock is held. */
6101 
6102     /*
6103      * Dequeue all board 'done' requests. A pointer to the last request
6104      * is returned in 'last_scp'.
6105      */
6106     done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
6107 
6108     /*
6109      * Dequeue all board 'active' requests for all devices and set
6110      * the request status to DID_RESET. A pointer to the last request
6111      * is returned in 'last_scp'.
6112      */
6113     if (done_scp == NULL) {
6114         done_scp = asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL);
6115         for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
6116             tscp->result = HOST_BYTE(DID_RESET);
6117         }
6118     } else {
6119         /* Append to 'done_scp' at the end with 'last_scp'. */
6120         ASC_ASSERT(last_scp != NULL);
6121         last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
6122 			&boardp->active, &new_last_scp, ASC_TID_ALL);
6123         if (new_last_scp != NULL) {
6124             ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6125             for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
6126                 tscp->result = HOST_BYTE(DID_RESET);
6127             }
6128             last_scp = new_last_scp;
6129         }
6130     }
6131 
6132     /*
6133      * Dequeue all 'waiting' requests and set the request status
6134      * to DID_RESET.
6135      */
6136     if (done_scp == NULL) {
6137         done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL);
6138         for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
6139             tscp->result = HOST_BYTE(DID_RESET);
6140         }
6141     } else {
6142         /* Append to 'done_scp' at the end with 'last_scp'. */
6143         ASC_ASSERT(last_scp != NULL);
6144         last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
6145 			&boardp->waiting, &new_last_scp, ASC_TID_ALL);
6146         if (new_last_scp != NULL) {
6147             ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6148             for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
6149                 tscp->result = HOST_BYTE(DID_RESET);
6150             }
6151             last_scp = new_last_scp;
6152         }
6153     }
6154 
6155     /* Save the time of the most recently completed reset. */
6156     boardp->last_reset = jiffies;
6157 
6158     /* Clear reset flag. */
6159     boardp->flags &= ~ASC_HOST_IN_RESET;
6160 
6161     /* Release the board. */
6162     spin_unlock_irqrestore(&boardp->lock, flags);
6163 
6164     /*
6165      * Complete all the 'done_scp' requests.
6166      */
6167     if (done_scp != NULL) {
6168         asc_scsi_done_list(done_scp);
6169     }
6170 
6171     /*
6172      * XXX - Remove this comment and the next line when SCSI mid-level
6173      * no longer acquires 'io_request_lock' before calling the SCSI
6174      * low-level reset entrypoint.
6175      */
6176     ASC_LOCK_IO_REQUEST_LOCK
6177 
6178     ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
6179 
6180     return ret;
6181 }
6182 
6183 /*
6184  * advansys_biosparam()
6185  *
6186  * Translate disk drive geometry if the "BIOS greater than 1 GB"
6187  * support is enabled for a drive.
6188  *
6189  * ip (information pointer) is an int array with the following definition:
6190  * ip[0]: heads
6191  * ip[1]: sectors
6192  * ip[2]: cylinders
6193  */
6194 int
advansys_biosparam(Disk * dp,kdev_t dep,int ip[])6195 advansys_biosparam(Disk *dp, kdev_t dep, int ip[])
6196 {
6197     asc_board_t     *boardp;
6198 
6199     ASC_DBG(1, "advansys_biosparam: begin\n");
6200     ASC_STATS(dp->device->host, biosparam);
6201     boardp = ASC_BOARDP(dp->device->host);
6202     if (ASC_NARROW_BOARD(boardp)) {
6203         if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
6204              ASC_CNTL_BIOS_GT_1GB) && dp->capacity > 0x200000) {
6205                 ip[0] = 255;
6206                 ip[1] = 63;
6207         } else {
6208                 ip[0] = 64;
6209                 ip[1] = 32;
6210         }
6211     } else {
6212         if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
6213              BIOS_CTRL_EXTENDED_XLAT) && dp->capacity > 0x200000) {
6214                 ip[0] = 255;
6215                 ip[1] = 63;
6216         } else {
6217                 ip[0] = 64;
6218                 ip[1] = 32;
6219         }
6220     }
6221     ip[2] = dp->capacity / (ip[0] * ip[1]);
6222     ASC_DBG(1, "advansys_biosparam: end\n");
6223     return 0;
6224 }
6225 
6226 /*
6227  * advansys_setup()
6228  *
6229  * This function is called from init/main.c at boot time.
6230  * It it passed LILO parameters that can be set from the
6231  * LILO command line or in /etc/lilo.conf.
6232  *
6233  * It is used by the AdvanSys driver to either disable I/O
6234  * port scanning or to limit scanning to 1 - 4 I/O ports.
6235  * Regardless of the option setting EISA and PCI boards
6236  * will still be searched for and detected. This option
6237  * only affects searching for ISA and VL boards.
6238  *
6239  * If ADVANSYS_DEBUG is defined the driver debug level may
6240  * be set using the 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port.
6241  *
6242  * Examples:
6243  * 1. Eliminate I/O port scanning:
6244  *         boot: linux advansys=
6245  *       or
6246  *         boot: linux advansys=0x0
6247  * 2. Limit I/O port scanning to one I/O port:
6248  *        boot: linux advansys=0x110
6249  * 3. Limit I/O port scanning to four I/O ports:
6250  *        boot: linux advansys=0x110,0x210,0x230,0x330
6251  * 4. If ADVANSYS_DEBUG, limit I/O port scanning to four I/O ports and
6252  *    set the driver debug level to 2.
6253  *        boot: linux advansys=0x110,0x210,0x230,0x330,0xdeb2
6254  *
6255  * ints[0] - number of arguments
6256  * ints[1] - first argument
6257  * ints[2] - second argument
6258  * ...
6259  */
ASC_INITFUNC(void,advansys_setup (char * str,int * ints))6260 ASC_INITFUNC(
6261 void,
6262 advansys_setup(char *str, int *ints)
6263 )
6264 {
6265     int    i;
6266 
6267     if (asc_iopflag == ASC_TRUE) {
6268         printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n");
6269         return;
6270     }
6271 
6272     asc_iopflag = ASC_TRUE;
6273 
6274     if (ints[0] > ASC_NUM_IOPORT_PROBE) {
6275 #ifdef ADVANSYS_DEBUG
6276         if ((ints[0] == ASC_NUM_IOPORT_PROBE + 1) &&
6277             (ints[ASC_NUM_IOPORT_PROBE + 1] >> 4 == 0xdeb)) {
6278             asc_dbglvl = ints[ASC_NUM_IOPORT_PROBE + 1] & 0xf;
6279         } else {
6280 #endif /* ADVANSYS_DEBUG */
6281             printk("AdvanSys SCSI: only %d I/O ports accepted\n",
6282                 ASC_NUM_IOPORT_PROBE);
6283 #ifdef ADVANSYS_DEBUG
6284         }
6285 #endif /* ADVANSYS_DEBUG */
6286     }
6287 
6288 #ifdef ADVANSYS_DEBUG
6289     ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]);
6290     for (i = 1; i < ints[0]; i++) {
6291         ASC_DBG2(1, " ints[%d] 0x%x", i, ints[i]);
6292     }
6293     ASC_DBG(1, "\n");
6294 #endif /* ADVANSYS_DEBUG */
6295 
6296     for (i = 1; i <= ints[0] && i <= ASC_NUM_IOPORT_PROBE; i++) {
6297         asc_ioport[i-1] = ints[i];
6298         ASC_DBG2(1, "advansys_setup: asc_ioport[%d] 0x%x\n",
6299             i - 1, asc_ioport[i-1]);
6300     }
6301 }
6302 
6303 
6304 /*
6305  * --- Loadable Driver Support
6306  */
6307 
6308 #if ASC_LINUX_KERNEL24
6309 static
6310 #endif
6311 #if ASC_LINUX_KERNEL24 || (ASC_LINUX_KERNEL22 && defined(MODULE))
6312 Scsi_Host_Template driver_template = ADVANSYS;
6313 # include "scsi_module.c"
6314 #endif
6315 
6316 
6317 /*
6318  * --- Miscellaneous Driver Functions
6319  */
6320 
6321 /*
6322  * First-level interrupt handler.
6323  *
6324  * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
6325  * all boards are currently checked for interrupts on each interrupt, 'dev_id'
6326  * is not referenced. 'dev_id' could be used to identify an interrupt passed
6327  * to the AdvanSys driver which is for a device sharing an interrupt with
6328  * an AdvanSys adapter.
6329  */
6330 STATIC void
advansys_interrupt(int irq,void * dev_id,struct pt_regs * regs)6331 advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs)
6332 {
6333     ulong           flags;
6334     int             i;
6335     asc_board_t     *boardp;
6336     Scsi_Cmnd       *done_scp = NULL, *last_scp = NULL;
6337     Scsi_Cmnd       *new_last_scp;
6338 
6339     ASC_DBG(1, "advansys_interrupt: begin\n");
6340 
6341     /*
6342      * Check for interrupts on all boards.
6343      * AscISR() will call asc_isr_callback().
6344      */
6345     for (i = 0; i < asc_board_count; i++) {
6346         boardp = ASC_BOARDP(asc_host[i]);
6347         ASC_DBG2(2, "advansys_interrupt: i %d, boardp 0x%lx\n",
6348             i, (ulong) boardp);
6349         spin_lock_irqsave(&boardp->lock, flags);
6350         if (ASC_NARROW_BOARD(boardp)) {
6351             /*
6352              * Narrow Board
6353              */
6354             if (AscIsIntPending(asc_host[i]->io_port)) {
6355                 ASC_STATS(asc_host[i], interrupt);
6356                 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
6357                 AscISR(&boardp->dvc_var.asc_dvc_var);
6358             }
6359         } else {
6360             /*
6361              * Wide Board
6362              */
6363             ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
6364             if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
6365                 ASC_STATS(asc_host[i], interrupt);
6366             }
6367         }
6368 
6369         /*
6370          * Start waiting requests and create a list of completed requests.
6371          *
6372          * If a reset request is being performed for the board, the reset
6373          * handler will complete pending requests after it has completed.
6374          */
6375         if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
6376             ASC_DBG2(1, "advansys_interrupt: done_scp 0x%lx, last_scp 0x%lx\n",
6377                 (ulong) done_scp, (ulong) last_scp);
6378 
6379             /* Start any waiting commands for the board. */
6380             if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
6381                 ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
6382                 asc_execute_queue(&boardp->waiting);
6383             }
6384 
6385              /*
6386               * Add to the list of requests that must be completed.
6387               *
6388               * 'done_scp' will always be NULL on the first iteration
6389               * of this loop. 'last_scp' is set at the same time as
6390               * 'done_scp'.
6391               */
6392             if (done_scp == NULL) {
6393                 done_scp = asc_dequeue_list(&boardp->done, &last_scp,
6394                     ASC_TID_ALL);
6395             } else {
6396                 ASC_ASSERT(last_scp != NULL);
6397                 last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
6398 			&boardp->done, &new_last_scp, ASC_TID_ALL);
6399                 if (new_last_scp != NULL) {
6400                     ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6401                     last_scp = new_last_scp;
6402                 }
6403             }
6404         }
6405         spin_unlock_irqrestore(&boardp->lock, flags);
6406     }
6407 
6408     /*
6409      * If interrupts were enabled on entry, then they
6410      * are now enabled here.
6411      *
6412      * Complete all requests on the done list.
6413      */
6414     asc_scsi_done_list(done_scp);
6415 
6416     ASC_DBG(1, "advansys_interrupt: end\n");
6417     return;
6418 }
6419 
6420 /*
6421  * Set the number of commands to queue per device for the
6422  * specified host adapter.
6423  */
6424 STATIC void
advansys_select_queue_depths(struct Scsi_Host * shp,Scsi_Device * devicelist)6425 advansys_select_queue_depths(struct Scsi_Host *shp, Scsi_Device *devicelist)
6426 {
6427     Scsi_Device        *device;
6428     asc_board_t        *boardp;
6429 
6430     boardp = ASC_BOARDP(shp);
6431     boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
6432     for (device = devicelist; device != NULL; device = device->next) {
6433         if (device->host != shp) {
6434             continue;
6435         }
6436         /*
6437          * Save a pointer to the device and set its initial/maximum
6438          * queue depth.
6439          */
6440         boardp->device[device->id] = device;
6441         if (ASC_NARROW_BOARD(boardp)) {
6442             device->queue_depth =
6443                 boardp->dvc_var.asc_dvc_var.max_dvc_qng[device->id];
6444         } else {
6445             device->queue_depth =
6446                 boardp->dvc_var.adv_dvc_var.max_dvc_qng;
6447         }
6448         ASC_DBG3(1,
6449             "advansys_select_queue_depths: shp 0x%lx, id %d, depth %d\n",
6450             (ulong) shp, device->id, device->queue_depth);
6451     }
6452 }
6453 
6454 /*
6455  * Complete all requests on the singly linked list pointed
6456  * to by 'scp'.
6457  *
6458  * Interrupts can be enabled on entry.
6459  */
6460 STATIC void
asc_scsi_done_list(Scsi_Cmnd * scp)6461 asc_scsi_done_list(Scsi_Cmnd *scp)
6462 {
6463     Scsi_Cmnd    *tscp;
6464 
6465     ASC_DBG(2, "asc_scsi_done_list: begin\n");
6466     while (scp != NULL) {
6467         ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong) scp);
6468         tscp = REQPNEXT(scp);
6469         scp->host_scribble = NULL;
6470         ASC_STATS(scp->host, done);
6471         ASC_ASSERT(scp->scsi_done != NULL);
6472         scp->scsi_done(scp);
6473         scp = tscp;
6474     }
6475     ASC_DBG(2, "asc_scsi_done_list: done\n");
6476     return;
6477 }
6478 
6479 /*
6480  * Execute a single 'Scsi_Cmnd'.
6481  *
6482  * The function 'done' is called when the request has been completed.
6483  *
6484  * Scsi_Cmnd:
6485  *
6486  *  host - board controlling device
6487  *  device - device to send command
6488  *  target - target of device
6489  *  lun - lun of device
6490  *  cmd_len - length of SCSI CDB
6491  *  cmnd - buffer for SCSI 8, 10, or 12 byte CDB
6492  *  use_sg - if non-zero indicates scatter-gather request with use_sg elements
6493  *
6494  *  if (use_sg == 0) {
6495  *    request_buffer - buffer address for request
6496  *    request_bufflen - length of request buffer
6497  *  } else {
6498  *    request_buffer - pointer to scatterlist structure
6499  *  }
6500  *
6501  *  sense_buffer - sense command buffer
6502  *
6503  *  result (4 bytes of an int):
6504  *    Byte Meaning
6505  *    0 SCSI Status Byte Code
6506  *    1 SCSI One Byte Message Code
6507  *    2 Host Error Code
6508  *    3 Mid-Level Error Code
6509  *
6510  *  host driver fields:
6511  *    SCp - Scsi_Pointer used for command processing status
6512  *    scsi_done - used to save caller's done function
6513  *    host_scribble - used for pointer to another Scsi_Cmnd
6514  *
6515  * If this function returns ASC_NOERROR the request has been enqueued
6516  * on the board's 'active' queue and will be completed from the
6517  * interrupt handler.
6518  *
6519  * If this function returns ASC_NOERROR the request has been enqueued
6520  * on the board's 'done' queue and must be completed by the caller.
6521  *
6522  * If ASC_BUSY is returned the request will be enqueued by the
6523  * caller on the target's waiting queue and re-tried later.
6524  */
6525 STATIC int
asc_execute_scsi_cmnd(Scsi_Cmnd * scp)6526 asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
6527 {
6528     asc_board_t        *boardp;
6529     ASC_DVC_VAR        *asc_dvc_varp;
6530     ADV_DVC_VAR        *adv_dvc_varp;
6531     ADV_SCSI_REQ_Q     *adv_scsiqp;
6532     Scsi_Device        *device;
6533     int                ret;
6534 
6535     ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
6536         (ulong) scp, (ulong) scp->scsi_done);
6537 
6538     boardp = ASC_BOARDP(scp->host);
6539     device = boardp->device[scp->target];
6540 
6541     if (ASC_NARROW_BOARD(boardp)) {
6542         /*
6543          * Build and execute Narrow Board request.
6544          */
6545 
6546         asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6547 
6548         /*
6549          * Build Asc Library request structure using the
6550          * global structures 'asc_scsi_req' and 'asc_sg_head'.
6551          *
6552          * If an error is returned, then the request has been
6553          * queued on the board done queue. It will be completed
6554          * by the caller.
6555          *
6556          * asc_build_req() can not return ASC_BUSY.
6557          */
6558         if (asc_build_req(boardp, scp) == ASC_ERROR) {
6559             ASC_STATS(scp->host, build_error);
6560             return ASC_ERROR;
6561         }
6562 
6563         /*
6564          * Execute the command. If there is no error, add the command
6565          * to the active queue.
6566          */
6567         switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
6568         case ASC_NOERROR:
6569             ASC_STATS(scp->host, exe_noerror);
6570             /*
6571              * Increment monotonically increasing per device successful
6572              * request counter. Wrapping doesn't matter.
6573              */
6574             boardp->reqcnt[scp->target]++;
6575             asc_enqueue(&boardp->active, scp, ASC_BACK);
6576             ASC_DBG(1,
6577                 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
6578             break;
6579         case ASC_BUSY:
6580             /*
6581              * Caller will enqueue request on the target's waiting queue
6582              * and retry later.
6583              */
6584             ASC_STATS(scp->host, exe_busy);
6585             break;
6586         case ASC_ERROR:
6587             ASC_PRINT2(
6588 "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
6589                 boardp->id, asc_dvc_varp->err_code);
6590             ASC_STATS(scp->host, exe_error);
6591             scp->result = HOST_BYTE(DID_ERROR);
6592             asc_enqueue(&boardp->done, scp, ASC_BACK);
6593             break;
6594         default:
6595             ASC_PRINT2(
6596 "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
6597                 boardp->id, asc_dvc_varp->err_code);
6598             ASC_STATS(scp->host, exe_unknown);
6599             scp->result = HOST_BYTE(DID_ERROR);
6600             asc_enqueue(&boardp->done, scp, ASC_BACK);
6601             break;
6602         }
6603     } else {
6604         /*
6605          * Build and execute Wide Board request.
6606          */
6607         adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6608 
6609         /*
6610          * Build and get a pointer to an Adv Library request structure.
6611          *
6612          * If the request is successfully built then send it below,
6613          * otherwise return with an error.
6614          */
6615         switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
6616         case ASC_NOERROR:
6617             ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
6618             break;
6619         case ASC_BUSY:
6620             ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
6621             /*
6622              * If busy is returned the request has not been enqueued.
6623              * It will be enqueued by the caller on the target's waiting
6624              * queue and retried later.
6625              *
6626              * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg'
6627              * count wide board busy conditions. They are updated in
6628              * adv_build_req and adv_get_sglist, respectively.
6629              */
6630             return ASC_BUSY;
6631         case ASC_ERROR:
6632              /*
6633               * If an error is returned, then the request has been
6634               * queued on the board done queue. It will be completed
6635               * by the caller.
6636               */
6637         default:
6638             ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
6639             ASC_STATS(scp->host, build_error);
6640             return ASC_ERROR;
6641         }
6642 
6643         /*
6644          * Execute the command. If there is no error, add the command
6645          * to the active queue.
6646          */
6647         switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
6648         case ASC_NOERROR:
6649             ASC_STATS(scp->host, exe_noerror);
6650             /*
6651              * Increment monotonically increasing per device successful
6652              * request counter. Wrapping doesn't matter.
6653              */
6654             boardp->reqcnt[scp->target]++;
6655             asc_enqueue(&boardp->active, scp, ASC_BACK);
6656             ASC_DBG(1,
6657                 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
6658             break;
6659         case ASC_BUSY:
6660             /*
6661              * Caller will enqueue request on the target's waiting queue
6662              * and retry later.
6663              */
6664             ASC_STATS(scp->host, exe_busy);
6665             break;
6666         case ASC_ERROR:
6667             ASC_PRINT2(
6668 "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
6669                 boardp->id, adv_dvc_varp->err_code);
6670             ASC_STATS(scp->host, exe_error);
6671             scp->result = HOST_BYTE(DID_ERROR);
6672             asc_enqueue(&boardp->done, scp, ASC_BACK);
6673             break;
6674         default:
6675             ASC_PRINT2(
6676 "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
6677                 boardp->id, adv_dvc_varp->err_code);
6678             ASC_STATS(scp->host, exe_unknown);
6679             scp->result = HOST_BYTE(DID_ERROR);
6680             asc_enqueue(&boardp->done, scp, ASC_BACK);
6681             break;
6682         }
6683     }
6684 
6685     ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
6686     return ret;
6687 }
6688 
6689 /*
6690  * Build a request structure for the Asc Library (Narrow Board).
6691  *
6692  * The global structures 'asc_scsi_q' and 'asc_sg_head' are
6693  * used to build the request.
6694  *
6695  * If an error occurs, then queue the request on the board done
6696  * queue and return ASC_ERROR.
6697  */
6698 STATIC int
asc_build_req(asc_board_t * boardp,Scsi_Cmnd * scp)6699 asc_build_req(asc_board_t *boardp, Scsi_Cmnd *scp)
6700 {
6701     /*
6702      * Mutually exclusive access is required to 'asc_scsi_q' and
6703      * 'asc_sg_head' until after the request is started.
6704      */
6705     memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
6706 
6707     /*
6708      * Point the ASC_SCSI_Q to the 'Scsi_Cmnd'.
6709      */
6710     asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
6711 
6712     /*
6713      * Build the ASC_SCSI_Q request.
6714      *
6715      * For narrow boards a CDB length maximum of 12 bytes
6716      * is supported.
6717      */
6718     if (scp->cmd_len > ASC_MAX_CDB_LEN) {
6719         ASC_PRINT3(
6720 "asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN  %d\n",
6721             boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN);
6722         scp->result = HOST_BYTE(DID_ERROR);
6723         asc_enqueue(&boardp->done, scp, ASC_BACK);
6724         return ASC_ERROR;
6725     }
6726     asc_scsi_q.cdbptr = &scp->cmnd[0];
6727     asc_scsi_q.q2.cdb_len = scp->cmd_len;
6728     asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->target);
6729     asc_scsi_q.q1.target_lun = scp->lun;
6730     asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->target, scp->lun);
6731     asc_scsi_q.q1.sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
6732     asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
6733 
6734     /*
6735      * If there are any outstanding requests for the current target,
6736      * then every 255th request send an ORDERED request. This heuristic
6737      * tries to retain the benefit of request sorting while preventing
6738      * request starvation. 255 is the max number of tags or pending commands
6739      * a device may have outstanding.
6740      *
6741      * The request count is incremented below for every successfully
6742      * started request.
6743      *
6744      */
6745     if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->target] > 0) &&
6746         (boardp->reqcnt[scp->target] % 255) == 0) {
6747         asc_scsi_q.q2.tag_code = M2_QTAG_MSG_ORDERED;
6748     } else {
6749         asc_scsi_q.q2.tag_code = M2_QTAG_MSG_SIMPLE;
6750     }
6751 
6752     /*
6753      * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
6754      * buffer command.
6755      */
6756     if (scp->use_sg == 0) {
6757         /*
6758          * CDB request of single contiguous buffer.
6759          */
6760         ASC_STATS(scp->host, cont_cnt);
6761         asc_scsi_q.q1.data_addr =
6762             cpu_to_le32(virt_to_bus(scp->request_buffer));
6763         asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
6764         ASC_STATS_ADD(scp->host, cont_xfer,
6765                       ASC_CEILING(scp->request_bufflen, 512));
6766         asc_scsi_q.q1.sg_queue_cnt = 0;
6767         asc_scsi_q.sg_head = NULL;
6768     } else {
6769         /*
6770          * CDB scatter-gather request list.
6771          */
6772         int                     sgcnt;
6773         struct scatterlist      *slp;
6774 
6775         if (scp->use_sg > scp->host->sg_tablesize) {
6776             ASC_PRINT3(
6777 "asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
6778                 boardp->id, scp->use_sg, scp->host->sg_tablesize);
6779             scp->result = HOST_BYTE(DID_ERROR);
6780             asc_enqueue(&boardp->done, scp, ASC_BACK);
6781             return ASC_ERROR;
6782         }
6783 
6784         ASC_STATS(scp->host, sg_cnt);
6785 
6786         /*
6787          * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
6788          * structure to point to it.
6789          */
6790         memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
6791 
6792         asc_scsi_q.q1.cntl |= QC_SG_HEAD;
6793         asc_scsi_q.sg_head = &asc_sg_head;
6794         asc_scsi_q.q1.data_cnt = 0;
6795         asc_scsi_q.q1.data_addr = 0;
6796         /* This is a byte value, otherwise it would need to be swapped. */
6797         asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = scp->use_sg;
6798         ASC_STATS_ADD(scp->host, sg_elem, asc_sg_head.entry_cnt);
6799 
6800         /*
6801          * Convert scatter-gather list into ASC_SG_HEAD list.
6802          */
6803         slp = (struct scatterlist *) scp->request_buffer;
6804         for (sgcnt = 0; sgcnt < scp->use_sg; sgcnt++, slp++) {
6805             asc_sg_head.sg_list[sgcnt].addr =
6806                 cpu_to_le32(virt_to_bus(slp->address));
6807             asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(slp->length);
6808             ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512));
6809         }
6810     }
6811 
6812     ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
6813     ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6814 
6815     return ASC_NOERROR;
6816 }
6817 
6818 /*
6819  * Build a request structure for the Adv Library (Wide Board).
6820  *
6821  * If an adv_req_t can not be allocated to issue the request,
6822  * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
6823  *
6824  * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
6825  * microcode for DMA addresses or math operations are byte swapped
6826  * to little-endian order.
6827  */
6828 STATIC int
adv_build_req(asc_board_t * boardp,Scsi_Cmnd * scp,ADV_SCSI_REQ_Q ** adv_scsiqpp)6829 adv_build_req(asc_board_t *boardp, Scsi_Cmnd *scp,
6830     ADV_SCSI_REQ_Q **adv_scsiqpp)
6831 {
6832     adv_req_t           *reqp;
6833     ADV_SCSI_REQ_Q      *scsiqp;
6834     int                 i;
6835     int                 ret;
6836 
6837     /*
6838      * Allocate an adv_req_t structure from the board to execute
6839      * the command.
6840      */
6841     if (boardp->adv_reqp == NULL) {
6842         ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
6843         ASC_STATS(scp->host, adv_build_noreq);
6844         return ASC_BUSY;
6845     } else {
6846         reqp = boardp->adv_reqp;
6847         boardp->adv_reqp = reqp->next_reqp;
6848         reqp->next_reqp = NULL;
6849     }
6850 
6851     /*
6852      * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
6853      */
6854     scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
6855 
6856     /*
6857      * Initialize the structure.
6858      */
6859     scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
6860 
6861     /*
6862      * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
6863      */
6864     scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
6865 
6866     /*
6867      * Set the adv_req_t 'cmndp' to point to the Scsi_Cmnd structure.
6868      */
6869     reqp->cmndp = scp;
6870 
6871     /*
6872      * Build the ADV_SCSI_REQ_Q request.
6873      */
6874 
6875     /*
6876      * Set CDB length and copy it to the request structure.
6877      * For wide  boards a CDB length maximum of 16 bytes
6878      * is supported.
6879      */
6880     if (scp->cmd_len > ADV_MAX_CDB_LEN) {
6881         ASC_PRINT3(
6882 "adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN  %d\n",
6883             boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
6884         scp->result = HOST_BYTE(DID_ERROR);
6885         asc_enqueue(&boardp->done, scp, ASC_BACK);
6886         return ASC_ERROR;
6887     }
6888     scsiqp->cdb_len = scp->cmd_len;
6889     /* Copy first 12 CDB bytes to cdb[]. */
6890     for (i = 0; i < scp->cmd_len && i < 12; i++) {
6891         scsiqp->cdb[i] = scp->cmnd[i];
6892     }
6893     /* Copy last 4 CDB bytes, if present, to cdb16[]. */
6894     for (; i < scp->cmd_len; i++) {
6895         scsiqp->cdb16[i - 12] = scp->cmnd[i];
6896     }
6897 
6898     scsiqp->target_id = scp->target;
6899     scsiqp->target_lun = scp->lun;
6900 
6901     scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
6902     scsiqp->sense_len = sizeof(scp->sense_buffer);
6903 
6904     /*
6905      * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
6906      * buffer command.
6907      */
6908     scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
6909     scsiqp->vdata_addr = scp->request_buffer;
6910     scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
6911 
6912     if (scp->use_sg == 0) {
6913         /*
6914          * CDB request of single contiguous buffer.
6915          */
6916         reqp->sgblkp = NULL;
6917         scsiqp->sg_list_ptr = NULL;
6918         scsiqp->sg_real_addr = 0;
6919         ASC_STATS(scp->host, cont_cnt);
6920         ASC_STATS_ADD(scp->host, cont_xfer,
6921                       ASC_CEILING(scp->request_bufflen, 512));
6922     } else {
6923         /*
6924          * CDB scatter-gather request list.
6925          */
6926         if (scp->use_sg > ADV_MAX_SG_LIST) {
6927             ASC_PRINT3(
6928 "adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
6929                 boardp->id, scp->use_sg, scp->host->sg_tablesize);
6930             scp->result = HOST_BYTE(DID_ERROR);
6931             asc_enqueue(&boardp->done, scp, ASC_BACK);
6932 
6933             /*
6934              * Free the 'adv_req_t' structure by adding it back to the
6935              * board free list.
6936              */
6937             reqp->next_reqp = boardp->adv_reqp;
6938             boardp->adv_reqp = reqp;
6939 
6940             return ASC_ERROR;
6941         }
6942 
6943         if ((ret = adv_get_sglist(boardp, reqp, scp)) != ADV_SUCCESS) {
6944             /*
6945              * Free the adv_req_t structure by adding it back to the
6946              * board free list.
6947              */
6948             reqp->next_reqp = boardp->adv_reqp;
6949             boardp->adv_reqp = reqp;
6950 
6951             return ret;
6952         }
6953 
6954         ASC_STATS(scp->host, sg_cnt);
6955         ASC_STATS_ADD(scp->host, sg_elem, scp->use_sg);
6956     }
6957 
6958     ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
6959     ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6960 
6961     *adv_scsiqpp = scsiqp;
6962 
6963     return ASC_NOERROR;
6964 }
6965 
6966 /*
6967  * Build scatter-gather list for Adv Library (Wide Board).
6968  *
6969  * Additional ADV_SG_BLOCK structures will need to be allocated
6970  * if the total number of scatter-gather elements exceeds
6971  * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
6972  * assumed to be physically contiguous.
6973  *
6974  * Return:
6975  *      ADV_SUCCESS(1) - SG List successfully created
6976  *      ADV_ERROR(-1) - SG List creation failed
6977  */
6978 STATIC int
adv_get_sglist(asc_board_t * boardp,adv_req_t * reqp,Scsi_Cmnd * scp)6979 adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, Scsi_Cmnd *scp)
6980 {
6981     adv_sgblk_t         *sgblkp;
6982     ADV_SCSI_REQ_Q      *scsiqp;
6983     struct scatterlist  *slp;
6984     int                 sg_elem_cnt;
6985     ADV_SG_BLOCK        *sg_block, *prev_sg_block;
6986     ADV_PADDR           sg_block_paddr;
6987     int                 i;
6988 
6989     scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
6990     slp = (struct scatterlist *) scp->request_buffer;
6991     sg_elem_cnt = scp->use_sg;
6992     prev_sg_block = NULL;
6993     reqp->sgblkp = NULL;
6994 
6995     do
6996     {
6997         /*
6998          * Allocate a 'adv_sgblk_t' structure from the board free
6999          * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
7000          * (15) scatter-gather elements.
7001          */
7002         if ((sgblkp = boardp->adv_sgblkp) == NULL) {
7003             ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
7004             ASC_STATS(scp->host, adv_build_nosg);
7005 
7006             /*
7007              * Allocation failed. Free 'adv_sgblk_t' structures already
7008              * allocated for the request.
7009              */
7010             while ((sgblkp = reqp->sgblkp) != NULL)
7011             {
7012                 /* Remove 'sgblkp' from the request list. */
7013                 reqp->sgblkp = sgblkp->next_sgblkp;
7014 
7015                 /* Add 'sgblkp' to the board free list. */
7016                 sgblkp->next_sgblkp = boardp->adv_sgblkp;
7017                 boardp->adv_sgblkp = sgblkp;
7018             }
7019             return ASC_BUSY;
7020         } else {
7021             /* Complete 'adv_sgblk_t' board allocation. */
7022             boardp->adv_sgblkp = sgblkp->next_sgblkp;
7023             sgblkp->next_sgblkp = NULL;
7024 
7025             /*
7026              * Get 8 byte aligned virtual and physical addresses for
7027              * the allocated ADV_SG_BLOCK structure.
7028              */
7029             sg_block = (ADV_SG_BLOCK *) ADV_8BALIGN(&sgblkp->sg_block);
7030             sg_block_paddr = virt_to_bus(sg_block);
7031 
7032             /*
7033              * Check if this is the first 'adv_sgblk_t' for the request.
7034              */
7035             if (reqp->sgblkp == NULL)
7036             {
7037                 /* Request's first scatter-gather block. */
7038                 reqp->sgblkp = sgblkp;
7039 
7040                 /*
7041                  * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
7042                  * address pointers.
7043                  */
7044                 scsiqp->sg_list_ptr = sg_block;
7045                 scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr);
7046             } else
7047             {
7048                 /* Request's second or later scatter-gather block. */
7049                 sgblkp->next_sgblkp = reqp->sgblkp;
7050                 reqp->sgblkp = sgblkp;
7051 
7052                 /*
7053                  * Point the previous ADV_SG_BLOCK structure to
7054                  * the newly allocated ADV_SG_BLOCK structure.
7055                  */
7056                 ASC_ASSERT(prev_sg_block != NULL);
7057                 prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr);
7058             }
7059         }
7060 
7061         for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
7062         {
7063             sg_block->sg_list[i].sg_addr =
7064                 cpu_to_le32(virt_to_bus(slp->address));
7065             sg_block->sg_list[i].sg_count = cpu_to_le32(slp->length);
7066             ASC_STATS_ADD(scp->host, sg_xfer, ASC_CEILING(slp->length, 512));
7067 
7068             if (--sg_elem_cnt == 0)
7069             {   /* Last ADV_SG_BLOCK and scatter-gather entry. */
7070                 sg_block->sg_cnt = i + 1;
7071                 sg_block->sg_ptr = 0L;    /* Last ADV_SG_BLOCK in list. */
7072                 return ADV_SUCCESS;
7073             }
7074             slp++;
7075         }
7076         sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
7077         prev_sg_block = sg_block;
7078     }
7079     while (1);
7080     /* NOTREACHED */
7081 }
7082 
7083 /*
7084  * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
7085  *
7086  * Interrupt callback function for the Narrow SCSI Asc Library.
7087  */
7088 STATIC void
asc_isr_callback(ASC_DVC_VAR * asc_dvc_varp,ASC_QDONE_INFO * qdonep)7089 asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
7090 {
7091     asc_board_t         *boardp;
7092     Scsi_Cmnd           *scp;
7093     struct Scsi_Host    *shp;
7094     int                 i;
7095 
7096     ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
7097         (ulong) asc_dvc_varp, (ulong) qdonep);
7098     ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
7099 
7100     /*
7101      * Get the Scsi_Cmnd structure and Scsi_Host structure for the
7102      * command that has been completed.
7103      */
7104     scp = (Scsi_Cmnd *) ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
7105     ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong) scp);
7106 
7107     if (scp == NULL) {
7108         ASC_PRINT("asc_isr_callback: scp is NULL\n");
7109         return;
7110     }
7111     ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
7112 
7113     /*
7114      * If the request's host pointer is not valid, display a
7115      * message and return.
7116      */
7117     shp = scp->host;
7118     for (i = 0; i < asc_board_count; i++) {
7119         if (asc_host[i] == shp) {
7120             break;
7121         }
7122     }
7123     if (i == asc_board_count) {
7124         ASC_PRINT2(
7125             "asc_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
7126             (ulong) scp, (ulong) shp);
7127         return;
7128     }
7129 
7130     ASC_STATS(shp, callback);
7131     ASC_DBG1(1, "asc_isr_callback: shp 0x%lx\n", (ulong) shp);
7132 
7133     /*
7134      * If the request isn't found on the active queue, it may
7135      * have been removed to handle a reset request.
7136      * Display a message and return.
7137      */
7138     boardp = ASC_BOARDP(shp);
7139     ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
7140     if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
7141         ASC_PRINT2(
7142             "asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
7143             boardp->id, (ulong) scp);
7144         return;
7145     }
7146 
7147     /*
7148      * 'qdonep' contains the command's ending status.
7149      */
7150     switch (qdonep->d3.done_stat) {
7151     case QD_NO_ERROR:
7152         ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
7153         scp->result = 0;
7154 
7155         /*
7156          * If an INQUIRY command completed successfully, then call
7157          * the AscInquiryHandling() function to set-up the device.
7158          */
7159         if (scp->cmnd[0] == SCSICMD_Inquiry && scp->lun == 0 &&
7160             (scp->request_bufflen - qdonep->remain_bytes) >= 8)
7161         {
7162             AscInquiryHandling(asc_dvc_varp, scp->target & 0x7,
7163                 (ASC_SCSI_INQUIRY *) scp->request_buffer);
7164         }
7165 
7166 #if ASC_LINUX_KERNEL24
7167         /*
7168          * Check for an underrun condition.
7169          *
7170          * If there was no error and an underrun condition, then
7171          * then return the number of underrun bytes.
7172          */
7173         if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
7174             qdonep->remain_bytes <= scp->request_bufflen) {
7175             ASC_DBG1(1, "asc_isr_callback: underrun condition %u bytes\n",
7176             (unsigned) qdonep->remain_bytes);
7177             scp->resid = qdonep->remain_bytes;
7178         }
7179 #endif
7180         break;
7181 
7182     case QD_WITH_ERROR:
7183         ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
7184         switch (qdonep->d3.host_stat) {
7185         case QHSTA_NO_ERROR:
7186             if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) {
7187                 ASC_DBG(2, "asc_isr_callback: SS_CHK_CONDITION\n");
7188                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
7189                     sizeof(scp->sense_buffer));
7190                 /*
7191                  * Note: The 'status_byte()' macro used by target drivers
7192                  * defined in scsi.h shifts the status byte returned by
7193                  * host drivers right by 1 bit. This is why target drivers
7194                  * also use right shifted status byte definitions. For
7195                  * instance target drivers use CHECK_CONDITION, defined to
7196                  * 0x1, instead of the SCSI defined check condition value
7197                  * of 0x2. Host drivers are supposed to return the status
7198                  * byte as it is defined by SCSI.
7199                  */
7200                 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
7201                     STATUS_BYTE(qdonep->d3.scsi_stat);
7202             } else {
7203                 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
7204             }
7205             break;
7206 
7207         default:
7208             /* QHSTA error occurred */
7209             ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
7210                 qdonep->d3.host_stat);
7211             scp->result = HOST_BYTE(DID_BAD_TARGET);
7212             break;
7213         }
7214         break;
7215 
7216     case QD_ABORTED_BY_HOST:
7217         ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
7218         scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.scsi_msg) |
7219                 STATUS_BYTE(qdonep->d3.scsi_stat);
7220         break;
7221 
7222     default:
7223         ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n", qdonep->d3.done_stat);
7224         scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
7225                 STATUS_BYTE(qdonep->d3.scsi_stat);
7226         break;
7227     }
7228 
7229     /*
7230      * If the 'init_tidmask' bit isn't already set for the target and the
7231      * current request finished normally, then set the bit for the target
7232      * to indicate that a device is present.
7233      */
7234     if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 &&
7235         qdonep->d3.done_stat == QD_NO_ERROR &&
7236         qdonep->d3.host_stat == QHSTA_NO_ERROR) {
7237         boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target);
7238     }
7239 
7240     /*
7241      * Because interrupts may be enabled by the 'Scsi_Cmnd' done
7242      * function, add the command to the end of the board's done queue.
7243      * The done function for the command will be called from
7244      * advansys_interrupt().
7245      */
7246     asc_enqueue(&boardp->done, scp, ASC_BACK);
7247 
7248     return;
7249 }
7250 
7251 /*
7252  * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
7253  *
7254  * Callback function for the Wide SCSI Adv Library.
7255  */
7256 STATIC void
adv_isr_callback(ADV_DVC_VAR * adv_dvc_varp,ADV_SCSI_REQ_Q * scsiqp)7257 adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
7258 {
7259     asc_board_t         *boardp;
7260     adv_req_t           *reqp;
7261     adv_sgblk_t         *sgblkp;
7262     Scsi_Cmnd           *scp;
7263     struct Scsi_Host    *shp;
7264     int                 i;
7265 #if ASC_LINUX_KERNEL24
7266     ADV_DCNT            resid_cnt;
7267 #endif
7268 
7269 
7270     ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
7271         (ulong) adv_dvc_varp, (ulong) scsiqp);
7272     ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
7273 
7274     /*
7275      * Get the adv_req_t structure for the command that has been
7276      * completed. The adv_req_t structure actually contains the
7277      * completed ADV_SCSI_REQ_Q structure.
7278      */
7279     reqp = (adv_req_t *) ADV_U32_TO_VADDR(scsiqp->srb_ptr);
7280     ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong) reqp);
7281     if (reqp == NULL) {
7282         ASC_PRINT("adv_isr_callback: reqp is NULL\n");
7283         return;
7284     }
7285 
7286     /*
7287      * Get the Scsi_Cmnd structure and Scsi_Host structure for the
7288      * command that has been completed.
7289      *
7290      * Note: The adv_req_t request structure and adv_sgblk_t structure,
7291      * if any, are dropped, because a board structure pointer can not be
7292      * determined.
7293      */
7294     scp = reqp->cmndp;
7295     ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong) scp);
7296     if (scp == NULL) {
7297         ASC_PRINT("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
7298         return;
7299     }
7300     ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
7301 
7302     /*
7303      * If the request's host pointer is not valid, display a message
7304      * and return.
7305      */
7306     shp = scp->host;
7307     for (i = 0; i < asc_board_count; i++) {
7308         if (asc_host[i] == shp) {
7309             break;
7310         }
7311     }
7312     /*
7313      * Note: If the host structure is not found, the adv_req_t request
7314      * structure and adv_sgblk_t structure, if any, is dropped.
7315      */
7316     if (i == asc_board_count) {
7317         ASC_PRINT2(
7318             "adv_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
7319             (ulong) scp, (ulong) shp);
7320         return;
7321     }
7322 
7323     ASC_STATS(shp, callback);
7324     ASC_DBG1(1, "adv_isr_callback: shp 0x%lx\n", (ulong) shp);
7325 
7326     /*
7327      * If the request isn't found on the active queue, it may have been
7328      * removed to handle a reset request. Display a message and return.
7329      *
7330      * Note: Because the structure may still be in use don't attempt
7331      * to free the adv_req_t and adv_sgblk_t, if any, structures.
7332      */
7333     boardp = ASC_BOARDP(shp);
7334     ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
7335     if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
7336         ASC_PRINT2(
7337             "adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
7338             boardp->id, (ulong) scp);
7339         return;
7340     }
7341 
7342     /*
7343      * 'done_status' contains the command's ending status.
7344      */
7345     switch (scsiqp->done_status) {
7346     case QD_NO_ERROR:
7347         ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
7348         scp->result = 0;
7349 
7350 #if ASC_LINUX_KERNEL24
7351         /*
7352          * Check for an underrun condition.
7353          *
7354          * If there was no error and an underrun condition, then
7355          * then return the number of underrun bytes.
7356          */
7357         resid_cnt = le32_to_cpu(scsiqp->data_cnt);
7358         if (scp->request_bufflen != 0 && resid_cnt != 0 &&
7359             resid_cnt <= scp->request_bufflen) {
7360             ASC_DBG1(1, "adv_isr_callback: underrun condition %lu bytes\n",
7361                 (ulong) resid_cnt);
7362             scp->resid = resid_cnt;
7363         }
7364 #endif
7365         break;
7366 
7367     case QD_WITH_ERROR:
7368         ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
7369         switch (scsiqp->host_status) {
7370         case QHSTA_NO_ERROR:
7371             if (scsiqp->scsi_status == SS_CHK_CONDITION) {
7372                 ASC_DBG(2, "adv_isr_callback: SS_CHK_CONDITION\n");
7373                 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
7374                     sizeof(scp->sense_buffer));
7375                 /*
7376                  * Note: The 'status_byte()' macro used by target drivers
7377                  * defined in scsi.h shifts the status byte returned by
7378                  * host drivers right by 1 bit. This is why target drivers
7379                  * also use right shifted status byte definitions. For
7380                  * instance target drivers use CHECK_CONDITION, defined to
7381                  * 0x1, instead of the SCSI defined check condition value
7382                  * of 0x2. Host drivers are supposed to return the status
7383                  * byte as it is defined by SCSI.
7384                  */
7385                 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
7386                     STATUS_BYTE(scsiqp->scsi_status);
7387             } else {
7388                 scp->result = STATUS_BYTE(scsiqp->scsi_status);
7389             }
7390             break;
7391 
7392         default:
7393             /* Some other QHSTA error occurred. */
7394             ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
7395                 scsiqp->host_status);
7396             scp->result = HOST_BYTE(DID_BAD_TARGET);
7397             break;
7398         }
7399         break;
7400 
7401     case QD_ABORTED_BY_HOST:
7402         ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
7403         scp->result = HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
7404         break;
7405 
7406     default:
7407         ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n", scsiqp->done_status);
7408         scp->result = HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
7409         break;
7410     }
7411 
7412     /*
7413      * If the 'init_tidmask' bit isn't already set for the target and the
7414      * current request finished normally, then set the bit for the target
7415      * to indicate that a device is present.
7416      */
7417     if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->target)) == 0 &&
7418         scsiqp->done_status == QD_NO_ERROR &&
7419         scsiqp->host_status == QHSTA_NO_ERROR) {
7420         boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->target);
7421     }
7422 
7423     /*
7424      * Because interrupts may be enabled by the 'Scsi_Cmnd' done
7425      * function, add the command to the end of the board's done queue.
7426      * The done function for the command will be called from
7427      * advansys_interrupt().
7428      */
7429     asc_enqueue(&boardp->done, scp, ASC_BACK);
7430 
7431     /*
7432      * Free all 'adv_sgblk_t' structures allocated for the request.
7433      */
7434     while ((sgblkp = reqp->sgblkp) != NULL)
7435     {
7436         /* Remove 'sgblkp' from the request list. */
7437         reqp->sgblkp = sgblkp->next_sgblkp;
7438 
7439         /* Add 'sgblkp' to the board free list. */
7440         sgblkp->next_sgblkp = boardp->adv_sgblkp;
7441         boardp->adv_sgblkp = sgblkp;
7442     }
7443 
7444     /*
7445      * Free the adv_req_t structure used with the command by adding
7446      * it back to the board free list.
7447      */
7448     reqp->next_reqp = boardp->adv_reqp;
7449     boardp->adv_reqp = reqp;
7450 
7451     ASC_DBG(1, "adv_isr_callback: done\n");
7452 
7453     return;
7454 }
7455 
7456 /*
7457  * adv_async_callback() - Adv Library asynchronous event callback function.
7458  */
7459 STATIC void
adv_async_callback(ADV_DVC_VAR * adv_dvc_varp,uchar code)7460 adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
7461 {
7462     switch (code)
7463     {
7464     case ADV_ASYNC_SCSI_BUS_RESET_DET:
7465         /*
7466          * The firmware detected a SCSI Bus reset.
7467          */
7468         ASC_DBG(0, "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
7469         break;
7470 
7471     case ADV_ASYNC_RDMA_FAILURE:
7472         /*
7473          * Handle RDMA failure by resetting the SCSI Bus and
7474          * possibly the chip if it is unresponsive. Log the error
7475          * with a unique code.
7476          */
7477         ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
7478         AdvResetChipAndSB(adv_dvc_varp);
7479         break;
7480 
7481     case ADV_HOST_SCSI_BUS_RESET:
7482         /*
7483          * Host generated SCSI bus reset occurred.
7484          */
7485         ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
7486         break;
7487 
7488     default:
7489         ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
7490         break;
7491     }
7492 }
7493 
7494 /*
7495  * Add a 'REQP' to the end of specified queue. Set 'tidmask'
7496  * to indicate a command is queued for the device.
7497  *
7498  * 'flag' may be either ASC_FRONT or ASC_BACK.
7499  *
7500  * 'REQPNEXT(reqp)' returns reqp's next pointer.
7501  */
7502 STATIC void
asc_enqueue(asc_queue_t * ascq,REQP reqp,int flag)7503 asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
7504 {
7505     int        tid;
7506 
7507     ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
7508         (ulong) ascq, (ulong) reqp, flag);
7509     ASC_ASSERT(reqp != NULL);
7510     ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
7511     tid = REQPTID(reqp);
7512     ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7513     if (flag == ASC_FRONT) {
7514         reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
7515         ascq->q_first[tid] = reqp;
7516         /* If the queue was empty, set the last pointer. */
7517         if (ascq->q_last[tid] == NULL) {
7518             ascq->q_last[tid] = reqp;
7519         }
7520     } else { /* ASC_BACK */
7521         if (ascq->q_last[tid] != NULL) {
7522             ascq->q_last[tid]->host_scribble = (unsigned char *)reqp;
7523         }
7524         ascq->q_last[tid] = reqp;
7525         reqp->host_scribble = NULL;
7526         /* If the queue was empty, set the first pointer. */
7527         if (ascq->q_first[tid] == NULL) {
7528             ascq->q_first[tid] = reqp;
7529         }
7530     }
7531     /* The queue has at least one entry, set its bit. */
7532     ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
7533 #ifdef ADVANSYS_STATS
7534     /* Maintain request queue statistics. */
7535     ascq->q_tot_cnt[tid]++;
7536     ascq->q_cur_cnt[tid]++;
7537     if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
7538         ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
7539         ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
7540             tid, ascq->q_max_cnt[tid]);
7541     }
7542     REQPTIME(reqp) = REQTIMESTAMP();
7543 #endif /* ADVANSYS_STATS */
7544     ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong) reqp);
7545     return;
7546 }
7547 
7548 /*
7549  * Return first queued 'REQP' on the specified queue for
7550  * the specified target device. Clear the 'tidmask' bit for
7551  * the device if no more commands are left queued for it.
7552  *
7553  * 'REQPNEXT(reqp)' returns reqp's next pointer.
7554  */
7555 STATIC REQP
asc_dequeue(asc_queue_t * ascq,int tid)7556 asc_dequeue(asc_queue_t *ascq, int tid)
7557 {
7558     REQP    reqp;
7559 
7560     ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong) ascq, tid);
7561     ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7562     if ((reqp = ascq->q_first[tid]) != NULL) {
7563         ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
7564         ascq->q_first[tid] = REQPNEXT(reqp);
7565         /* If the queue is empty, clear its bit and the last pointer. */
7566         if (ascq->q_first[tid] == NULL) {
7567             ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7568             ASC_ASSERT(ascq->q_last[tid] == reqp);
7569             ascq->q_last[tid] = NULL;
7570         }
7571 #ifdef ADVANSYS_STATS
7572         /* Maintain request queue statistics. */
7573         ascq->q_cur_cnt[tid]--;
7574         ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
7575         REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
7576 #endif /* ADVANSYS_STATS */
7577     }
7578     ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong) reqp);
7579     return reqp;
7580 }
7581 
7582 /*
7583  * Return a pointer to a singly linked list of all the requests queued
7584  * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
7585  *
7586  * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
7587  * the last request returned in the singly linked list.
7588  *
7589  * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
7590  * then all queued requests are concatenated into one list and
7591  * returned.
7592  *
7593  * Note: If 'lastpp' is used to append a new list to the end of
7594  * an old list, only change the old list last pointer if '*lastpp'
7595  * (or the function return value) is not NULL, i.e. use a temporary
7596  * variable for 'lastpp' and check its value after the function return
7597  * before assigning it to the list last pointer.
7598  *
7599  * Unfortunately collecting queuing time statistics adds overhead to
7600  * the function that isn't inherent to the function's algorithm.
7601  */
7602 STATIC REQP
asc_dequeue_list(asc_queue_t * ascq,REQP * lastpp,int tid)7603 asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
7604 {
7605     REQP    firstp, lastp;
7606     int     i;
7607 
7608     ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong) ascq, tid);
7609     ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
7610 
7611     /*
7612      * If 'tid' is not ASC_TID_ALL, return requests only for
7613      * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
7614      * requests for all tids.
7615      */
7616     if (tid != ASC_TID_ALL) {
7617         /* Return all requests for the specified 'tid'. */
7618         if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
7619             /* List is empty; Set first and last return pointers to NULL. */
7620             firstp = lastp = NULL;
7621         } else {
7622             firstp = ascq->q_first[tid];
7623             lastp = ascq->q_last[tid];
7624             ascq->q_first[tid] = ascq->q_last[tid] = NULL;
7625             ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7626 #ifdef ADVANSYS_STATS
7627             {
7628                 REQP reqp;
7629                 ascq->q_cur_cnt[tid] = 0;
7630                 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
7631                     REQTIMESTAT("asc_dequeue_list", ascq, reqp, tid);
7632                 }
7633             }
7634 #endif /* ADVANSYS_STATS */
7635         }
7636     } else {
7637         /* Return all requests for all tids. */
7638         firstp = lastp = NULL;
7639         for (i = 0; i <= ADV_MAX_TID; i++) {
7640             if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
7641                 if (firstp == NULL) {
7642                     firstp = ascq->q_first[i];
7643                     lastp = ascq->q_last[i];
7644                 } else {
7645                     ASC_ASSERT(lastp != NULL);
7646                     lastp->host_scribble = (unsigned char *)ascq->q_first[i];
7647                     lastp = ascq->q_last[i];
7648                 }
7649                 ascq->q_first[i] = ascq->q_last[i] = NULL;
7650                 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7651 #ifdef ADVANSYS_STATS
7652                 ascq->q_cur_cnt[i] = 0;
7653 #endif /* ADVANSYS_STATS */
7654             }
7655         }
7656 #ifdef ADVANSYS_STATS
7657         {
7658             REQP reqp;
7659             for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
7660                 REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->target);
7661             }
7662         }
7663 #endif /* ADVANSYS_STATS */
7664     }
7665     if (lastpp) {
7666         *lastpp = lastp;
7667     }
7668     ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong) firstp);
7669     return firstp;
7670 }
7671 
7672 /*
7673  * Remove the specified 'REQP' from the specified queue for
7674  * the specified target device. Clear the 'tidmask' bit for the
7675  * device if no more commands are left queued for it.
7676  *
7677  * 'REQPNEXT(reqp)' returns reqp's the next pointer.
7678  *
7679  * Return ASC_TRUE if the command was found and removed,
7680  * otherwise return ASC_FALSE.
7681  */
7682 STATIC int
asc_rmqueue(asc_queue_t * ascq,REQP reqp)7683 asc_rmqueue(asc_queue_t *ascq, REQP reqp)
7684 {
7685     REQP        currp, prevp;
7686     int         tid;
7687     int         ret = ASC_FALSE;
7688 
7689     ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
7690         (ulong) ascq, (ulong) reqp);
7691     ASC_ASSERT(reqp != NULL);
7692 
7693     tid = REQPTID(reqp);
7694     ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7695 
7696     /*
7697      * Handle the common case of 'reqp' being the first
7698      * entry on the queue.
7699      */
7700     if (reqp == ascq->q_first[tid]) {
7701         ret = ASC_TRUE;
7702         ascq->q_first[tid] = REQPNEXT(reqp);
7703         /* If the queue is now empty, clear its bit and the last pointer. */
7704         if (ascq->q_first[tid] == NULL) {
7705             ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7706             ASC_ASSERT(ascq->q_last[tid] == reqp);
7707             ascq->q_last[tid] = NULL;
7708         }
7709     } else if (ascq->q_first[tid] != NULL) {
7710         ASC_ASSERT(ascq->q_last[tid] != NULL);
7711         /*
7712          * Because the case of 'reqp' being the first entry has been
7713          * handled above and it is known the queue is not empty, if
7714          * 'reqp' is found on the queue it is guaranteed the queue will
7715          * not become empty and that 'q_first[tid]' will not be changed.
7716          *
7717          * Set 'prevp' to the first entry, 'currp' to the second entry,
7718          * and search for 'reqp'.
7719          */
7720         for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
7721              currp; prevp = currp, currp = REQPNEXT(currp)) {
7722             if (currp == reqp) {
7723                 ret = ASC_TRUE;
7724                 prevp->host_scribble = (unsigned char *)REQPNEXT(currp);
7725                 reqp->host_scribble = NULL;
7726                 if (ascq->q_last[tid] == reqp) {
7727                     ascq->q_last[tid] = prevp;
7728                 }
7729                 break;
7730             }
7731         }
7732     }
7733 #ifdef ADVANSYS_STATS
7734     /* Maintain request queue statistics. */
7735     if (ret == ASC_TRUE) {
7736         ascq->q_cur_cnt[tid]--;
7737         REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
7738     }
7739     ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
7740 #endif /* ADVANSYS_STATS */
7741     ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong) reqp, ret);
7742     return ret;
7743 }
7744 
7745 /*
7746  * Execute as many queued requests as possible for the specified queue.
7747  *
7748  * Calls asc_execute_scsi_cmnd() to execute a REQP/Scsi_Cmnd.
7749  */
7750 STATIC void
asc_execute_queue(asc_queue_t * ascq)7751 asc_execute_queue(asc_queue_t *ascq)
7752 {
7753     ADV_SCSI_BIT_ID_TYPE    scan_tidmask;
7754     REQP                    reqp;
7755     int                     i;
7756 
7757     ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong) ascq);
7758     /*
7759      * Execute queued commands for devices attached to
7760      * the current board in round-robin fashion.
7761      */
7762     scan_tidmask = ascq->q_tidmask;
7763     do {
7764         for (i = 0; i <= ADV_MAX_TID; i++) {
7765             if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
7766                 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
7767                     scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7768                 } else if (asc_execute_scsi_cmnd((Scsi_Cmnd *) reqp)
7769                             == ASC_BUSY) {
7770                     scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7771                     /*
7772                      * The request returned ASC_BUSY. Enqueue at the front of
7773                      * target's waiting list to maintain correct ordering.
7774                      */
7775                     asc_enqueue(ascq, reqp, ASC_FRONT);
7776                 }
7777             }
7778         }
7779     } while (scan_tidmask);
7780     return;
7781 }
7782 
7783 #ifdef CONFIG_PROC_FS
7784 /*
7785  * asc_prt_board_devices()
7786  *
7787  * Print driver information for devices attached to the board.
7788  *
7789  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7790  * cf. asc_prt_line().
7791  *
7792  * Return the number of characters copied into 'cp'. No more than
7793  * 'cplen' characters will be copied to 'cp'.
7794  */
7795 STATIC int
asc_prt_board_devices(struct Scsi_Host * shp,char * cp,int cplen)7796 asc_prt_board_devices(struct Scsi_Host *shp, char *cp, int cplen)
7797 {
7798     asc_board_t        *boardp;
7799     int                leftlen;
7800     int                totlen;
7801     int                len;
7802     int                chip_scsi_id;
7803     int                i;
7804 
7805     boardp = ASC_BOARDP(shp);
7806     leftlen = cplen;
7807     totlen = len = 0;
7808 
7809     len = asc_prt_line(cp, leftlen,
7810 "\nDevice Information for AdvanSys SCSI Host %d:\n", shp->host_no);
7811     ASC_PRT_NEXT();
7812 
7813     if (ASC_NARROW_BOARD(boardp)) {
7814         chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7815     } else {
7816         chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7817     }
7818 
7819     len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
7820     ASC_PRT_NEXT();
7821     for (i = 0; i <= ADV_MAX_TID; i++) {
7822         if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
7823             len = asc_prt_line(cp, leftlen, " %X,", i);
7824             ASC_PRT_NEXT();
7825         }
7826     }
7827     len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
7828     ASC_PRT_NEXT();
7829 
7830     return totlen;
7831 }
7832 
7833 /*
7834  * Display Wide Board BIOS Information.
7835  */
7836 STATIC int
asc_prt_adv_bios(struct Scsi_Host * shp,char * cp,int cplen)7837 asc_prt_adv_bios(struct Scsi_Host *shp, char *cp, int cplen)
7838 {
7839     asc_board_t        *boardp;
7840     int                leftlen;
7841     int                totlen;
7842     int                len;
7843     ushort             major, minor, letter;
7844 
7845     boardp = ASC_BOARDP(shp);
7846     leftlen = cplen;
7847     totlen = len = 0;
7848 
7849     len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
7850     ASC_PRT_NEXT();
7851 
7852     /*
7853      * If the BIOS saved a valid signature, then fill in
7854      * the BIOS code segment base address.
7855      */
7856     if (boardp->bios_signature != 0x55AA) {
7857         len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
7858         ASC_PRT_NEXT();
7859         len = asc_prt_line(cp, leftlen,
7860 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
7861         ASC_PRT_NEXT();
7862         len = asc_prt_line(cp, leftlen,
7863 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
7864         ASC_PRT_NEXT();
7865     } else {
7866         major = (boardp->bios_version >> 12) & 0xF;
7867         minor = (boardp->bios_version >> 8) & 0xF;
7868         letter = (boardp->bios_version & 0xFF);
7869 
7870         len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
7871             major, minor, letter >= 26 ? '?' : letter + 'A');
7872         ASC_PRT_NEXT();
7873 
7874         /*
7875          * Current available ROM BIOS release is 3.1I for UW
7876          * and 3.2I for U2W. This code doesn't differentiate
7877          * UW and U2W boards.
7878          */
7879         if (major < 3 || (major <= 3 && minor < 1) ||
7880             (major <= 3 && minor <= 1 && letter < ('I'- 'A'))) {
7881             len = asc_prt_line(cp, leftlen,
7882 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
7883             ASC_PRT_NEXT();
7884             len = asc_prt_line(cp, leftlen,
7885 "ftp://ftp.connectcom.net/pub\n");
7886             ASC_PRT_NEXT();
7887         }
7888     }
7889 
7890     return totlen;
7891 }
7892 
7893 /*
7894  * Add serial number to information bar if signature AAh
7895  * is found in at bit 15-9 (7 bits) of word 1.
7896  *
7897  * Serial Number consists fo 12 alpha-numeric digits.
7898  *
7899  *       1 - Product type (A,B,C,D..)  Word0: 15-13 (3 bits)
7900  *       2 - MFG Location (A,B,C,D..)  Word0: 12-10 (3 bits)
7901  *     3-4 - Product ID (0-99)         Word0: 9-0 (10 bits)
7902  *       5 - Product revision (A-J)    Word0:  "         "
7903  *
7904  *           Signature                 Word1: 15-9 (7 bits)
7905  *       6 - Year (0-9)                Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
7906  *     7-8 - Week of the year (1-52)   Word1: 5-0 (6 bits)
7907  *
7908  *    9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
7909  *
7910  * Note 1: Only production cards will have a serial number.
7911  *
7912  * Note 2: Signature is most significant 7 bits (0xFE).
7913  *
7914  * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
7915  */
7916 STATIC int
asc_get_eeprom_string(ushort * serialnum,uchar * cp)7917 asc_get_eeprom_string(ushort *serialnum, uchar *cp)
7918 {
7919     ushort      w, num;
7920 
7921     if ((serialnum[1] & 0xFE00) != ((ushort) 0xAA << 8)) {
7922         return ASC_FALSE;
7923     } else {
7924         /*
7925          * First word - 6 digits.
7926          */
7927         w = serialnum[0];
7928 
7929         /* Product type - 1st digit. */
7930         if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
7931             /* Product type is P=Prototype */
7932             *cp += 0x8;
7933         }
7934         cp++;
7935 
7936         /* Manufacturing location - 2nd digit. */
7937         *cp++ = 'A' + ((w & 0x1C00) >> 10);
7938 
7939         /* Product ID - 3rd, 4th digits. */
7940         num = w & 0x3FF;
7941         *cp++ = '0' + (num / 100);
7942         num %= 100;
7943         *cp++ = '0' + (num / 10);
7944 
7945         /* Product revision - 5th digit. */
7946         *cp++ = 'A' + (num % 10);
7947 
7948         /*
7949          * Second word
7950          */
7951         w = serialnum[1];
7952 
7953         /*
7954          * Year - 6th digit.
7955          *
7956          * If bit 15 of third word is set, then the
7957          * last digit of the year is greater than 7.
7958          */
7959         if (serialnum[2] & 0x8000) {
7960             *cp++ = '8' + ((w & 0x1C0) >> 6);
7961         } else {
7962             *cp++ = '0' + ((w & 0x1C0) >> 6);
7963         }
7964 
7965         /* Week of year - 7th, 8th digits. */
7966         num = w & 0x003F;
7967         *cp++ = '0' + num / 10;
7968         num %= 10;
7969         *cp++ = '0' + num;
7970 
7971         /*
7972          * Third word
7973          */
7974         w = serialnum[2] & 0x7FFF;
7975 
7976         /* Serial number - 9th digit. */
7977         *cp++ = 'A' + (w / 1000);
7978 
7979         /* 10th, 11th, 12th digits. */
7980         num = w % 1000;
7981         *cp++ = '0' + num / 100;
7982         num %= 100;
7983         *cp++ = '0' + num / 10;
7984         num %= 10;
7985         *cp++ = '0' + num;
7986 
7987         *cp = '\0';     /* Null Terminate the string. */
7988         return ASC_TRUE;
7989     }
7990 }
7991 
7992 /*
7993  * asc_prt_asc_board_eeprom()
7994  *
7995  * Print board EEPROM configuration.
7996  *
7997  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7998  * cf. asc_prt_line().
7999  *
8000  * Return the number of characters copied into 'cp'. No more than
8001  * 'cplen' characters will be copied to 'cp'.
8002  */
8003 STATIC int
asc_prt_asc_board_eeprom(struct Scsi_Host * shp,char * cp,int cplen)8004 asc_prt_asc_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
8005 {
8006     asc_board_t        *boardp;
8007     ASC_DVC_VAR        *asc_dvc_varp;
8008     int                leftlen;
8009     int                totlen;
8010     int                len;
8011     ASCEEP_CONFIG      *ep;
8012     int                i;
8013 #ifdef CONFIG_ISA
8014     int                isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
8015 #endif /* CONFIG_ISA */
8016     uchar              serialstr[13];
8017 
8018     boardp = ASC_BOARDP(shp);
8019     asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
8020     ep = &boardp->eep_config.asc_eep;
8021 
8022     leftlen = cplen;
8023     totlen = len = 0;
8024 
8025     len = asc_prt_line(cp, leftlen,
8026 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
8027     ASC_PRT_NEXT();
8028 
8029     if (asc_get_eeprom_string((ushort *) &ep->adapter_info[0], serialstr) ==
8030         ASC_TRUE) {
8031         len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
8032         ASC_PRT_NEXT();
8033     } else {
8034         if (ep->adapter_info[5] == 0xBB) {
8035             len = asc_prt_line(cp, leftlen,
8036                 " Default Settings Used for EEPROM-less Adapter.\n");
8037             ASC_PRT_NEXT();
8038         } else {
8039             len = asc_prt_line(cp, leftlen,
8040                 " Serial Number Signature Not Present.\n");
8041             ASC_PRT_NEXT();
8042         }
8043     }
8044 
8045     len = asc_prt_line(cp, leftlen,
8046 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
8047         ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng, ep->max_tag_qng);
8048     ASC_PRT_NEXT();
8049 
8050     len = asc_prt_line(cp, leftlen,
8051 " cntl 0x%x, no_scam 0x%x\n",
8052         ep->cntl, ep->no_scam);
8053     ASC_PRT_NEXT();
8054 
8055     len = asc_prt_line(cp, leftlen,
8056 " Target ID:           ");
8057     ASC_PRT_NEXT();
8058     for (i = 0; i <= ASC_MAX_TID; i++) {
8059         len = asc_prt_line(cp, leftlen, " %d", i);
8060         ASC_PRT_NEXT();
8061     }
8062     len = asc_prt_line(cp, leftlen, "\n");
8063     ASC_PRT_NEXT();
8064 
8065     len = asc_prt_line(cp, leftlen,
8066 " Disconnects:         ");
8067     ASC_PRT_NEXT();
8068     for (i = 0; i <= ASC_MAX_TID; i++) {
8069         len = asc_prt_line(cp, leftlen, " %c",
8070             (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8071         ASC_PRT_NEXT();
8072     }
8073     len = asc_prt_line(cp, leftlen, "\n");
8074     ASC_PRT_NEXT();
8075 
8076     len = asc_prt_line(cp, leftlen,
8077 " Command Queuing:     ");
8078     ASC_PRT_NEXT();
8079     for (i = 0; i <= ASC_MAX_TID; i++) {
8080         len = asc_prt_line(cp, leftlen, " %c",
8081             (ep->use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8082         ASC_PRT_NEXT();
8083     }
8084     len = asc_prt_line(cp, leftlen, "\n");
8085     ASC_PRT_NEXT();
8086 
8087     len = asc_prt_line(cp, leftlen,
8088 " Start Motor:         ");
8089     ASC_PRT_NEXT();
8090     for (i = 0; i <= ASC_MAX_TID; i++) {
8091         len = asc_prt_line(cp, leftlen, " %c",
8092             (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8093         ASC_PRT_NEXT();
8094     }
8095     len = asc_prt_line(cp, leftlen, "\n");
8096     ASC_PRT_NEXT();
8097 
8098     len = asc_prt_line(cp, leftlen,
8099 " Synchronous Transfer:");
8100     ASC_PRT_NEXT();
8101     for (i = 0; i <= ASC_MAX_TID; i++) {
8102         len = asc_prt_line(cp, leftlen, " %c",
8103             (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8104         ASC_PRT_NEXT();
8105     }
8106     len = asc_prt_line(cp, leftlen, "\n");
8107     ASC_PRT_NEXT();
8108 
8109 #ifdef CONFIG_ISA
8110     if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
8111         len = asc_prt_line(cp, leftlen,
8112 " Host ISA DMA speed:   %d MB/S\n",
8113             isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
8114         ASC_PRT_NEXT();
8115     }
8116 #endif /* CONFIG_ISA */
8117 
8118      return totlen;
8119 }
8120 
8121 /*
8122  * asc_prt_adv_board_eeprom()
8123  *
8124  * Print board EEPROM configuration.
8125  *
8126  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8127  * cf. asc_prt_line().
8128  *
8129  * Return the number of characters copied into 'cp'. No more than
8130  * 'cplen' characters will be copied to 'cp'.
8131  */
8132 STATIC int
asc_prt_adv_board_eeprom(struct Scsi_Host * shp,char * cp,int cplen)8133 asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
8134 {
8135     asc_board_t                 *boardp;
8136     ADV_DVC_VAR                 *adv_dvc_varp;
8137     int                         leftlen;
8138     int                         totlen;
8139     int                         len;
8140     int                         i;
8141     char                        *termstr;
8142     uchar                       serialstr[13];
8143     ADVEEP_3550_CONFIG          *ep_3550 = NULL;
8144     ADVEEP_38C0800_CONFIG       *ep_38C0800 = NULL;
8145     ADVEEP_38C1600_CONFIG       *ep_38C1600 = NULL;
8146     ushort                      word;
8147     ushort                      *wordp;
8148     ushort                      sdtr_speed = 0;
8149 
8150     boardp = ASC_BOARDP(shp);
8151     adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
8152     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8153     {
8154         ep_3550 = &boardp->eep_config.adv_3550_eep;
8155     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8156     {
8157         ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
8158     } else
8159     {
8160         ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
8161     }
8162 
8163     leftlen = cplen;
8164     totlen = len = 0;
8165 
8166     len = asc_prt_line(cp, leftlen,
8167 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
8168     ASC_PRT_NEXT();
8169 
8170     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8171     {
8172         wordp = &ep_3550->serial_number_word1;
8173     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8174     {
8175         wordp = &ep_38C0800->serial_number_word1;
8176     } else
8177     {
8178         wordp = &ep_38C1600->serial_number_word1;
8179     }
8180 
8181     if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
8182         len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
8183         ASC_PRT_NEXT();
8184     } else {
8185         len = asc_prt_line(cp, leftlen,
8186             " Serial Number Signature Not Present.\n");
8187         ASC_PRT_NEXT();
8188     }
8189 
8190     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8191     {
8192         len = asc_prt_line(cp, leftlen,
8193 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
8194             ep_3550->adapter_scsi_id, ep_3550->max_host_qng,
8195             ep_3550->max_dvc_qng);
8196         ASC_PRT_NEXT();
8197     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8198     {
8199         len = asc_prt_line(cp, leftlen,
8200 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
8201             ep_38C0800->adapter_scsi_id, ep_38C0800->max_host_qng,
8202             ep_38C0800->max_dvc_qng);
8203         ASC_PRT_NEXT();
8204     } else
8205     {
8206         len = asc_prt_line(cp, leftlen,
8207 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
8208             ep_38C1600->adapter_scsi_id, ep_38C1600->max_host_qng,
8209             ep_38C1600->max_dvc_qng);
8210         ASC_PRT_NEXT();
8211     }
8212     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8213     {
8214         word = ep_3550->termination;
8215     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8216     {
8217         word = ep_38C0800->termination_lvd;
8218     } else
8219     {
8220         word = ep_38C1600->termination_lvd;
8221     }
8222     switch (word) {
8223         case 1:
8224             termstr = "Low Off/High Off";
8225             break;
8226         case 2:
8227             termstr = "Low Off/High On";
8228             break;
8229         case 3:
8230             termstr = "Low On/High On";
8231             break;
8232         default:
8233         case 0:
8234             termstr = "Automatic";
8235             break;
8236     }
8237 
8238     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8239     {
8240         len = asc_prt_line(cp, leftlen,
8241 " termination: %u (%s), bios_ctrl: 0x%x\n",
8242             ep_3550->termination, termstr, ep_3550->bios_ctrl);
8243         ASC_PRT_NEXT();
8244     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8245     {
8246         len = asc_prt_line(cp, leftlen,
8247 " termination: %u (%s), bios_ctrl: 0x%x\n",
8248             ep_38C0800->termination_lvd, termstr, ep_38C0800->bios_ctrl);
8249         ASC_PRT_NEXT();
8250     } else
8251     {
8252         len = asc_prt_line(cp, leftlen,
8253 " termination: %u (%s), bios_ctrl: 0x%x\n",
8254             ep_38C1600->termination_lvd, termstr, ep_38C1600->bios_ctrl);
8255         ASC_PRT_NEXT();
8256     }
8257 
8258     len = asc_prt_line(cp, leftlen,
8259 " Target ID:           ");
8260     ASC_PRT_NEXT();
8261     for (i = 0; i <= ADV_MAX_TID; i++) {
8262         len = asc_prt_line(cp, leftlen, " %X", i);
8263         ASC_PRT_NEXT();
8264     }
8265     len = asc_prt_line(cp, leftlen, "\n");
8266     ASC_PRT_NEXT();
8267 
8268     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8269     {
8270         word = ep_3550->disc_enable;
8271     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8272     {
8273         word = ep_38C0800->disc_enable;
8274     } else
8275     {
8276         word = ep_38C1600->disc_enable;
8277     }
8278     len = asc_prt_line(cp, leftlen,
8279 " Disconnects:         ");
8280     ASC_PRT_NEXT();
8281     for (i = 0; i <= ADV_MAX_TID; i++) {
8282         len = asc_prt_line(cp, leftlen, " %c",
8283             (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8284         ASC_PRT_NEXT();
8285     }
8286     len = asc_prt_line(cp, leftlen, "\n");
8287     ASC_PRT_NEXT();
8288 
8289     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8290     {
8291         word = ep_3550->tagqng_able;
8292     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8293     {
8294         word = ep_38C0800->tagqng_able;
8295     } else
8296     {
8297         word = ep_38C1600->tagqng_able;
8298     }
8299     len = asc_prt_line(cp, leftlen,
8300 " Command Queuing:     ");
8301     ASC_PRT_NEXT();
8302     for (i = 0; i <= ADV_MAX_TID; i++) {
8303         len = asc_prt_line(cp, leftlen, " %c",
8304             (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8305         ASC_PRT_NEXT();
8306     }
8307     len = asc_prt_line(cp, leftlen, "\n");
8308     ASC_PRT_NEXT();
8309 
8310     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8311     {
8312         word = ep_3550->start_motor;
8313     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8314     {
8315         word = ep_38C0800->start_motor;
8316     } else
8317     {
8318         word = ep_38C1600->start_motor;
8319     }
8320     len = asc_prt_line(cp, leftlen,
8321 " Start Motor:         ");
8322     ASC_PRT_NEXT();
8323     for (i = 0; i <= ADV_MAX_TID; i++) {
8324         len = asc_prt_line(cp, leftlen, " %c",
8325             (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8326         ASC_PRT_NEXT();
8327     }
8328     len = asc_prt_line(cp, leftlen, "\n");
8329     ASC_PRT_NEXT();
8330 
8331     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8332     {
8333         len = asc_prt_line(cp, leftlen,
8334 " Synchronous Transfer:");
8335         ASC_PRT_NEXT();
8336         for (i = 0; i <= ADV_MAX_TID; i++) {
8337             len = asc_prt_line(cp, leftlen, " %c",
8338                 (ep_3550->sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8339             ASC_PRT_NEXT();
8340         }
8341         len = asc_prt_line(cp, leftlen, "\n");
8342         ASC_PRT_NEXT();
8343     }
8344 
8345     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8346     {
8347         len = asc_prt_line(cp, leftlen,
8348 " Ultra Transfer:      ");
8349     ASC_PRT_NEXT();
8350         for (i = 0; i <= ADV_MAX_TID; i++) {
8351             len = asc_prt_line(cp, leftlen, " %c",
8352                 (ep_3550->ultra_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8353             ASC_PRT_NEXT();
8354         }
8355         len = asc_prt_line(cp, leftlen, "\n");
8356         ASC_PRT_NEXT();
8357     }
8358 
8359     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8360     {
8361         word = ep_3550->wdtr_able;
8362     } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8363     {
8364         word = ep_38C0800->wdtr_able;
8365     } else
8366     {
8367         word = ep_38C1600->wdtr_able;
8368     }
8369     len = asc_prt_line(cp, leftlen,
8370 " Wide Transfer:       ");
8371     ASC_PRT_NEXT();
8372     for (i = 0; i <= ADV_MAX_TID; i++) {
8373         len = asc_prt_line(cp, leftlen, " %c",
8374             (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8375         ASC_PRT_NEXT();
8376     }
8377     len = asc_prt_line(cp, leftlen, "\n");
8378     ASC_PRT_NEXT();
8379 
8380     if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
8381         adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600)
8382     {
8383         len = asc_prt_line(cp, leftlen,
8384 " Synchronous Transfer Speed (Mhz):\n  ");
8385         ASC_PRT_NEXT();
8386         for (i = 0; i <= ADV_MAX_TID; i++) {
8387             char *speed_str;
8388 
8389             if (i == 0)
8390             {
8391                 sdtr_speed = adv_dvc_varp->sdtr_speed1;
8392             } else if (i == 4)
8393             {
8394                 sdtr_speed = adv_dvc_varp->sdtr_speed2;
8395             } else if (i == 8)
8396             {
8397                 sdtr_speed = adv_dvc_varp->sdtr_speed3;
8398             } else if (i == 12)
8399             {
8400                 sdtr_speed = adv_dvc_varp->sdtr_speed4;
8401             }
8402             switch (sdtr_speed & ADV_MAX_TID)
8403             {
8404                 case 0:  speed_str = "Off"; break;
8405                 case 1:  speed_str = "  5"; break;
8406                 case 2:  speed_str = " 10"; break;
8407                 case 3:  speed_str = " 20"; break;
8408                 case 4:  speed_str = " 40"; break;
8409                 case 5:  speed_str = " 80"; break;
8410                 default: speed_str = "Unk"; break;
8411             }
8412             len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
8413             ASC_PRT_NEXT();
8414             if (i == 7)
8415             {
8416                 len = asc_prt_line(cp, leftlen, "\n  ");
8417                 ASC_PRT_NEXT();
8418             }
8419             sdtr_speed >>= 4;
8420         }
8421         len = asc_prt_line(cp, leftlen, "\n");
8422         ASC_PRT_NEXT();
8423     }
8424 
8425     return totlen;
8426 }
8427 
8428 /*
8429  * asc_prt_driver_conf()
8430  *
8431  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8432  * cf. asc_prt_line().
8433  *
8434  * Return the number of characters copied into 'cp'. No more than
8435  * 'cplen' characters will be copied to 'cp'.
8436  */
8437 STATIC int
asc_prt_driver_conf(struct Scsi_Host * shp,char * cp,int cplen)8438 asc_prt_driver_conf(struct Scsi_Host *shp, char *cp, int cplen)
8439 {
8440     asc_board_t            *boardp;
8441     int                    leftlen;
8442     int                    totlen;
8443     int                    len;
8444     int                    chip_scsi_id;
8445     int                    i;
8446 
8447     boardp = ASC_BOARDP(shp);
8448 
8449     leftlen = cplen;
8450     totlen = len = 0;
8451 
8452     len = asc_prt_line(cp, leftlen,
8453 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
8454         shp->host_no);
8455     ASC_PRT_NEXT();
8456 
8457     len = asc_prt_line(cp, leftlen,
8458 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
8459         shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun,
8460         shp->max_channel);
8461     ASC_PRT_NEXT();
8462 
8463     len = asc_prt_line(cp, leftlen,
8464 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
8465         shp->unique_id, shp->can_queue, shp->this_id, shp->sg_tablesize,
8466         shp->cmd_per_lun);
8467     ASC_PRT_NEXT();
8468 
8469     len = asc_prt_line(cp, leftlen,
8470 " unchecked_isa_dma %d, use_clustering %d, loaded_as_module %d\n",
8471         shp->unchecked_isa_dma, shp->use_clustering, shp->loaded_as_module);
8472     ASC_PRT_NEXT();
8473 
8474     len = asc_prt_line(cp, leftlen,
8475 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
8476         boardp->flags, boardp->last_reset, jiffies, boardp->asc_n_io_port);
8477     ASC_PRT_NEXT();
8478 
8479      /* 'shp->n_io_port' may be truncated because it is only one byte. */
8480     len = asc_prt_line(cp, leftlen,
8481 " io_port 0x%x, n_io_port 0x%x\n",
8482         shp->io_port, shp->n_io_port);
8483     ASC_PRT_NEXT();
8484 
8485     if (ASC_NARROW_BOARD(boardp)) {
8486         chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
8487     } else {
8488         chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
8489     }
8490 
8491     if (boardp->flags & ASC_SELECT_QUEUE_DEPTHS) {
8492         len = asc_prt_line(cp, leftlen, " queue_depth:");
8493         ASC_PRT_NEXT();
8494         for (i = 0; i <= ADV_MAX_TID; i++) {
8495             if ((chip_scsi_id == i) ||
8496                 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8497                 continue;
8498             }
8499             if (boardp->device[i] == NULL) {
8500                 continue;
8501             }
8502             len = asc_prt_line(cp, leftlen, " %X:%d",
8503                 i, boardp->device[i]->queue_depth);
8504             ASC_PRT_NEXT();
8505         }
8506         len = asc_prt_line(cp, leftlen, "\n");
8507         ASC_PRT_NEXT();
8508     }
8509 
8510     return totlen;
8511 }
8512 
8513 /*
8514  * asc_prt_asc_board_info()
8515  *
8516  * Print dynamic board configuration information.
8517  *
8518  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8519  * cf. asc_prt_line().
8520  *
8521  * Return the number of characters copied into 'cp'. No more than
8522  * 'cplen' characters will be copied to 'cp'.
8523  */
8524 STATIC int
asc_prt_asc_board_info(struct Scsi_Host * shp,char * cp,int cplen)8525 asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8526 {
8527     asc_board_t            *boardp;
8528     int                    chip_scsi_id;
8529     int                    leftlen;
8530     int                    totlen;
8531     int                    len;
8532     ASC_DVC_VAR            *v;
8533     ASC_DVC_CFG            *c;
8534     int                    i;
8535     int                    renegotiate = 0;
8536 
8537     boardp = ASC_BOARDP(shp);
8538     v = &boardp->dvc_var.asc_dvc_var;
8539     c = &boardp->dvc_cfg.asc_dvc_cfg;
8540     chip_scsi_id = c->chip_scsi_id;
8541 
8542     leftlen = cplen;
8543     totlen = len = 0;
8544 
8545     len = asc_prt_line(cp, leftlen,
8546 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8547     shp->host_no);
8548     ASC_PRT_NEXT();
8549 
8550     len = asc_prt_line(cp, leftlen,
8551 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
8552         c->chip_version, c->lib_version, c->lib_serial_no, c->mcode_date);
8553     ASC_PRT_NEXT();
8554 
8555     len = asc_prt_line(cp, leftlen,
8556 " mcode_version 0x%x, err_code %u\n",
8557          c->mcode_version, v->err_code);
8558     ASC_PRT_NEXT();
8559 
8560     /* Current number of commands waiting for the host. */
8561     len = asc_prt_line(cp, leftlen,
8562 " Total Command Pending: %d\n", v->cur_total_qng);
8563     ASC_PRT_NEXT();
8564 
8565     len = asc_prt_line(cp, leftlen,
8566 " Command Queuing:");
8567     ASC_PRT_NEXT();
8568     for (i = 0; i <= ASC_MAX_TID; i++) {
8569         if ((chip_scsi_id == i) ||
8570             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8571             continue;
8572         }
8573         len = asc_prt_line(cp, leftlen, " %X:%c",
8574             i, (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8575         ASC_PRT_NEXT();
8576     }
8577     len = asc_prt_line(cp, leftlen, "\n");
8578     ASC_PRT_NEXT();
8579 
8580     /* Current number of commands waiting for a device. */
8581     len = asc_prt_line(cp, leftlen,
8582 " Command Queue Pending:");
8583     ASC_PRT_NEXT();
8584     for (i = 0; i <= ASC_MAX_TID; i++) {
8585         if ((chip_scsi_id == i) ||
8586             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8587             continue;
8588         }
8589         len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
8590         ASC_PRT_NEXT();
8591     }
8592     len = asc_prt_line(cp, leftlen, "\n");
8593     ASC_PRT_NEXT();
8594 
8595     /* Current limit on number of commands that can be sent to a device. */
8596     len = asc_prt_line(cp, leftlen,
8597 " Command Queue Limit:");
8598     ASC_PRT_NEXT();
8599     for (i = 0; i <= ASC_MAX_TID; i++) {
8600         if ((chip_scsi_id == i) ||
8601             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8602             continue;
8603         }
8604         len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
8605         ASC_PRT_NEXT();
8606     }
8607     len = asc_prt_line(cp, leftlen, "\n");
8608     ASC_PRT_NEXT();
8609 
8610     /* Indicate whether the device has returned queue full status. */
8611     len = asc_prt_line(cp, leftlen,
8612 " Command Queue Full:");
8613     ASC_PRT_NEXT();
8614     for (i = 0; i <= ASC_MAX_TID; i++) {
8615         if ((chip_scsi_id == i) ||
8616             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8617             continue;
8618         }
8619         if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
8620             len = asc_prt_line(cp, leftlen, " %X:Y-%d",
8621                 i, boardp->queue_full_cnt[i]);
8622         } else {
8623             len = asc_prt_line(cp, leftlen, " %X:N", i);
8624         }
8625         ASC_PRT_NEXT();
8626     }
8627     len = asc_prt_line(cp, leftlen, "\n");
8628     ASC_PRT_NEXT();
8629 
8630     len = asc_prt_line(cp, leftlen,
8631 " Synchronous Transfer:");
8632     ASC_PRT_NEXT();
8633     for (i = 0; i <= ASC_MAX_TID; i++) {
8634         if ((chip_scsi_id == i) ||
8635             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8636             continue;
8637         }
8638         len = asc_prt_line(cp, leftlen, " %X:%c",
8639             i, (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8640         ASC_PRT_NEXT();
8641     }
8642     len = asc_prt_line(cp, leftlen, "\n");
8643     ASC_PRT_NEXT();
8644 
8645     for (i = 0; i <= ASC_MAX_TID; i++) {
8646         uchar syn_period_ix;
8647 
8648         if ((chip_scsi_id == i) ||
8649             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
8650             ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
8651             continue;
8652         }
8653 
8654         len = asc_prt_line(cp, leftlen, "  %X:", i);
8655         ASC_PRT_NEXT();
8656 
8657         if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0)
8658         {
8659             len = asc_prt_line(cp, leftlen, " Asynchronous");
8660             ASC_PRT_NEXT();
8661         } else
8662         {
8663             syn_period_ix =
8664                 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1);
8665 
8666             len = asc_prt_line(cp, leftlen,
8667                 " Transfer Period Factor: %d (%d.%d Mhz),",
8668                 v->sdtr_period_tbl[syn_period_ix],
8669                 250 / v->sdtr_period_tbl[syn_period_ix],
8670                 ASC_TENTHS(250, v->sdtr_period_tbl[syn_period_ix]));
8671             ASC_PRT_NEXT();
8672 
8673             len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
8674                 boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET);
8675             ASC_PRT_NEXT();
8676         }
8677 
8678         if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8679             len = asc_prt_line(cp, leftlen, "*\n");
8680             renegotiate = 1;
8681         } else
8682         {
8683             len = asc_prt_line(cp, leftlen, "\n");
8684         }
8685         ASC_PRT_NEXT();
8686     }
8687 
8688     if (renegotiate)
8689     {
8690         len = asc_prt_line(cp, leftlen,
8691             " * = Re-negotiation pending before next command.\n");
8692         ASC_PRT_NEXT();
8693     }
8694 
8695     return totlen;
8696 }
8697 
8698 /*
8699  * asc_prt_adv_board_info()
8700  *
8701  * Print dynamic board configuration information.
8702  *
8703  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8704  * cf. asc_prt_line().
8705  *
8706  * Return the number of characters copied into 'cp'. No more than
8707  * 'cplen' characters will be copied to 'cp'.
8708  */
8709 STATIC int
asc_prt_adv_board_info(struct Scsi_Host * shp,char * cp,int cplen)8710 asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8711 {
8712     asc_board_t            *boardp;
8713     int                    leftlen;
8714     int                    totlen;
8715     int                    len;
8716     int                    i;
8717     ADV_DVC_VAR            *v;
8718     ADV_DVC_CFG            *c;
8719     AdvPortAddr            iop_base;
8720     ushort                 chip_scsi_id;
8721     ushort                 lramword;
8722     uchar                  lrambyte;
8723     ushort                 tagqng_able;
8724     ushort                 sdtr_able, wdtr_able;
8725     ushort                 wdtr_done, sdtr_done;
8726     ushort                 period = 0;
8727     int                    renegotiate = 0;
8728 
8729     boardp = ASC_BOARDP(shp);
8730     v = &boardp->dvc_var.adv_dvc_var;
8731     c = &boardp->dvc_cfg.adv_dvc_cfg;
8732     iop_base = v->iop_base;
8733     chip_scsi_id = v->chip_scsi_id;
8734 
8735     leftlen = cplen;
8736     totlen = len = 0;
8737 
8738     len = asc_prt_line(cp, leftlen,
8739 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8740     shp->host_no);
8741     ASC_PRT_NEXT();
8742 
8743     len = asc_prt_line(cp, leftlen,
8744 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
8745          v->iop_base,
8746          AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1) & CABLE_DETECT,
8747          v->err_code);
8748     ASC_PRT_NEXT();
8749 
8750     len = asc_prt_line(cp, leftlen,
8751 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
8752         c->chip_version, c->lib_version, c->mcode_date, c->mcode_version);
8753     ASC_PRT_NEXT();
8754 
8755     AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8756     len = asc_prt_line(cp, leftlen,
8757 " Queuing Enabled:");
8758     ASC_PRT_NEXT();
8759     for (i = 0; i <= ADV_MAX_TID; i++) {
8760         if ((chip_scsi_id == i) ||
8761             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8762             continue;
8763         }
8764 
8765         len = asc_prt_line(cp, leftlen, " %X:%c",
8766             i, (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8767         ASC_PRT_NEXT();
8768     }
8769     len = asc_prt_line(cp, leftlen, "\n");
8770     ASC_PRT_NEXT();
8771 
8772     len = asc_prt_line(cp, leftlen,
8773 " Queue Limit:");
8774     ASC_PRT_NEXT();
8775     for (i = 0; i <= ADV_MAX_TID; i++) {
8776         if ((chip_scsi_id == i) ||
8777             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8778             continue;
8779         }
8780 
8781         AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, lrambyte);
8782 
8783         len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
8784         ASC_PRT_NEXT();
8785     }
8786     len = asc_prt_line(cp, leftlen, "\n");
8787     ASC_PRT_NEXT();
8788 
8789     len = asc_prt_line(cp, leftlen,
8790 " Command Pending:");
8791     ASC_PRT_NEXT();
8792     for (i = 0; i <= ADV_MAX_TID; i++) {
8793         if ((chip_scsi_id == i) ||
8794             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8795             continue;
8796         }
8797 
8798         AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, lrambyte);
8799 
8800         len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
8801         ASC_PRT_NEXT();
8802     }
8803     len = asc_prt_line(cp, leftlen, "\n");
8804     ASC_PRT_NEXT();
8805 
8806     AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8807     len = asc_prt_line(cp, leftlen,
8808 " Wide Enabled:");
8809     ASC_PRT_NEXT();
8810     for (i = 0; i <= ADV_MAX_TID; i++) {
8811         if ((chip_scsi_id == i) ||
8812             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8813             continue;
8814         }
8815 
8816         len = asc_prt_line(cp, leftlen, " %X:%c",
8817             i, (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8818         ASC_PRT_NEXT();
8819     }
8820     len = asc_prt_line(cp, leftlen, "\n");
8821     ASC_PRT_NEXT();
8822 
8823     AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
8824     len = asc_prt_line(cp, leftlen,
8825 " Transfer Bit Width:");
8826     ASC_PRT_NEXT();
8827     for (i = 0; i <= ADV_MAX_TID; i++) {
8828         if ((chip_scsi_id == i) ||
8829             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8830             continue;
8831         }
8832 
8833         AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
8834             lramword);
8835 
8836         len = asc_prt_line(cp, leftlen, " %X:%d",
8837             i, (lramword & 0x8000) ? 16 : 8);
8838         ASC_PRT_NEXT();
8839 
8840         if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
8841             (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8842             len = asc_prt_line(cp, leftlen, "*");
8843             ASC_PRT_NEXT();
8844             renegotiate = 1;
8845         }
8846     }
8847     len = asc_prt_line(cp, leftlen, "\n");
8848     ASC_PRT_NEXT();
8849 
8850     AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8851     len = asc_prt_line(cp, leftlen,
8852 " Synchronous Enabled:");
8853     ASC_PRT_NEXT();
8854     for (i = 0; i <= ADV_MAX_TID; i++) {
8855         if ((chip_scsi_id == i) ||
8856             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8857             continue;
8858         }
8859 
8860         len = asc_prt_line(cp, leftlen, " %X:%c",
8861             i, (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8862         ASC_PRT_NEXT();
8863     }
8864     len = asc_prt_line(cp, leftlen, "\n");
8865     ASC_PRT_NEXT();
8866 
8867     AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
8868     for (i = 0; i <= ADV_MAX_TID; i++) {
8869 
8870         AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
8871             lramword);
8872         lramword &= ~0x8000;
8873 
8874         if ((chip_scsi_id == i) ||
8875             ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
8876             ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
8877             continue;
8878         }
8879 
8880         len = asc_prt_line(cp, leftlen, "  %X:", i);
8881         ASC_PRT_NEXT();
8882 
8883         if ((lramword & 0x1F) == 0) /* Check for REQ/ACK Offset 0. */
8884         {
8885             len = asc_prt_line(cp, leftlen, " Asynchronous");
8886             ASC_PRT_NEXT();
8887         } else
8888         {
8889             len = asc_prt_line(cp, leftlen, " Transfer Period Factor: ");
8890             ASC_PRT_NEXT();
8891 
8892             if ((lramword & 0x1F00) == 0x1100) /* 80 Mhz */
8893             {
8894                 len = asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
8895                 ASC_PRT_NEXT();
8896             } else if ((lramword & 0x1F00) == 0x1000) /* 40 Mhz */
8897             {
8898                 len = asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
8899                 ASC_PRT_NEXT();
8900             } else /* 20 Mhz or below. */
8901             {
8902                 period = (((lramword >> 8) * 25) + 50)/4;
8903 
8904                 if (period == 0) /* Should never happen. */
8905                 {
8906                     len = asc_prt_line(cp, leftlen, "%d (? Mhz), ");
8907                     ASC_PRT_NEXT();
8908                 } else
8909                 {
8910                     len = asc_prt_line(cp, leftlen,
8911                         "%d (%d.%d Mhz),",
8912                         period, 250/period, ASC_TENTHS(250, period));
8913                     ASC_PRT_NEXT();
8914                 }
8915             }
8916 
8917             len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
8918                 lramword & 0x1F);
8919             ASC_PRT_NEXT();
8920         }
8921 
8922         if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8923             len = asc_prt_line(cp, leftlen, "*\n");
8924             renegotiate = 1;
8925         } else
8926         {
8927             len = asc_prt_line(cp, leftlen, "\n");
8928         }
8929         ASC_PRT_NEXT();
8930     }
8931 
8932     if (renegotiate)
8933     {
8934         len = asc_prt_line(cp, leftlen,
8935             " * = Re-negotiation pending before next command.\n");
8936         ASC_PRT_NEXT();
8937     }
8938 
8939     return totlen;
8940 }
8941 
8942 /*
8943  * asc_proc_copy()
8944  *
8945  * Copy proc information to a read buffer taking into account the current
8946  * read offset in the file and the remaining space in the read buffer.
8947  */
8948 STATIC int
asc_proc_copy(off_t advoffset,off_t offset,char * curbuf,int leftlen,char * cp,int cplen)8949 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
8950               char *cp, int cplen)
8951 {
8952     int cnt = 0;
8953 
8954     ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
8955             (unsigned) offset, (unsigned) advoffset, cplen);
8956     if (offset <= advoffset) {
8957         /* Read offset below current offset, copy everything. */
8958         cnt = ASC_MIN(cplen, leftlen);
8959         ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
8960                 (ulong) curbuf, (ulong) cp, cnt);
8961         memcpy(curbuf, cp, cnt);
8962     } else if (offset < advoffset + cplen) {
8963         /* Read offset within current range, partial copy. */
8964         cnt = (advoffset + cplen) - offset;
8965         cp = (cp + cplen) - cnt;
8966         cnt = ASC_MIN(cnt, leftlen);
8967         ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
8968                 (ulong) curbuf, (ulong) cp, cnt);
8969         memcpy(curbuf, cp, cnt);
8970     }
8971     return cnt;
8972 }
8973 
8974 /*
8975  * asc_prt_line()
8976  *
8977  * If 'cp' is NULL print to the console, otherwise print to a buffer.
8978  *
8979  * Return 0 if printing to the console, otherwise return the number of
8980  * bytes written to the buffer.
8981  *
8982  * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
8983  * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
8984  */
8985 STATIC int
asc_prt_line(char * buf,int buflen,char * fmt,...)8986 asc_prt_line(char *buf, int buflen, char *fmt, ...)
8987 {
8988     va_list        args;
8989     int            ret;
8990     char           s[ASC_PRTLINE_SIZE];
8991 
8992     va_start(args, fmt);
8993     ret = vsprintf(s, fmt, args);
8994     ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
8995     if (buf == NULL) {
8996         (void) printk(s);
8997         ret = 0;
8998     } else {
8999         ret = ASC_MIN(buflen, ret);
9000         memcpy(buf, s, ret);
9001     }
9002     va_end(args);
9003     return ret;
9004 }
9005 #endif /* CONFIG_PROC_FS */
9006 
9007 
9008 /*
9009  * --- Functions Required by the Asc Library
9010  */
9011 
9012 /*
9013  * Delay for 'n' milliseconds. Don't use the 'jiffies'
9014  * global variable which is incremented once every 5 ms
9015  * from a timer interrupt, because this function may be
9016  * called when interrupts are disabled.
9017  */
9018 STATIC void
DvcSleepMilliSecond(ADV_DCNT n)9019 DvcSleepMilliSecond(ADV_DCNT n)
9020 {
9021     ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong) n);
9022     mdelay(n);
9023 }
9024 
9025 /*
9026  * Currently and inline noop but leave as a placeholder.
9027  * Leave DvcEnterCritical() as a noop placeholder.
9028  */
9029 STATIC inline ulong
DvcEnterCritical(void)9030 DvcEnterCritical(void)
9031 {
9032     return 0;
9033 }
9034 
9035 /*
9036  * Critical sections are all protected by the board spinlock.
9037  * Leave DvcLeaveCritical() as a noop placeholder.
9038  */
9039 STATIC inline void
DvcLeaveCritical(ulong flags)9040 DvcLeaveCritical(ulong flags)
9041 {
9042     return;
9043 }
9044 
9045 /*
9046  * void
9047  * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
9048  *
9049  * Calling/Exit State:
9050  *    none
9051  *
9052  * Description:
9053  *     Output an ASC_SCSI_Q structure to the chip
9054  */
9055 STATIC void
DvcPutScsiQ(PortAddr iop_base,ushort s_addr,uchar * outbuf,int words)9056 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
9057 {
9058     int    i;
9059 
9060     ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
9061     AscSetChipLramAddr(iop_base, s_addr);
9062     for (i = 0; i < 2 * words; i += 2) {
9063         if (i == 4 || i == 20) {
9064             continue;
9065         }
9066         outpw(iop_base + IOP_RAM_DATA,
9067             ((ushort) outbuf[i + 1] << 8) | outbuf[i]);
9068     }
9069 }
9070 
9071 /*
9072  * void
9073  * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
9074  *
9075  * Calling/Exit State:
9076  *    none
9077  *
9078  * Description:
9079  *     Input an ASC_QDONE_INFO structure from the chip
9080  */
9081 STATIC void
DvcGetQinfo(PortAddr iop_base,ushort s_addr,uchar * inbuf,int words)9082 DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
9083 {
9084     int    i;
9085     ushort word;
9086 
9087     AscSetChipLramAddr(iop_base, s_addr);
9088     for (i = 0; i < 2 * words; i += 2) {
9089         if (i == 10) {
9090             continue;
9091         }
9092         word = inpw(iop_base + IOP_RAM_DATA);
9093         inbuf[i] = word & 0xff;
9094         inbuf[i + 1] = (word >> 8) & 0xff;
9095     }
9096     ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
9097 }
9098 
9099 /*
9100  * Read a PCI configuration byte.
9101  */
ASC_INITFUNC(STATIC uchar,DvcReadPCIConfigByte (ASC_DVC_VAR * asc_dvc,ushort offset))9102 ASC_INITFUNC(
9103 STATIC uchar,
9104 DvcReadPCIConfigByte(
9105         ASC_DVC_VAR *asc_dvc,
9106         ushort offset)
9107 )
9108 {
9109 #ifdef CONFIG_PCI
9110     uchar byte_data;
9111     pcibios_read_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
9112         PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
9113             ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
9114         offset, &byte_data);
9115     return byte_data;
9116 #else /* !defined(CONFIG_PCI) */
9117     return 0;
9118 #endif /* !defined(CONFIG_PCI) */
9119 }
9120 
9121 /*
9122  * Write a PCI configuration byte.
9123  */
ASC_INITFUNC(STATIC void,DvcWritePCIConfigByte (ASC_DVC_VAR * asc_dvc,ushort offset,uchar byte_data))9124 ASC_INITFUNC(
9125 STATIC void,
9126 DvcWritePCIConfigByte(
9127         ASC_DVC_VAR *asc_dvc,
9128         ushort offset,
9129         uchar  byte_data)
9130 )
9131 {
9132 #ifdef CONFIG_PCI
9133     pcibios_write_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
9134         PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
9135             ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
9136         offset, byte_data);
9137 #endif /* CONFIG_PCI */
9138 }
9139 
9140 /*
9141  * Return the BIOS address of the adapter at the specified
9142  * I/O port and with the specified bus type.
9143  */
ASC_INITFUNC(STATIC ushort,AscGetChipBiosAddress (PortAddr iop_base,ushort bus_type))9144 ASC_INITFUNC(
9145 STATIC ushort,
9146 AscGetChipBiosAddress(
9147         PortAddr iop_base,
9148         ushort bus_type
9149 )
9150 )
9151 {
9152     ushort  cfg_lsw;
9153     ushort  bios_addr;
9154 
9155     /*
9156      * The PCI BIOS is re-located by the motherboard BIOS. Because
9157      * of this the driver can not determine where a PCI BIOS is
9158      * loaded and executes.
9159      */
9160     if (bus_type & ASC_IS_PCI)
9161     {
9162         return(0);
9163     }
9164 
9165 #ifdef CONFIG_ISA
9166     if((bus_type & ASC_IS_EISA) != 0)
9167     {
9168         cfg_lsw = AscGetEisaChipCfg(iop_base);
9169         cfg_lsw &= 0x000F;
9170         bios_addr = (ushort)(ASC_BIOS_MIN_ADDR  +
9171                                 (cfg_lsw * ASC_BIOS_BANK_SIZE));
9172         return(bios_addr);
9173     }/* if */
9174 #endif /* CONFIG_ISA */
9175 
9176     cfg_lsw = AscGetChipCfgLsw(iop_base);
9177 
9178     /*
9179     *  ISA PnP uses the top bit as the 32K BIOS flag
9180     */
9181     if (bus_type == ASC_IS_ISAPNP)
9182     {
9183         cfg_lsw &= 0x7FFF;
9184     }/* if */
9185 
9186     bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
9187             ASC_BIOS_MIN_ADDR);
9188     return(bios_addr);
9189 }
9190 
9191 
9192 /*
9193  * --- Functions Required by the Adv Library
9194  */
9195 
9196 /*
9197  * DvcGetPhyAddr()
9198  *
9199  * Return the physical address of 'vaddr' and set '*lenp' to the
9200  * number of physically contiguous bytes that follow 'vaddr'.
9201  * 'flag' indicates the type of structure whose physical address
9202  * is being translated.
9203  *
9204  * Note: Because Linux currently doesn't page the kernel and all
9205  * kernel buffers are physically contiguous, leave '*lenp' unchanged.
9206  */
9207 ADV_PADDR
DvcGetPhyAddr(ADV_DVC_VAR * asc_dvc,ADV_SCSI_REQ_Q * scsiq,uchar * vaddr,ADV_SDCNT * lenp,int flag)9208 DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
9209         uchar *vaddr, ADV_SDCNT *lenp, int flag)
9210 {
9211     ADV_PADDR           paddr;
9212 
9213     paddr = virt_to_bus(vaddr);
9214 
9215     ASC_DBG4(4,
9216         "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
9217         (ulong) vaddr, (ulong) lenp, (ulong) *((ulong *) lenp), (ulong) paddr);
9218 
9219     return paddr;
9220 }
9221 
9222 /*
9223  * Read a PCI configuration byte.
9224  */
ASC_INITFUNC(STATIC uchar,DvcAdvReadPCIConfigByte (ADV_DVC_VAR * asc_dvc,ushort offset))9225 ASC_INITFUNC(
9226 STATIC uchar,
9227 DvcAdvReadPCIConfigByte(
9228         ADV_DVC_VAR *asc_dvc,
9229         ushort offset)
9230 )
9231 {
9232 #ifdef CONFIG_PCI
9233     uchar byte_data;
9234     pcibios_read_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
9235         PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
9236             ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
9237         offset, &byte_data);
9238     return byte_data;
9239 #else /* CONFIG_PCI */
9240     return 0;
9241 #endif /* CONFIG_PCI */
9242 }
9243 
9244 /*
9245  * Write a PCI configuration byte.
9246  */
ASC_INITFUNC(STATIC void,DvcAdvWritePCIConfigByte (ADV_DVC_VAR * asc_dvc,ushort offset,uchar byte_data))9247 ASC_INITFUNC(
9248 STATIC void,
9249 DvcAdvWritePCIConfigByte(
9250         ADV_DVC_VAR *asc_dvc,
9251         ushort offset,
9252         uchar  byte_data)
9253 )
9254 {
9255 #ifdef CONFIG_PCI
9256     pcibios_write_config_byte(ASC_PCI_ID2BUS(asc_dvc->cfg->pci_slot_info),
9257         PCI_DEVFN(ASC_PCI_ID2DEV(asc_dvc->cfg->pci_slot_info),
9258             ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info)),
9259         offset, byte_data);
9260 #endif /* CONFIG_PCI */
9261 }
9262 
9263 /*
9264  * --- Tracing and Debugging Functions
9265  */
9266 
9267 #ifdef ADVANSYS_STATS
9268 #ifdef CONFIG_PROC_FS
9269 /*
9270  * asc_prt_board_stats()
9271  *
9272  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
9273  * cf. asc_prt_line().
9274  *
9275  * Return the number of characters copied into 'cp'. No more than
9276  * 'cplen' characters will be copied to 'cp'.
9277  */
9278 STATIC int
asc_prt_board_stats(struct Scsi_Host * shp,char * cp,int cplen)9279 asc_prt_board_stats(struct Scsi_Host *shp, char *cp, int cplen)
9280 {
9281     int                    leftlen;
9282     int                    totlen;
9283     int                    len;
9284     struct asc_stats       *s;
9285     asc_board_t            *boardp;
9286 
9287     leftlen = cplen;
9288     totlen = len = 0;
9289 
9290     boardp = ASC_BOARDP(shp);
9291     s = &boardp->asc_stats;
9292 
9293     len = asc_prt_line(cp, leftlen,
9294 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", shp->host_no);
9295     ASC_PRT_NEXT();
9296 
9297     len = asc_prt_line(cp, leftlen,
9298 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
9299         s->queuecommand, s->reset, s->biosparam, s->interrupt);
9300     ASC_PRT_NEXT();
9301 
9302     len = asc_prt_line(cp, leftlen,
9303 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
9304         s->callback, s->done, s->build_error, s->adv_build_noreq,
9305         s->adv_build_nosg);
9306     ASC_PRT_NEXT();
9307 
9308     len = asc_prt_line(cp, leftlen,
9309 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
9310         s->exe_noerror, s->exe_busy, s->exe_error, s->exe_unknown);
9311     ASC_PRT_NEXT();
9312 
9313     /*
9314      * Display data transfer statistics.
9315      */
9316     if (s->cont_cnt > 0) {
9317         len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
9318         ASC_PRT_NEXT();
9319 
9320         len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
9321                     s->cont_xfer/2,
9322                     ASC_TENTHS(s->cont_xfer, 2));
9323         ASC_PRT_NEXT();
9324 
9325         /* Contiguous transfer average size */
9326         len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
9327                     (s->cont_xfer/2)/s->cont_cnt,
9328                     ASC_TENTHS((s->cont_xfer/2), s->cont_cnt));
9329         ASC_PRT_NEXT();
9330     }
9331 
9332     if (s->sg_cnt > 0) {
9333 
9334         len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
9335                     s->sg_cnt, s->sg_elem);
9336         ASC_PRT_NEXT();
9337 
9338         len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
9339                     s->sg_xfer/2,
9340                     ASC_TENTHS(s->sg_xfer, 2));
9341         ASC_PRT_NEXT();
9342 
9343         /* Scatter gather transfer statistics */
9344         len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
9345                     s->sg_elem/s->sg_cnt,
9346                     ASC_TENTHS(s->sg_elem, s->sg_cnt));
9347         ASC_PRT_NEXT();
9348 
9349         len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
9350                     (s->sg_xfer/2)/s->sg_elem,
9351                     ASC_TENTHS((s->sg_xfer/2), s->sg_elem));
9352         ASC_PRT_NEXT();
9353 
9354         len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
9355                     (s->sg_xfer/2)/s->sg_cnt,
9356                     ASC_TENTHS((s->sg_xfer/2), s->sg_cnt));
9357         ASC_PRT_NEXT();
9358     }
9359 
9360     /*
9361      * Display request queuing statistics.
9362      */
9363     len = asc_prt_line(cp, leftlen,
9364 " Active and Waiting Request Queues (Time Unit: %d HZ):\n", HZ);
9365     ASC_PRT_NEXT();
9366 
9367 
9368      return totlen;
9369 }
9370 
9371 /*
9372  * asc_prt_target_stats()
9373  *
9374  * Note: no single line should be greater than ASC_PRTLINE_SIZE,
9375  * cf. asc_prt_line().
9376  *
9377  * This is separated from asc_prt_board_stats because a full set
9378  * of targets will overflow ASC_PRTBUF_SIZE.
9379  *
9380  * Return the number of characters copied into 'cp'. No more than
9381  * 'cplen' characters will be copied to 'cp'.
9382  */
9383 STATIC int
asc_prt_target_stats(struct Scsi_Host * shp,int tgt_id,char * cp,int cplen)9384 asc_prt_target_stats(struct Scsi_Host *shp, int tgt_id, char *cp, int cplen)
9385 {
9386     int                    leftlen;
9387     int                    totlen;
9388     int                    len;
9389     struct asc_stats       *s;
9390     ushort                 chip_scsi_id;
9391     asc_board_t            *boardp;
9392     asc_queue_t            *active;
9393     asc_queue_t            *waiting;
9394 
9395     leftlen = cplen;
9396     totlen = len = 0;
9397 
9398     boardp = ASC_BOARDP(shp);
9399     s = &boardp->asc_stats;
9400 
9401     active = &ASC_BOARDP(shp)->active;
9402     waiting = &ASC_BOARDP(shp)->waiting;
9403 
9404     if (ASC_NARROW_BOARD(boardp)) {
9405         chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
9406     } else {
9407         chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
9408     }
9409 
9410     if ((chip_scsi_id == tgt_id) ||
9411         ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
9412         return 0;
9413     }
9414 
9415     do {
9416         if (active->q_tot_cnt[tgt_id] > 0 || waiting->q_tot_cnt[tgt_id] > 0) {
9417             len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
9418             ASC_PRT_NEXT();
9419 
9420             len = asc_prt_line(cp, leftlen,
9421 "   active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
9422                 active->q_cur_cnt[tgt_id], active->q_max_cnt[tgt_id],
9423                 active->q_tot_cnt[tgt_id],
9424                 active->q_min_tim[tgt_id], active->q_max_tim[tgt_id],
9425                 (active->q_tot_cnt[tgt_id] == 0) ? 0 :
9426                 (active->q_tot_tim[tgt_id]/active->q_tot_cnt[tgt_id]),
9427                 (active->q_tot_cnt[tgt_id] == 0) ? 0 :
9428                 ASC_TENTHS(active->q_tot_tim[tgt_id],
9429                 active->q_tot_cnt[tgt_id]));
9430              ASC_PRT_NEXT();
9431 
9432              len = asc_prt_line(cp, leftlen,
9433 "   waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
9434                 waiting->q_cur_cnt[tgt_id], waiting->q_max_cnt[tgt_id],
9435                 waiting->q_tot_cnt[tgt_id],
9436                 waiting->q_min_tim[tgt_id], waiting->q_max_tim[tgt_id],
9437                 (waiting->q_tot_cnt[tgt_id] == 0) ? 0 :
9438                 (waiting->q_tot_tim[tgt_id]/waiting->q_tot_cnt[tgt_id]),
9439                 (waiting->q_tot_cnt[tgt_id] == 0) ? 0 :
9440                 ASC_TENTHS(waiting->q_tot_tim[tgt_id],
9441                 waiting->q_tot_cnt[tgt_id]));
9442              ASC_PRT_NEXT();
9443         }
9444     } while (0);
9445 
9446      return totlen;
9447 }
9448 #endif /* CONFIG_PROC_FS */
9449 #endif /* ADVANSYS_STATS */
9450 
9451 #ifdef ADVANSYS_DEBUG
9452 /*
9453  * asc_prt_scsi_host()
9454  */
9455 STATIC void
asc_prt_scsi_host(struct Scsi_Host * s)9456 asc_prt_scsi_host(struct Scsi_Host *s)
9457 {
9458     asc_board_t         *boardp;
9459 
9460     boardp = ASC_BOARDP(s);
9461 
9462     printk("Scsi_Host at addr 0x%lx\n", (ulong) s);
9463     printk(
9464 " next 0x%lx, extra_bytes %u, host_busy %u, host_no %d, last_reset %d,\n",
9465         (ulong) s->next, s->extra_bytes, s->host_busy, s->host_no,
9466         (unsigned) s->last_reset);
9467 
9468 #if ASC_LINUX_KERNEL24
9469     printk(
9470 " host_queue 0x%lx, hostt 0x%lx\n",
9471         (ulong) s->host_queue, (ulong) s->hostt);
9472 #elif ASC_LINUX_KERNEL22
9473     printk(
9474 " host_queue 0x%lx, hostt 0x%lx, block 0x%lx,\n",
9475         (ulong) s->host_queue, (ulong) s->hostt, (ulong) s->block);
9476 #endif
9477 
9478     printk(
9479 " base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
9480         (ulong) s->base, (ulong) s->io_port, s->n_io_port, s->irq);
9481 
9482     printk(
9483 " dma_channel %d, this_id %d, can_queue %d,\n",
9484         s->dma_channel, s->this_id, s->can_queue);
9485 
9486     printk(
9487 " cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d, loaded_as_module %d\n",
9488         s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma,
9489         s->loaded_as_module);
9490 
9491     if (ASC_NARROW_BOARD(boardp)) {
9492         asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
9493         asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
9494     } else {
9495         asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
9496         asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
9497     }
9498 }
9499 
9500 /*
9501  * asc_prt_scsi_cmnd()
9502  */
9503 STATIC void
asc_prt_scsi_cmnd(Scsi_Cmnd * s)9504 asc_prt_scsi_cmnd(Scsi_Cmnd *s)
9505 {
9506     printk("Scsi_Cmnd at addr 0x%lx\n", (ulong) s);
9507 
9508     printk(
9509 " host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
9510         (ulong) s->host, (ulong) s->device, s->target, s->lun,
9511         s->channel);
9512 
9513     asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
9514 
9515 #if ASC_LINUX_KERNEL24
9516     printk (
9517 "sc_data_direction %u, resid %d\n",
9518         s->sc_data_direction, s->resid);
9519 #endif
9520 
9521     printk(
9522 " use_sg %u, sglist_len %u, abort_reason 0x%x\n",
9523         s->use_sg, s->sglist_len, s->abort_reason);
9524 
9525     printk(
9526 " serial_number 0x%x, serial_number_at_timeout 0x%x, retries %d, allowed %d\n",
9527         (unsigned) s->serial_number, (unsigned) s->serial_number_at_timeout,
9528          s->retries, s->allowed);
9529 
9530     printk(
9531 " timeout_per_command %d, timeout_total %d, timeout %d\n",
9532         s->timeout_per_command, s->timeout_total, s->timeout);
9533 
9534 #if ASC_LINUX_KERNEL24
9535     printk(
9536 " internal_timeout %u, flags %u\n",
9537         s->internal_timeout, s->flags);
9538 #elif ASC_LINUX_KERNEL22
9539     printk(
9540 " internal_timeout %u, flags %u, this_count %d\n",
9541         s->internal_timeout, s->flags,s->this_count);
9542 #endif
9543 
9544     printk(
9545 " scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
9546         (ulong) s->scsi_done, (ulong) s->done,
9547         (ulong) s->host_scribble, s->result);
9548 
9549     printk(
9550 " tag %u, pid %u\n",
9551         (unsigned) s->tag, (unsigned) s->pid);
9552 }
9553 
9554 /*
9555  * asc_prt_asc_dvc_var()
9556  */
9557 STATIC void
asc_prt_asc_dvc_var(ASC_DVC_VAR * h)9558 asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
9559 {
9560     printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong) h);
9561 
9562     printk(
9563 " iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n",
9564         h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
9565 
9566     printk(
9567 " bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n",
9568         h->bus_type, (ulong) h->isr_callback, (ulong) h->exe_callback,
9569         (unsigned) h->init_sdtr);
9570 
9571     printk(
9572 " sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n",
9573         (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng,
9574         (unsigned) h->unit_not_ready, (unsigned) h->chip_no);
9575 
9576     printk(
9577 " queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n",
9578         (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor,
9579         (unsigned) h->scsi_reset_wait);
9580 
9581     printk(
9582 " is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n",
9583         (unsigned) h->is_in_int, (unsigned) h->max_total_qng,
9584         (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt);
9585 
9586     printk(
9587 " last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n",
9588         (unsigned) h->last_q_shortage, (unsigned) h->init_state,
9589         (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer);
9590 
9591     printk(
9592 " cfg 0x%lx, irq_no 0x%x\n",
9593         (ulong) h->cfg, (unsigned) h->irq_no);
9594 }
9595 
9596 /*
9597  * asc_prt_asc_dvc_cfg()
9598  */
9599 STATIC void
asc_prt_asc_dvc_cfg(ASC_DVC_CFG * h)9600 asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
9601 {
9602     printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong) h);
9603 
9604     printk(
9605 " can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
9606             h->can_tagged_qng, h->cmd_qng_enabled);
9607     printk(
9608 " disc_enable 0x%x, sdtr_enable 0x%x,\n",
9609             h->disc_enable, h->sdtr_enable);
9610 
9611     printk(
9612 " chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
9613              h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
9614              h->chip_version);
9615 
9616     printk(
9617 " pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
9618           h->pci_device_id, h->lib_serial_no, h->lib_version, h->mcode_date);
9619 
9620     printk(
9621 " mcode_version %d, overrun_buf 0x%lx\n",
9622             h->mcode_version, (ulong) h->overrun_buf);
9623 }
9624 
9625 /*
9626  * asc_prt_asc_scsi_q()
9627  */
9628 STATIC void
asc_prt_asc_scsi_q(ASC_SCSI_Q * q)9629 asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
9630 {
9631     ASC_SG_HEAD    *sgp;
9632     int i;
9633 
9634     printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong) q);
9635 
9636     printk(
9637 " target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
9638             q->q2.target_ix, q->q1.target_lun,
9639             (ulong) q->q2.srb_ptr, q->q2.tag_code);
9640 
9641     printk(
9642 " data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
9643             (ulong) le32_to_cpu(q->q1.data_addr),
9644             (ulong) le32_to_cpu(q->q1.data_cnt),
9645             (ulong) le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
9646 
9647     printk(
9648 " cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
9649             (ulong) q->cdbptr, q->q2.cdb_len,
9650             (ulong) q->sg_head, q->q1.sg_queue_cnt);
9651 
9652     if (q->sg_head) {
9653         sgp = q->sg_head;
9654         printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong) sgp);
9655         printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt);
9656         for (i = 0; i < sgp->entry_cnt; i++) {
9657             printk(" [%u]: addr 0x%lx, bytes %lu\n",
9658                 i, (ulong) le32_to_cpu(sgp->sg_list[i].addr),
9659                 (ulong) le32_to_cpu(sgp->sg_list[i].bytes));
9660         }
9661 
9662     }
9663 }
9664 
9665 /*
9666  * asc_prt_asc_qdone_info()
9667  */
9668 STATIC void
asc_prt_asc_qdone_info(ASC_QDONE_INFO * q)9669 asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
9670 {
9671     printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong) q);
9672     printk(
9673 " srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
9674             (ulong) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
9675             q->d2.tag_code);
9676     printk(
9677 " done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
9678             q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
9679 }
9680 
9681 /*
9682  * asc_prt_adv_dvc_var()
9683  *
9684  * Display an ADV_DVC_VAR structure.
9685  */
9686 STATIC void
asc_prt_adv_dvc_var(ADV_DVC_VAR * h)9687 asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
9688 {
9689     printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong) h);
9690 
9691     printk(
9692 "  iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
9693         (ulong) h->iop_base, h->err_code, (unsigned) h->ultra_able);
9694 
9695     printk(
9696 "  isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
9697         (ulong) h->isr_callback, (unsigned) h->sdtr_able,
9698         (unsigned) h->wdtr_able);
9699 
9700     printk(
9701 "  start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
9702         (unsigned) h->start_motor,
9703         (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
9704 
9705     printk(
9706 "  max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
9707         (unsigned) h->max_host_qng, (unsigned) h->max_dvc_qng,
9708         (ulong) h->carr_freelist);
9709 
9710     printk(
9711 "  icq_sp 0x%lx, irq_sp 0x%lx\n",
9712         (ulong) h->icq_sp, (ulong) h->irq_sp);
9713 
9714     printk(
9715 "  no_scam 0x%x, tagqng_able 0x%x\n",
9716         (unsigned) h->no_scam, (unsigned) h->tagqng_able);
9717 
9718     printk(
9719 "  chip_scsi_id 0x%x, cfg 0x%lx\n",
9720         (unsigned) h->chip_scsi_id, (ulong) h->cfg);
9721 }
9722 
9723 /*
9724  * asc_prt_adv_dvc_cfg()
9725  *
9726  * Display an ADV_DVC_CFG structure.
9727  */
9728 STATIC void
asc_prt_adv_dvc_cfg(ADV_DVC_CFG * h)9729 asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
9730 {
9731     printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong) h);
9732 
9733     printk(
9734 "  disc_enable 0x%x, termination 0x%x\n",
9735         h->disc_enable, h->termination);
9736 
9737     printk(
9738 "  chip_version 0x%x, mcode_date 0x%x\n",
9739         h->chip_version, h->mcode_date);
9740 
9741     printk(
9742 "  mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
9743        h->mcode_version, h->pci_device_id, h->lib_version);
9744 
9745     printk(
9746 "  control_flag 0x%x, pci_slot_info 0x%x\n",
9747        h->control_flag, h->pci_slot_info);
9748 }
9749 
9750 /*
9751  * asc_prt_adv_scsi_req_q()
9752  *
9753  * Display an ADV_SCSI_REQ_Q structure.
9754  */
9755 STATIC void
asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q * q)9756 asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
9757 {
9758     int                 sg_blk_cnt;
9759     struct asc_sg_block *sg_ptr;
9760 
9761     printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong) q);
9762 
9763     printk(
9764 "  target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
9765             q->target_id, q->target_lun, (ulong) q->srb_ptr, q->a_flag);
9766 
9767     printk("  cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
9768             q->cntl, (ulong) le32_to_cpu(q->data_addr), (ulong) q->vdata_addr);
9769 
9770     printk(
9771 "  data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
9772             (ulong) le32_to_cpu(q->data_cnt),
9773             (ulong) le32_to_cpu(q->sense_addr), q->sense_len);
9774 
9775     printk(
9776 "  cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
9777             q->cdb_len, q->done_status, q->host_status, q->scsi_status);
9778 
9779     printk(
9780 "  sg_working_ix 0x%x, target_cmd %u\n",
9781             q->sg_working_ix, q->target_cmd);
9782 
9783     printk(
9784 "  scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
9785             (ulong) le32_to_cpu(q->scsiq_rptr),
9786             (ulong) le32_to_cpu(q->sg_real_addr), (ulong) q->sg_list_ptr);
9787 
9788     /* Display the request's ADV_SG_BLOCK structures. */
9789     if (q->sg_list_ptr != NULL)
9790     {
9791         sg_blk_cnt = 0;
9792         while (1) {
9793             /*
9794              * 'sg_ptr' is a physical address. Convert it to a virtual
9795              * address by indexing 'sg_blk_cnt' into the virtual address
9796              * array 'sg_list_ptr'.
9797              *
9798              * XXX - Assumes all SG physical blocks are virtually contiguous.
9799              */
9800             sg_ptr = &(((ADV_SG_BLOCK *) (q->sg_list_ptr))[sg_blk_cnt]);
9801             asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
9802             if (sg_ptr->sg_ptr == 0)
9803             {
9804                 break;
9805             }
9806             sg_blk_cnt++;
9807         }
9808     }
9809 }
9810 
9811 /*
9812  * asc_prt_adv_sgblock()
9813  *
9814  * Display an ADV_SG_BLOCK structure.
9815  */
9816 STATIC void
asc_prt_adv_sgblock(int sgblockno,ADV_SG_BLOCK * b)9817 asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
9818 {
9819     int i;
9820 
9821     printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
9822         (ulong) b, sgblockno);
9823     printk("  sg_cnt %u, sg_ptr 0x%lx\n",
9824         b->sg_cnt, (ulong) le32_to_cpu(b->sg_ptr));
9825     ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
9826     if (b->sg_ptr != 0)
9827     {
9828         ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
9829     }
9830     for (i = 0; i < b->sg_cnt; i++) {
9831         printk("  [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
9832             i, (ulong) b->sg_list[i].sg_addr, (ulong) b->sg_list[i].sg_count);
9833     }
9834 }
9835 
9836 /*
9837  * asc_prt_hex()
9838  *
9839  * Print hexadecimal output in 4 byte groupings 32 bytes
9840  * or 8 double-words per line.
9841  */
9842 STATIC void
asc_prt_hex(char * f,uchar * s,int l)9843 asc_prt_hex(char *f, uchar *s, int l)
9844 {
9845     int            i;
9846     int            j;
9847     int            k;
9848     int            m;
9849 
9850     printk("%s: (%d bytes)\n", f, l);
9851 
9852     for (i = 0; i < l; i += 32) {
9853 
9854         /* Display a maximum of 8 double-words per line. */
9855         if ((k = (l - i) / 4) >= 8) {
9856             k = 8;
9857             m = 0;
9858         } else {
9859             m = (l - i) % 4;
9860         }
9861 
9862         for (j = 0; j < k; j++) {
9863             printk(" %2.2X%2.2X%2.2X%2.2X",
9864                 (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1],
9865                 (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]);
9866         }
9867 
9868         switch (m) {
9869         case 0:
9870         default:
9871             break;
9872         case 1:
9873             printk(" %2.2X",
9874                 (unsigned) s[i+(j*4)]);
9875             break;
9876         case 2:
9877             printk(" %2.2X%2.2X",
9878                 (unsigned) s[i+(j*4)],
9879                 (unsigned) s[i+(j*4)+1]);
9880             break;
9881         case 3:
9882             printk(" %2.2X%2.2X%2.2X",
9883                 (unsigned) s[i+(j*4)+1],
9884                 (unsigned) s[i+(j*4)+2],
9885                 (unsigned) s[i+(j*4)+3]);
9886             break;
9887         }
9888 
9889         printk("\n");
9890     }
9891 }
9892 #endif /* ADVANSYS_DEBUG */
9893 
9894 /*
9895  * --- Asc Library Functions
9896  */
9897 
ASC_INITFUNC(STATIC ushort,AscGetEisaChipCfg (PortAddr iop_base))9898 ASC_INITFUNC(
9899 STATIC ushort,
9900 AscGetEisaChipCfg(
9901                      PortAddr iop_base
9902 )
9903 )
9904 {
9905     PortAddr            eisa_cfg_iop;
9906 
9907     eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
9908       (PortAddr) (ASC_EISA_CFG_IOP_MASK);
9909     return (inpw(eisa_cfg_iop));
9910 }
9911 
ASC_INITFUNC(STATIC uchar,AscSetChipScsiID (PortAddr iop_base,uchar new_host_id))9912 ASC_INITFUNC(
9913 STATIC uchar,
9914 AscSetChipScsiID(
9915                     PortAddr iop_base,
9916                     uchar new_host_id
9917 )
9918 )
9919 {
9920     ushort              cfg_lsw;
9921 
9922     if (AscGetChipScsiID(iop_base) == new_host_id) {
9923         return (new_host_id);
9924     }
9925     cfg_lsw = AscGetChipCfgLsw(iop_base);
9926     cfg_lsw &= 0xF8FF;
9927     cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID) << 8);
9928     AscSetChipCfgLsw(iop_base, cfg_lsw);
9929     return (AscGetChipScsiID(iop_base));
9930 }
9931 
ASC_INITFUNC(STATIC uchar,AscGetChipScsiCtrl (PortAddr iop_base))9932 ASC_INITFUNC(
9933 STATIC uchar,
9934 AscGetChipScsiCtrl(
9935                       PortAddr iop_base
9936 )
9937 )
9938 {
9939     uchar               sc;
9940 
9941     AscSetBank(iop_base, 1);
9942     sc = inp(iop_base + IOP_REG_SC);
9943     AscSetBank(iop_base, 0);
9944     return (sc);
9945 }
9946 
ASC_INITFUNC(STATIC uchar,AscGetChipVersion (PortAddr iop_base,ushort bus_type))9947 ASC_INITFUNC(
9948 STATIC uchar,
9949 AscGetChipVersion(
9950                      PortAddr iop_base,
9951                      ushort bus_type
9952 )
9953 )
9954 {
9955     if ((bus_type & ASC_IS_EISA) != 0) {
9956         PortAddr            eisa_iop;
9957         uchar               revision;
9958         eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
9959           (PortAddr) ASC_EISA_REV_IOP_MASK;
9960         revision = inp(eisa_iop);
9961         return ((uchar) ((ASC_CHIP_MIN_VER_EISA - 1) + revision));
9962     }
9963     return (AscGetChipVerNo(iop_base));
9964 }
9965 
ASC_INITFUNC(STATIC ushort,AscGetChipBusType (PortAddr iop_base))9966 ASC_INITFUNC(
9967 STATIC ushort,
9968 AscGetChipBusType(
9969                      PortAddr iop_base
9970 )
9971 )
9972 {
9973     ushort              chip_ver;
9974 
9975     chip_ver = AscGetChipVerNo(iop_base);
9976     if (
9977            (chip_ver >= ASC_CHIP_MIN_VER_VL)
9978            && (chip_ver <= ASC_CHIP_MAX_VER_VL)
9979 ) {
9980         if (
9981                ((iop_base & 0x0C30) == 0x0C30)
9982                || ((iop_base & 0x0C50) == 0x0C50)
9983 ) {
9984             return (ASC_IS_EISA);
9985         }
9986         return (ASC_IS_VL);
9987     }
9988     if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
9989         (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
9990         if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
9991             return (ASC_IS_ISAPNP);
9992         }
9993         return (ASC_IS_ISA);
9994     } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
9995                (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
9996         return (ASC_IS_PCI);
9997     }
9998     return (0);
9999 }
10000 
10001 STATIC ASC_DCNT
AscLoadMicroCode(PortAddr iop_base,ushort s_addr,uchar * mcode_buf,ushort mcode_size)10002 AscLoadMicroCode(
10003                     PortAddr iop_base,
10004                     ushort s_addr,
10005                     uchar *mcode_buf,
10006                     ushort mcode_size
10007 )
10008 {
10009     ASC_DCNT            chksum;
10010     ushort              mcode_word_size;
10011     ushort              mcode_chksum;
10012 
10013     /* Write the microcode buffer starting at LRAM address 0. */
10014     mcode_word_size = (ushort) (mcode_size >> 1);
10015     AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
10016     AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
10017 
10018     chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
10019     ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong) chksum);
10020     mcode_chksum = (ushort) AscMemSumLramWord(iop_base,
10021           (ushort) ASC_CODE_SEC_BEG,
10022           (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2));
10023     ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
10024         (ulong) mcode_chksum);
10025     AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
10026     AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
10027     return (chksum);
10028 }
10029 
10030 STATIC int
AscFindSignature(PortAddr iop_base)10031 AscFindSignature(
10032                     PortAddr iop_base
10033 )
10034 {
10035     ushort              sig_word;
10036 
10037     ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
10038         iop_base, AscGetChipSignatureByte(iop_base));
10039     if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) {
10040         ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
10041             iop_base, AscGetChipSignatureWord(iop_base));
10042         sig_word = AscGetChipSignatureWord(iop_base);
10043         if ((sig_word == (ushort) ASC_1000_ID0W) ||
10044             (sig_word == (ushort) ASC_1000_ID0W_FIX)) {
10045             return (1);
10046         }
10047     }
10048     return (0);
10049 }
10050 
10051 STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] ASC_INITDATA =
10052 {
10053     0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
10054     ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
10055 };
10056 
10057 #ifdef CONFIG_ISA
10058 STATIC uchar _isa_pnp_inited ASC_INITDATA = 0;
10059 
ASC_INITFUNC(STATIC PortAddr,AscSearchIOPortAddr (PortAddr iop_beg,ushort bus_type))10060 ASC_INITFUNC(
10061 STATIC PortAddr,
10062 AscSearchIOPortAddr(
10063                        PortAddr iop_beg,
10064                        ushort bus_type
10065 )
10066 )
10067 {
10068     if (bus_type & ASC_IS_VL) {
10069         while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
10070             if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL) {
10071                 return (iop_beg);
10072             }
10073         }
10074         return (0);
10075     }
10076     if (bus_type & ASC_IS_ISA) {
10077         if (_isa_pnp_inited == 0) {
10078             AscSetISAPNPWaitForKey();
10079             _isa_pnp_inited++;
10080         }
10081         while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
10082             if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT) != 0) {
10083                 return (iop_beg);
10084             }
10085         }
10086         return (0);
10087     }
10088     if (bus_type & ASC_IS_EISA) {
10089         if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
10090             return (iop_beg);
10091         }
10092         return (0);
10093     }
10094     return (0);
10095 }
10096 
ASC_INITFUNC(STATIC PortAddr,AscSearchIOPortAddr11 (PortAddr s_addr))10097 ASC_INITFUNC(
10098 STATIC PortAddr,
10099 AscSearchIOPortAddr11(
10100                          PortAddr s_addr
10101 )
10102 )
10103 {
10104     int                 i;
10105     PortAddr            iop_base;
10106 
10107     for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
10108         if (_asc_def_iop_base[i] > s_addr) {
10109             break;
10110         }
10111     }
10112     for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
10113         iop_base = _asc_def_iop_base[i];
10114         if (check_region(iop_base, ASC_IOADR_GAP) != 0) {
10115             ASC_DBG1(1,
10116                "AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n",
10117                      iop_base);
10118             continue;
10119         }
10120         ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n", iop_base);
10121         if (AscFindSignature(iop_base)) {
10122             return (iop_base);
10123         }
10124     }
10125     return (0);
10126 }
10127 
ASC_INITFUNC(STATIC void,AscSetISAPNPWaitForKey (void))10128 ASC_INITFUNC(
10129 STATIC void,
10130 AscSetISAPNPWaitForKey(
10131     void)
10132 )
10133 {
10134     outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
10135     outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
10136     return;
10137 }
10138 #endif /* CONFIG_ISA */
10139 
ASC_INITFUNC(STATIC void,AscToggleIRQAct (PortAddr iop_base))10140 ASC_INITFUNC(
10141 STATIC void,
10142 AscToggleIRQAct(
10143                    PortAddr iop_base
10144 )
10145 )
10146 {
10147     AscSetChipStatus(iop_base, CIW_IRQ_ACT);
10148     AscSetChipStatus(iop_base, 0);
10149     return;
10150 }
10151 
ASC_INITFUNC(STATIC uchar,AscGetChipIRQ (PortAddr iop_base,ushort bus_type))10152 ASC_INITFUNC(
10153 STATIC uchar,
10154 AscGetChipIRQ(
10155                  PortAddr iop_base,
10156                  ushort bus_type
10157 )
10158 )
10159 {
10160     ushort              cfg_lsw;
10161     uchar               chip_irq;
10162 
10163     if ((bus_type & ASC_IS_EISA) != 0) {
10164         cfg_lsw = AscGetEisaChipCfg(iop_base);
10165         chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10);
10166         if ((chip_irq == 13) || (chip_irq > 15)) {
10167             return (0);
10168         }
10169         return (chip_irq);
10170     }
10171     if ((bus_type & ASC_IS_VL) != 0) {
10172         cfg_lsw = AscGetChipCfgLsw(iop_base);
10173         chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07));
10174         if ((chip_irq == 0) ||
10175             (chip_irq == 4) ||
10176             (chip_irq == 7)) {
10177             return (0);
10178         }
10179         return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1)));
10180     }
10181     cfg_lsw = AscGetChipCfgLsw(iop_base);
10182     chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03));
10183     if (chip_irq == 3)
10184         chip_irq += (uchar) 2;
10185     return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
10186 }
10187 
ASC_INITFUNC(STATIC uchar,AscSetChipIRQ (PortAddr iop_base,uchar irq_no,ushort bus_type))10188 ASC_INITFUNC(
10189 STATIC uchar,
10190 AscSetChipIRQ(
10191                  PortAddr iop_base,
10192                  uchar irq_no,
10193                  ushort bus_type
10194 )
10195 )
10196 {
10197     ushort              cfg_lsw;
10198 
10199     if ((bus_type & ASC_IS_VL) != 0) {
10200         if (irq_no != 0) {
10201             if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) {
10202                 irq_no = 0;
10203             } else {
10204                 irq_no -= (uchar) ((ASC_MIN_IRQ_NO - 1));
10205             }
10206         }
10207         cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE3);
10208         cfg_lsw |= (ushort) 0x0010;
10209         AscSetChipCfgLsw(iop_base, cfg_lsw);
10210         AscToggleIRQAct(iop_base);
10211         cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE0);
10212         cfg_lsw |= (ushort) ((irq_no & 0x07) << 2);
10213         AscSetChipCfgLsw(iop_base, cfg_lsw);
10214         AscToggleIRQAct(iop_base);
10215         return (AscGetChipIRQ(iop_base, bus_type));
10216     }
10217     if ((bus_type & (ASC_IS_ISA)) != 0) {
10218         if (irq_no == 15)
10219             irq_no -= (uchar) 2;
10220         irq_no -= (uchar) ASC_MIN_IRQ_NO;
10221         cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFF3);
10222         cfg_lsw |= (ushort) ((irq_no & 0x03) << 2);
10223         AscSetChipCfgLsw(iop_base, cfg_lsw);
10224         return (AscGetChipIRQ(iop_base, bus_type));
10225     }
10226     return (0);
10227 }
10228 
10229 #ifdef CONFIG_ISA
ASC_INITFUNC(STATIC void,AscEnableIsaDma (uchar dma_channel))10230 ASC_INITFUNC(
10231 STATIC void,
10232 AscEnableIsaDma(
10233                    uchar dma_channel
10234 )
10235 )
10236 {
10237     if (dma_channel < 4) {
10238         outp(0x000B, (ushort) (0xC0 | dma_channel));
10239         outp(0x000A, dma_channel);
10240     } else if (dma_channel < 8) {
10241         outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4)));
10242         outp(0x00D4, (ushort) (dma_channel - 4));
10243     }
10244     return;
10245 }
10246 #endif /* CONFIG_ISA */
10247 
10248 STATIC int
AscIsrChipHalted(ASC_DVC_VAR * asc_dvc)10249 AscIsrChipHalted(
10250                     ASC_DVC_VAR *asc_dvc
10251 )
10252 {
10253     EXT_MSG             ext_msg;
10254     EXT_MSG             out_msg;
10255     ushort              halt_q_addr;
10256     int                 sdtr_accept;
10257     ushort              int_halt_code;
10258     ASC_SCSI_BIT_ID_TYPE scsi_busy;
10259     ASC_SCSI_BIT_ID_TYPE target_id;
10260     PortAddr            iop_base;
10261     uchar               tag_code;
10262     uchar               q_status;
10263     uchar               halt_qp;
10264     uchar               sdtr_data;
10265     uchar               target_ix;
10266     uchar               q_cntl, tid_no;
10267     uchar               cur_dvc_qng;
10268     uchar               asyn_sdtr;
10269     uchar               scsi_status;
10270     asc_board_t         *boardp;
10271 
10272     ASC_ASSERT(asc_dvc->drv_ptr != NULL);
10273     boardp = asc_dvc->drv_ptr;
10274 
10275     iop_base = asc_dvc->iop_base;
10276     int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
10277 
10278     halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
10279     halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
10280     target_ix = AscReadLramByte(iop_base,
10281                    (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX));
10282     q_cntl = AscReadLramByte(iop_base,
10283                         (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL));
10284     tid_no = ASC_TIX_TO_TID(target_ix);
10285     target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no);
10286     if (asc_dvc->pci_fix_asyn_xfer & target_id) {
10287         asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
10288     } else {
10289         asyn_sdtr = 0;
10290     }
10291     if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
10292         if (asc_dvc->pci_fix_asyn_xfer & target_id) {
10293             AscSetChipSDTR(iop_base, 0, tid_no);
10294             boardp->sdtr_data[tid_no] = 0;
10295         }
10296         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10297         return (0);
10298     } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
10299         if (asc_dvc->pci_fix_asyn_xfer & target_id) {
10300             AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10301             boardp->sdtr_data[tid_no] = asyn_sdtr;
10302         }
10303         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10304         return (0);
10305     } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
10306 
10307         AscMemWordCopyPtrFromLram(iop_base,
10308                                ASCV_MSGIN_BEG,
10309                                (uchar *) &ext_msg,
10310                                sizeof(EXT_MSG) >> 1);
10311 
10312         if (ext_msg.msg_type == MS_EXTEND &&
10313             ext_msg.msg_req == MS_SDTR_CODE &&
10314             ext_msg.msg_len == MS_SDTR_LEN) {
10315             sdtr_accept = TRUE;
10316             if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
10317 
10318                 sdtr_accept = FALSE;
10319                 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
10320             }
10321             if ((ext_msg.xfer_period <
10322                  asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index]) ||
10323                 (ext_msg.xfer_period >
10324                  asc_dvc->sdtr_period_tbl[asc_dvc->max_sdtr_index])) {
10325                 sdtr_accept = FALSE;
10326                 ext_msg.xfer_period =
10327                     asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index];
10328             }
10329             if (sdtr_accept) {
10330                 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
10331                                            ext_msg.req_ack_offset);
10332                 if ((sdtr_data == 0xFF)) {
10333 
10334                     q_cntl |= QC_MSG_OUT;
10335                     asc_dvc->init_sdtr &= ~target_id;
10336                     asc_dvc->sdtr_done &= ~target_id;
10337                     AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10338                     boardp->sdtr_data[tid_no] = asyn_sdtr;
10339                 }
10340             }
10341             if (ext_msg.req_ack_offset == 0) {
10342 
10343                 q_cntl &= ~QC_MSG_OUT;
10344                 asc_dvc->init_sdtr &= ~target_id;
10345                 asc_dvc->sdtr_done &= ~target_id;
10346                 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10347             } else {
10348                 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
10349 
10350                     q_cntl &= ~QC_MSG_OUT;
10351                     asc_dvc->sdtr_done |= target_id;
10352                     asc_dvc->init_sdtr |= target_id;
10353                     asc_dvc->pci_fix_asyn_xfer &= ~target_id;
10354                     sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
10355                                                ext_msg.req_ack_offset);
10356                     AscSetChipSDTR(iop_base, sdtr_data, tid_no);
10357                     boardp->sdtr_data[tid_no] = sdtr_data;
10358                 } else {
10359 
10360                     q_cntl |= QC_MSG_OUT;
10361                     AscMsgOutSDTR(asc_dvc,
10362                                   ext_msg.xfer_period,
10363                                   ext_msg.req_ack_offset);
10364                     asc_dvc->pci_fix_asyn_xfer &= ~target_id;
10365                     sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
10366                                                ext_msg.req_ack_offset);
10367                     AscSetChipSDTR(iop_base, sdtr_data, tid_no);
10368                     boardp->sdtr_data[tid_no] = sdtr_data;
10369                     asc_dvc->sdtr_done |= target_id;
10370                     asc_dvc->init_sdtr |= target_id;
10371                 }
10372             }
10373 
10374             AscWriteLramByte(iop_base,
10375                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10376                              q_cntl);
10377             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10378             return (0);
10379         } else if (ext_msg.msg_type == MS_EXTEND &&
10380                    ext_msg.msg_req == MS_WDTR_CODE &&
10381                    ext_msg.msg_len == MS_WDTR_LEN) {
10382 
10383             ext_msg.wdtr_width = 0;
10384             AscMemWordCopyPtrToLram(iop_base,
10385                                  ASCV_MSGOUT_BEG,
10386                                  (uchar *) &ext_msg,
10387                                  sizeof(EXT_MSG) >> 1);
10388             q_cntl |= QC_MSG_OUT;
10389             AscWriteLramByte(iop_base,
10390                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10391                              q_cntl);
10392             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10393             return (0);
10394         } else {
10395 
10396             ext_msg.msg_type = M1_MSG_REJECT;
10397             AscMemWordCopyPtrToLram(iop_base,
10398                                  ASCV_MSGOUT_BEG,
10399                                  (uchar *) &ext_msg,
10400                                  sizeof(EXT_MSG) >> 1);
10401             q_cntl |= QC_MSG_OUT;
10402             AscWriteLramByte(iop_base,
10403                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10404                              q_cntl);
10405             AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10406             return (0);
10407         }
10408     } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
10409 
10410         q_cntl |= QC_REQ_SENSE;
10411 
10412         if ((asc_dvc->init_sdtr & target_id) != 0) {
10413 
10414             asc_dvc->sdtr_done &= ~target_id;
10415 
10416             sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10417             q_cntl |= QC_MSG_OUT;
10418             AscMsgOutSDTR(asc_dvc,
10419                           asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
10420                            (uchar) (asc_dvc->max_sdtr_index - 1)],
10421                           (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
10422         }
10423 
10424         AscWriteLramByte(iop_base,
10425                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10426                          q_cntl);
10427 
10428         tag_code = AscReadLramByte(iop_base,
10429                     (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
10430         tag_code &= 0xDC;
10431         if (
10432                (asc_dvc->pci_fix_asyn_xfer & target_id)
10433                && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
10434 ) {
10435 
10436             tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
10437                          | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
10438 
10439         }
10440         AscWriteLramByte(iop_base,
10441                      (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE),
10442                          tag_code);
10443 
10444         q_status = AscReadLramByte(iop_base,
10445                       (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS));
10446         q_status |= (QS_READY | QS_BUSY);
10447         AscWriteLramByte(iop_base,
10448                        (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10449                          q_status);
10450 
10451         scsi_busy = AscReadLramByte(iop_base,
10452                                     (ushort) ASCV_SCSIBUSY_B);
10453         scsi_busy &= ~target_id;
10454         AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10455 
10456         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10457         return (0);
10458     } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
10459 
10460         AscMemWordCopyPtrFromLram(iop_base,
10461                                ASCV_MSGOUT_BEG,
10462                                (uchar *) &out_msg,
10463                                sizeof(EXT_MSG) >> 1);
10464 
10465         if ((out_msg.msg_type == MS_EXTEND) &&
10466             (out_msg.msg_len == MS_SDTR_LEN) &&
10467             (out_msg.msg_req == MS_SDTR_CODE)) {
10468 
10469             asc_dvc->init_sdtr &= ~target_id;
10470             asc_dvc->sdtr_done &= ~target_id;
10471             AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10472             boardp->sdtr_data[tid_no] = asyn_sdtr;
10473         }
10474         q_cntl &= ~QC_MSG_OUT;
10475         AscWriteLramByte(iop_base,
10476                          (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10477                          q_cntl);
10478         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10479         return (0);
10480     } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
10481 
10482         scsi_status = AscReadLramByte(iop_base,
10483           (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS));
10484         cur_dvc_qng = AscReadLramByte(iop_base,
10485                      (ushort) ((ushort) ASC_QADR_BEG + (ushort) target_ix));
10486         if ((cur_dvc_qng > 0) &&
10487             (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
10488 
10489             scsi_busy = AscReadLramByte(iop_base,
10490                                         (ushort) ASCV_SCSIBUSY_B);
10491             scsi_busy |= target_id;
10492             AscWriteLramByte(iop_base,
10493                              (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10494             asc_dvc->queue_full_or_busy |= target_id;
10495 
10496             if (scsi_status == SS_QUEUE_FULL) {
10497                 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
10498                     cur_dvc_qng -= 1;
10499                     asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
10500 
10501                     AscWriteLramByte(iop_base,
10502                           (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG +
10503                            (ushort) tid_no),
10504                           cur_dvc_qng);
10505 
10506                     /*
10507                      * Set the device queue depth to the number of
10508                      * active requests when the QUEUE FULL condition
10509                      * was encountered.
10510                      */
10511                     boardp->queue_full |= target_id;
10512                     boardp->queue_full_cnt[tid_no] = cur_dvc_qng;
10513                 }
10514             }
10515         }
10516         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10517         return (0);
10518     }
10519 #if CC_VERY_LONG_SG_LIST
10520     else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC)
10521     {
10522         uchar              q_no;
10523         ushort             q_addr;
10524         uchar              sg_wk_q_no;
10525         uchar              first_sg_wk_q_no;
10526         ASC_SCSI_Q         *scsiq; /* Ptr to driver request. */
10527         ASC_SG_HEAD        *sg_head; /* Ptr to driver SG request. */
10528         ASC_SG_LIST_Q      scsi_sg_q; /* Structure written to queue. */
10529         ushort             sg_list_dwords;
10530         ushort             sg_entry_cnt;
10531         uchar              next_qp;
10532         int                i;
10533 
10534         q_no = AscReadLramByte(iop_base, (ushort) ASCV_REQ_SG_LIST_QP);
10535         if (q_no == ASC_QLINK_END)
10536         {
10537             return(0);
10538         }
10539 
10540         q_addr = ASC_QNO_TO_QADDR(q_no);
10541 
10542         /*
10543          * Convert the request's SRB pointer to a host ASC_SCSI_REQ
10544          * structure pointer using a macro provided by the driver.
10545          * The ASC_SCSI_REQ pointer provides a pointer to the
10546          * host ASC_SG_HEAD structure.
10547          */
10548         /* Read request's SRB pointer. */
10549         scsiq = (ASC_SCSI_Q *)
10550            ASC_SRB2SCSIQ(
10551                ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
10552                (ushort) (q_addr + ASC_SCSIQ_D_SRBPTR))));
10553 
10554         /*
10555          * Get request's first and working SG queue.
10556          */
10557         sg_wk_q_no = AscReadLramByte(iop_base,
10558             (ushort) (q_addr + ASC_SCSIQ_B_SG_WK_QP));
10559 
10560         first_sg_wk_q_no = AscReadLramByte(iop_base,
10561             (ushort) (q_addr + ASC_SCSIQ_B_FIRST_SG_WK_QP));
10562 
10563         /*
10564          * Reset request's working SG queue back to the
10565          * first SG queue.
10566          */
10567         AscWriteLramByte(iop_base,
10568             (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SG_WK_QP),
10569             first_sg_wk_q_no);
10570 
10571         sg_head = scsiq->sg_head;
10572 
10573         /*
10574          * Set sg_entry_cnt to the number of SG elements
10575          * that will be completed on this interrupt.
10576          *
10577          * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
10578          * SG elements. The data_cnt and data_addr fields which
10579          * add 1 to the SG element capacity are not used when
10580          * restarting SG handling after a halt.
10581          */
10582         if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1))
10583         {
10584              sg_entry_cnt = ASC_MAX_SG_LIST - 1;
10585 
10586              /*
10587               * Keep track of remaining number of SG elements that will
10588               * need to be handled on the next interrupt.
10589               */
10590              scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
10591         } else
10592         {
10593              sg_entry_cnt = scsiq->remain_sg_entry_cnt;
10594              scsiq->remain_sg_entry_cnt = 0;
10595         }
10596 
10597         /*
10598          * Copy SG elements into the list of allocated SG queues.
10599          *
10600          * Last index completed is saved in scsiq->next_sg_index.
10601          */
10602         next_qp = first_sg_wk_q_no;
10603         q_addr = ASC_QNO_TO_QADDR(next_qp);
10604         scsi_sg_q.sg_head_qp = q_no;
10605         scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
10606         for( i = 0; i < sg_head->queue_cnt; i++)
10607         {
10608              scsi_sg_q.seq_no = i + 1;
10609              if (sg_entry_cnt > ASC_SG_LIST_PER_Q)
10610              {
10611                  sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
10612                  sg_entry_cnt -= ASC_SG_LIST_PER_Q;
10613                  /*
10614                   * After very first SG queue RISC FW uses next
10615                   * SG queue first element then checks sg_list_cnt
10616                   * against zero and then decrements, so set
10617                   * sg_list_cnt 1 less than number of SG elements
10618                   * in each SG queue.
10619                   */
10620                  scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
10621                  scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
10622              } else {
10623                  /*
10624                   * This is the last SG queue in the list of
10625                   * allocated SG queues. If there are more
10626                   * SG elements than will fit in the allocated
10627                   * queues, then set the QCSG_SG_XFER_MORE flag.
10628                   */
10629                  if (scsiq->remain_sg_entry_cnt != 0)
10630                  {
10631                      scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
10632                  } else
10633                  {
10634                      scsi_sg_q.cntl |= QCSG_SG_XFER_END;
10635                  }
10636                  /* equals sg_entry_cnt * 2 */
10637                  sg_list_dwords = sg_entry_cnt << 1;
10638                  scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
10639                  scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
10640                  sg_entry_cnt = 0;
10641              }
10642 
10643              scsi_sg_q.q_no = next_qp;
10644              AscMemWordCopyPtrToLram(iop_base,
10645                           q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
10646                           (uchar *) &scsi_sg_q,
10647                           sizeof(ASC_SG_LIST_Q) >> 1);
10648 
10649              AscMemDWordCopyPtrToLram(iop_base,
10650                           q_addr + ASC_SGQ_LIST_BEG,
10651                           (uchar *) &sg_head->sg_list[scsiq->next_sg_index],
10652                           sg_list_dwords);
10653 
10654              scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
10655 
10656              /*
10657               * If the just completed SG queue contained the
10658               * last SG element, then no more SG queues need
10659               * to be written.
10660               */
10661              if (scsi_sg_q.cntl & QCSG_SG_XFER_END)
10662              {
10663                  break;
10664              }
10665 
10666              next_qp = AscReadLramByte( iop_base,
10667                           ( ushort )( q_addr+ASC_SCSIQ_B_FWD ) );
10668              q_addr = ASC_QNO_TO_QADDR( next_qp );
10669         }
10670 
10671         /*
10672          * Clear the halt condition so the RISC will be restarted
10673          * after the return.
10674          */
10675         AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10676         return(0);
10677     }
10678 #endif /* CC_VERY_LONG_SG_LIST */
10679     return (0);
10680 }
10681 
10682 STATIC uchar
_AscCopyLramScsiDoneQ(PortAddr iop_base,ushort q_addr,ASC_QDONE_INFO * scsiq,ASC_DCNT max_dma_count)10683 _AscCopyLramScsiDoneQ(
10684                          PortAddr iop_base,
10685                          ushort q_addr,
10686                          ASC_QDONE_INFO * scsiq,
10687                          ASC_DCNT max_dma_count
10688 )
10689 {
10690     ushort              _val;
10691     uchar               sg_queue_cnt;
10692 
10693     DvcGetQinfo(iop_base,
10694                 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
10695                 (uchar *) scsiq,
10696                 (sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2);
10697 
10698     _val = AscReadLramWord(iop_base,
10699                            (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS));
10700     scsiq->q_status = (uchar) _val;
10701     scsiq->q_no = (uchar) (_val >> 8);
10702     _val = AscReadLramWord(iop_base,
10703                            (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL));
10704     scsiq->cntl = (uchar) _val;
10705     sg_queue_cnt = (uchar) (_val >> 8);
10706     _val = AscReadLramWord(iop_base,
10707                         (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN));
10708     scsiq->sense_len = (uchar) _val;
10709     scsiq->extra_bytes = (uchar) (_val >> 8);
10710 
10711     /*
10712      * Read high word of remain bytes from alternate location.
10713      */
10714     scsiq->remain_bytes = (((ADV_DCNT) AscReadLramWord( iop_base,
10715                       (ushort) (q_addr+ (ushort) ASC_SCSIQ_W_ALT_DC1))) << 16);
10716     /*
10717      * Read low word of remain bytes from original location.
10718      */
10719     scsiq->remain_bytes += AscReadLramWord(iop_base,
10720         (ushort) (q_addr+ (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT));
10721 
10722     scsiq->remain_bytes &= max_dma_count;
10723     return (sg_queue_cnt);
10724 }
10725 
10726 STATIC int
AscIsrQDone(ASC_DVC_VAR * asc_dvc)10727 AscIsrQDone(
10728                ASC_DVC_VAR *asc_dvc
10729 )
10730 {
10731     uchar               next_qp;
10732     uchar               n_q_used;
10733     uchar               sg_list_qp;
10734     uchar               sg_queue_cnt;
10735     uchar               q_cnt;
10736     uchar               done_q_tail;
10737     uchar               tid_no;
10738     ASC_SCSI_BIT_ID_TYPE scsi_busy;
10739     ASC_SCSI_BIT_ID_TYPE target_id;
10740     PortAddr            iop_base;
10741     ushort              q_addr;
10742     ushort              sg_q_addr;
10743     uchar               cur_target_qng;
10744     ASC_QDONE_INFO      scsiq_buf;
10745     ASC_QDONE_INFO *scsiq;
10746     int                 false_overrun;
10747     ASC_ISR_CALLBACK    asc_isr_callback;
10748 
10749     iop_base = asc_dvc->iop_base;
10750     asc_isr_callback = asc_dvc->isr_callback;
10751     n_q_used = 1;
10752     scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
10753     done_q_tail = (uchar) AscGetVarDoneQTail(iop_base);
10754     q_addr = ASC_QNO_TO_QADDR(done_q_tail);
10755     next_qp = AscReadLramByte(iop_base,
10756                               (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD));
10757     if (next_qp != ASC_QLINK_END) {
10758         AscPutVarDoneQTail(iop_base, next_qp);
10759         q_addr = ASC_QNO_TO_QADDR(next_qp);
10760         sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
10761             asc_dvc->max_dma_count);
10762         AscWriteLramByte(iop_base,
10763                          (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10764              (uchar) (scsiq->q_status & (uchar) ~ (QS_READY | QS_ABORTED)));
10765         tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
10766         target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
10767         if ((scsiq->cntl & QC_SG_HEAD) != 0) {
10768             sg_q_addr = q_addr;
10769             sg_list_qp = next_qp;
10770             for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
10771                 sg_list_qp = AscReadLramByte(iop_base,
10772                            (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_FWD));
10773                 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
10774                 if (sg_list_qp == ASC_QLINK_END) {
10775                     AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_Q_LINKS);
10776                     scsiq->d3.done_stat = QD_WITH_ERROR;
10777                     scsiq->d3.host_stat = QHSTA_D_QDONE_SG_LIST_CORRUPTED;
10778                     goto FATAL_ERR_QDONE;
10779                 }
10780                 AscWriteLramByte(iop_base,
10781                          (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10782                                  QS_FREE);
10783             }
10784             n_q_used = sg_queue_cnt + 1;
10785             AscPutVarDoneQTail(iop_base, sg_list_qp);
10786         }
10787         if (asc_dvc->queue_full_or_busy & target_id) {
10788             cur_target_qng = AscReadLramByte(iop_base,
10789             (ushort) ((ushort) ASC_QADR_BEG + (ushort) scsiq->d2.target_ix));
10790             if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
10791                 scsi_busy = AscReadLramByte(iop_base,
10792                                             (ushort) ASCV_SCSIBUSY_B);
10793                 scsi_busy &= ~target_id;
10794                 AscWriteLramByte(iop_base,
10795                                  (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10796                 asc_dvc->queue_full_or_busy &= ~target_id;
10797             }
10798         }
10799         if (asc_dvc->cur_total_qng >= n_q_used) {
10800             asc_dvc->cur_total_qng -= n_q_used;
10801             if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
10802                 asc_dvc->cur_dvc_qng[tid_no]--;
10803             }
10804         } else {
10805             AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
10806             scsiq->d3.done_stat = QD_WITH_ERROR;
10807             goto FATAL_ERR_QDONE;
10808         }
10809         if ((scsiq->d2.srb_ptr == 0UL) ||
10810             ((scsiq->q_status & QS_ABORTED) != 0)) {
10811             return (0x11);
10812         } else if (scsiq->q_status == QS_DONE) {
10813             false_overrun = FALSE;
10814             if (scsiq->extra_bytes != 0) {
10815                 scsiq->remain_bytes += (ADV_DCNT) scsiq->extra_bytes;
10816             }
10817             if (scsiq->d3.done_stat == QD_WITH_ERROR) {
10818                 if (scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN) {
10819                     if ((scsiq->cntl & (QC_DATA_IN | QC_DATA_OUT)) == 0) {
10820                         scsiq->d3.done_stat = QD_NO_ERROR;
10821                         scsiq->d3.host_stat = QHSTA_NO_ERROR;
10822                     } else if (false_overrun) {
10823                         scsiq->d3.done_stat = QD_NO_ERROR;
10824                         scsiq->d3.host_stat = QHSTA_NO_ERROR;
10825                     }
10826                 } else if (scsiq->d3.host_stat ==
10827                            QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
10828                     AscStopChip(iop_base);
10829                     AscSetChipControl(iop_base,
10830                         (uchar) (CC_SCSI_RESET | CC_HALT));
10831                     DvcDelayNanoSecond(asc_dvc, 60000);
10832                     AscSetChipControl(iop_base, CC_HALT);
10833                     AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10834                     AscSetChipStatus(iop_base, 0);
10835                     AscSetChipControl(iop_base, 0);
10836                 }
10837             }
10838             if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
10839                 (*asc_isr_callback) (asc_dvc, scsiq);
10840             } else {
10841                 if ((AscReadLramByte(iop_base,
10842                           (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) ==
10843                      SCSICMD_StartStopUnit)) {
10844                     asc_dvc->unit_not_ready &= ~target_id;
10845                     if (scsiq->d3.done_stat != QD_NO_ERROR) {
10846                         asc_dvc->start_motor &= ~target_id;
10847                     }
10848                 }
10849             }
10850             return (1);
10851         } else {
10852             AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
10853           FATAL_ERR_QDONE:
10854             if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
10855                 (*asc_isr_callback) (asc_dvc, scsiq);
10856             }
10857             return (0x80);
10858         }
10859     }
10860     return (0);
10861 }
10862 
10863 STATIC int
AscISR(ASC_DVC_VAR * asc_dvc)10864 AscISR(
10865           ASC_DVC_VAR *asc_dvc
10866 )
10867 {
10868     ASC_CS_TYPE         chipstat;
10869     PortAddr            iop_base;
10870     ushort              saved_ram_addr;
10871     uchar               ctrl_reg;
10872     uchar               saved_ctrl_reg;
10873     int                 int_pending;
10874     int                 status;
10875     uchar               host_flag;
10876 
10877     iop_base = asc_dvc->iop_base;
10878     int_pending = FALSE;
10879 
10880     if (AscIsIntPending(iop_base) == 0)
10881     {
10882         return int_pending;
10883     }
10884 
10885     if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
10886         || (asc_dvc->isr_callback == 0)
10887 ) {
10888         return (ERR);
10889     }
10890     if (asc_dvc->in_critical_cnt != 0) {
10891         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
10892         return (ERR);
10893     }
10894     if (asc_dvc->is_in_int) {
10895         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
10896         return (ERR);
10897     }
10898     asc_dvc->is_in_int = TRUE;
10899     ctrl_reg = AscGetChipControl(iop_base);
10900     saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
10901                                    CC_SINGLE_STEP | CC_DIAG | CC_TEST));
10902     chipstat = AscGetChipStatus(iop_base);
10903     if (chipstat & CSW_SCSI_RESET_LATCH) {
10904         if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
10905             int i = 10;
10906             int_pending = TRUE;
10907             asc_dvc->sdtr_done = 0;
10908             saved_ctrl_reg &= (uchar) (~CC_HALT);
10909             while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) &&
10910                    (i-- > 0))
10911             {
10912                   DvcSleepMilliSecond(100);
10913             }
10914             AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
10915             AscSetChipControl(iop_base, CC_HALT);
10916             AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10917             AscSetChipStatus(iop_base, 0);
10918             chipstat = AscGetChipStatus(iop_base);
10919         }
10920     }
10921     saved_ram_addr = AscGetChipLramAddr(iop_base);
10922     host_flag = AscReadLramByte(iop_base,
10923         ASCV_HOST_FLAG_B) & (uchar) (~ASC_HOST_FLAG_IN_ISR);
10924     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10925                      (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR));
10926     if ((chipstat & CSW_INT_PENDING)
10927         || (int_pending)
10928 ) {
10929         AscAckInterrupt(iop_base);
10930         int_pending = TRUE;
10931         if ((chipstat & CSW_HALTED) &&
10932             (ctrl_reg & CC_SINGLE_STEP)) {
10933             if (AscIsrChipHalted(asc_dvc) == ERR) {
10934                 goto ISR_REPORT_QDONE_FATAL_ERROR;
10935             } else {
10936                 saved_ctrl_reg &= (uchar) (~CC_HALT);
10937             }
10938         } else {
10939           ISR_REPORT_QDONE_FATAL_ERROR:
10940             if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
10941                 while (((status = AscIsrQDone(asc_dvc)) & 0x01) != 0) {
10942                 }
10943             } else {
10944                 do {
10945                     if ((status = AscIsrQDone(asc_dvc)) == 1) {
10946                         break;
10947                     }
10948                 } while (status == 0x11);
10949             }
10950             if ((status & 0x80) != 0)
10951                 int_pending = ERR;
10952         }
10953     }
10954     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10955     AscSetChipLramAddr(iop_base, saved_ram_addr);
10956     AscSetChipControl(iop_base, saved_ctrl_reg);
10957     asc_dvc->is_in_int = FALSE;
10958     return (int_pending);
10959 }
10960 
10961 /* Microcode buffer is kept after initialization for error recovery. */
10962 STATIC uchar _asc_mcode_buf[] =
10963 {
10964   0x01,  0x03,  0x01,  0x19,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
10965   0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x0F,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
10966   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
10967   0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
10968   0x00,  0x00,  0x00,  0x00,  0xC3,  0x12,  0x0D,  0x05,  0x01,  0x00,  0x00,  0x00,  0x00,  0xFF,  0x00,  0x00,
10969   0x00,  0x00,  0x00,  0x00,  0xFF,  0x80,  0xFF,  0xFF,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,
10970   0x00,  0x00,  0x00,  0x23,  0x00,  0x00,  0x00,  0x00,  0x00,  0x07,  0x00,  0xFF,  0x00,  0x00,  0x00,  0x00,
10971   0xFF,  0xFF,  0xFF,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0xE4,  0x88,  0x00,  0x00,  0x00,  0x00,
10972   0x80,  0x73,  0x48,  0x04,  0x36,  0x00,  0x00,  0xA2,  0xC2,  0x00,  0x80,  0x73,  0x03,  0x23,  0x36,  0x40,
10973   0xB6,  0x00,  0x36,  0x00,  0x05,  0xD6,  0x0C,  0xD2,  0x12,  0xDA,  0x00,  0xA2,  0xC2,  0x00,  0x92,  0x80,
10974   0x1E,  0x98,  0x50,  0x00,  0xF5,  0x00,  0x48,  0x98,  0xDF,  0x23,  0x36,  0x60,  0xB6,  0x00,  0x92,  0x80,
10975   0x4F,  0x00,  0xF5,  0x00,  0x48,  0x98,  0xEF,  0x23,  0x36,  0x60,  0xB6,  0x00,  0x92,  0x80,  0x80,  0x62,
10976   0x92,  0x80,  0x00,  0x46,  0x15,  0xEE,  0x13,  0xEA,  0x02,  0x01,  0x09,  0xD8,  0xCD,  0x04,  0x4D,  0x00,
10977   0x00,  0xA3,  0xD6,  0x00,  0xA6,  0x97,  0x7F,  0x23,  0x04,  0x61,  0x84,  0x01,  0xE6,  0x84,  0xD2,  0xC1,
10978   0x80,  0x73,  0xCD,  0x04,  0x4D,  0x00,  0x00,  0xA3,  0xDA,  0x01,  0xA6,  0x97,  0xC6,  0x81,  0xC2,  0x88,
10979   0x80,  0x73,  0x80,  0x77,  0x00,  0x01,  0x01,  0xA1,  0xFE,  0x00,  0x4F,  0x00,  0x84,  0x97,  0x07,  0xA6,
10980   0x08,  0x01,  0x00,  0x33,  0x03,  0x00,  0xC2,  0x88,  0x03,  0x03,  0x01,  0xDE,  0xC2,  0x88,  0xCE,  0x00,
10981   0x69,  0x60,  0xCE,  0x00,  0x02,  0x03,  0x4A,  0x60,  0x00,  0xA2,  0x78,  0x01,  0x80,  0x63,  0x07,  0xA6,
10982   0x24,  0x01,  0x78,  0x81,  0x03,  0x03,  0x80,  0x63,  0xE2,  0x00,  0x07,  0xA6,  0x34,  0x01,  0x00,  0x33,
10983   0x04,  0x00,  0xC2,  0x88,  0x03,  0x07,  0x02,  0x01,  0x04,  0xCA,  0x0D,  0x23,  0x68,  0x98,  0x4D,  0x04,
10984   0x04,  0x85,  0x05,  0xD8,  0x0D,  0x23,  0x68,  0x98,  0xCD,  0x04,  0x15,  0x23,  0xF8,  0x88,  0xFB,  0x23,
10985   0x02,  0x61,  0x82,  0x01,  0x80,  0x63,  0x02,  0x03,  0x06,  0xA3,  0x62,  0x01,  0x00,  0x33,  0x0A,  0x00,
10986   0xC2,  0x88,  0x4E,  0x00,  0x07,  0xA3,  0x6E,  0x01,  0x00,  0x33,  0x0B,  0x00,  0xC2,  0x88,  0xCD,  0x04,
10987   0x36,  0x2D,  0x00,  0x33,  0x1A,  0x00,  0xC2,  0x88,  0x50,  0x04,  0x88,  0x81,  0x06,  0xAB,  0x82,  0x01,
10988   0x88,  0x81,  0x4E,  0x00,  0x07,  0xA3,  0x92,  0x01,  0x50,  0x00,  0x00,  0xA3,  0x3C,  0x01,  0x00,  0x05,
10989   0x7C,  0x81,  0x46,  0x97,  0x02,  0x01,  0x05,  0xC6,  0x04,  0x23,  0xA0,  0x01,  0x15,  0x23,  0xA1,  0x01,
10990   0xBE,  0x81,  0xFD,  0x23,  0x02,  0x61,  0x82,  0x01,  0x0A,  0xDA,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,
10991   0xB4,  0x01,  0x80,  0x63,  0xCD,  0x04,  0x36,  0x2D,  0x00,  0x33,  0x1B,  0x00,  0xC2,  0x88,  0x06,  0x23,
10992   0x68,  0x98,  0xCD,  0x04,  0xE6,  0x84,  0x06,  0x01,  0x00,  0xA2,  0xD4,  0x01,  0x57,  0x60,  0x00,  0xA0,
10993   0xDA,  0x01,  0xE6,  0x84,  0x80,  0x23,  0xA0,  0x01,  0xE6,  0x84,  0x80,  0x73,  0x4B,  0x00,  0x06,  0x61,
10994   0x00,  0xA2,  0x00,  0x02,  0x04,  0x01,  0x0C,  0xDE,  0x02,  0x01,  0x03,  0xCC,  0x4F,  0x00,  0x84,  0x97,
10995   0xFC,  0x81,  0x08,  0x23,  0x02,  0x41,  0x82,  0x01,  0x4F,  0x00,  0x62,  0x97,  0x48,  0x04,  0x84,  0x80,
10996   0xF0,  0x97,  0x00,  0x46,  0x56,  0x00,  0x03,  0xC0,  0x01,  0x23,  0xE8,  0x00,  0x81,  0x73,  0x06,  0x29,
10997   0x03,  0x42,  0x06,  0xE2,  0x03,  0xEE,  0x6B,  0xEB,  0x11,  0x23,  0xF8,  0x88,  0x04,  0x98,  0xF0,  0x80,
10998   0x80,  0x73,  0x80,  0x77,  0x07,  0xA4,  0x2A,  0x02,  0x7C,  0x95,  0x06,  0xA6,  0x34,  0x02,  0x03,  0xA6,
10999   0x4C,  0x04,  0x46,  0x82,  0x04,  0x01,  0x03,  0xD8,  0xB4,  0x98,  0x6A,  0x96,  0x46,  0x82,  0xFE,  0x95,
11000   0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0xB6,  0x2D,  0x02,  0xA6,  0x6C,  0x02,  0x07,  0xA6,  0x5A,  0x02,
11001   0x06,  0xA6,  0x5E,  0x02,  0x03,  0xA6,  0x62,  0x02,  0xC2,  0x88,  0x7C,  0x95,  0x48,  0x82,  0x60,  0x96,
11002   0x48,  0x82,  0x04,  0x23,  0xA0,  0x01,  0x14,  0x23,  0xA1,  0x01,  0x3C,  0x84,  0x04,  0x01,  0x0C,  0xDC,
11003   0xE0,  0x23,  0x25,  0x61,  0xEF,  0x00,  0x14,  0x01,  0x4F,  0x04,  0xA8,  0x01,  0x6F,  0x00,  0xA5,  0x01,
11004   0x03,  0x23,  0xA4,  0x01,  0x06,  0x23,  0x9C,  0x01,  0x24,  0x2B,  0x1C,  0x01,  0x02,  0xA6,  0xAA,  0x02,
11005   0x07,  0xA6,  0x5A,  0x02,  0x06,  0xA6,  0x5E,  0x02,  0x03,  0xA6,  0x20,  0x04,  0x01,  0xA6,  0xB4,  0x02,
11006   0x00,  0xA6,  0xB4,  0x02,  0x00,  0x33,  0x12,  0x00,  0xC2,  0x88,  0x00,  0x0E,  0x80,  0x63,  0x00,  0x43,
11007   0x00,  0xA0,  0x8C,  0x02,  0x4D,  0x04,  0x04,  0x01,  0x0B,  0xDC,  0xE7,  0x23,  0x04,  0x61,  0x84,  0x01,
11008   0x10,  0x31,  0x12,  0x35,  0x14,  0x01,  0xEC,  0x00,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,  0xEA,  0x82,
11009   0x18,  0x23,  0x04,  0x61,  0x18,  0xA0,  0xE2,  0x02,  0x04,  0x01,  0xA2,  0xC8,  0x00,  0x33,  0x1F,  0x00,
11010   0xC2,  0x88,  0x08,  0x31,  0x0A,  0x35,  0x0C,  0x39,  0x0E,  0x3D,  0x7E,  0x98,  0xB6,  0x2D,  0x01,  0xA6,
11011   0x14,  0x03,  0x00,  0xA6,  0x14,  0x03,  0x07,  0xA6,  0x0C,  0x03,  0x06,  0xA6,  0x10,  0x03,  0x03,  0xA6,
11012   0x20,  0x04,  0x02,  0xA6,  0x6C,  0x02,  0x00,  0x33,  0x33,  0x00,  0xC2,  0x88,  0x7C,  0x95,  0xEE,  0x82,
11013   0x60,  0x96,  0xEE,  0x82,  0x82,  0x98,  0x80,  0x42,  0x7E,  0x98,  0x64,  0xE4,  0x04,  0x01,  0x2D,  0xC8,
11014   0x31,  0x05,  0x07,  0x01,  0x00,  0xA2,  0x54,  0x03,  0x00,  0x43,  0x87,  0x01,  0x05,  0x05,  0x86,  0x98,
11015   0x7E,  0x98,  0x00,  0xA6,  0x16,  0x03,  0x07,  0xA6,  0x4C,  0x03,  0x03,  0xA6,  0x3C,  0x04,  0x06,  0xA6,
11016   0x50,  0x03,  0x01,  0xA6,  0x16,  0x03,  0x00,  0x33,  0x25,  0x00,  0xC2,  0x88,  0x7C,  0x95,  0x32,  0x83,
11017   0x60,  0x96,  0x32,  0x83,  0x04,  0x01,  0x10,  0xCE,  0x07,  0xC8,  0x05,  0x05,  0xEB,  0x04,  0x00,  0x33,
11018   0x00,  0x20,  0xC0,  0x20,  0x81,  0x62,  0x72,  0x83,  0x00,  0x01,  0x05,  0x05,  0xFF,  0xA2,  0x7A,  0x03,
11019   0xB1,  0x01,  0x08,  0x23,  0xB2,  0x01,  0x2E,  0x83,  0x05,  0x05,  0x15,  0x01,  0x00,  0xA2,  0x9A,  0x03,
11020   0xEC,  0x00,  0x6E,  0x00,  0x95,  0x01,  0x6C,  0x38,  0x00,  0x3F,  0x00,  0x00,  0x01,  0xA6,  0x96,  0x03,
11021   0x00,  0xA6,  0x96,  0x03,  0x10,  0x84,  0x80,  0x42,  0x7E,  0x98,  0x01,  0xA6,  0xA4,  0x03,  0x00,  0xA6,
11022   0xBC,  0x03,  0x10,  0x84,  0xA8,  0x98,  0x80,  0x42,  0x01,  0xA6,  0xA4,  0x03,  0x07,  0xA6,  0xB2,  0x03,
11023   0xD4,  0x83,  0x7C,  0x95,  0xA8,  0x83,  0x00,  0x33,  0x2F,  0x00,  0xC2,  0x88,  0xA8,  0x98,  0x80,  0x42,
11024   0x00,  0xA6,  0xBC,  0x03,  0x07,  0xA6,  0xCA,  0x03,  0xD4,  0x83,  0x7C,  0x95,  0xC0,  0x83,  0x00,  0x33,
11025   0x26,  0x00,  0xC2,  0x88,  0x38,  0x2B,  0x80,  0x32,  0x80,  0x36,  0x04,  0x23,  0xA0,  0x01,  0x12,  0x23,
11026   0xA1,  0x01,  0x10,  0x84,  0x07,  0xF0,  0x06,  0xA4,  0xF4,  0x03,  0x80,  0x6B,  0x80,  0x67,  0x05,  0x23,
11027   0x83,  0x03,  0x80,  0x63,  0x03,  0xA6,  0x0E,  0x04,  0x07,  0xA6,  0x06,  0x04,  0x06,  0xA6,  0x0A,  0x04,
11028   0x00,  0x33,  0x17,  0x00,  0xC2,  0x88,  0x7C,  0x95,  0xF4,  0x83,  0x60,  0x96,  0xF4,  0x83,  0x20,  0x84,
11029   0x07,  0xF0,  0x06,  0xA4,  0x20,  0x04,  0x80,  0x6B,  0x80,  0x67,  0x05,  0x23,  0x83,  0x03,  0x80,  0x63,
11030   0xB6,  0x2D,  0x03,  0xA6,  0x3C,  0x04,  0x07,  0xA6,  0x34,  0x04,  0x06,  0xA6,  0x38,  0x04,  0x00,  0x33,
11031   0x30,  0x00,  0xC2,  0x88,  0x7C,  0x95,  0x20,  0x84,  0x60,  0x96,  0x20,  0x84,  0x1D,  0x01,  0x06,  0xCC,
11032   0x00,  0x33,  0x00,  0x84,  0xC0,  0x20,  0x00,  0x23,  0xEA,  0x00,  0x81,  0x62,  0xA2,  0x0D,  0x80,  0x63,
11033   0x07,  0xA6,  0x5A,  0x04,  0x00,  0x33,  0x18,  0x00,  0xC2,  0x88,  0x03,  0x03,  0x80,  0x63,  0xA3,  0x01,
11034   0x07,  0xA4,  0x64,  0x04,  0x23,  0x01,  0x00,  0xA2,  0x86,  0x04,  0x0A,  0xA0,  0x76,  0x04,  0xE0,  0x00,
11035   0x00,  0x33,  0x1D,  0x00,  0xC2,  0x88,  0x0B,  0xA0,  0x82,  0x04,  0xE0,  0x00,  0x00,  0x33,  0x1E,  0x00,
11036   0xC2,  0x88,  0x42,  0x23,  0xF8,  0x88,  0x00,  0x23,  0x22,  0xA3,  0xE6,  0x04,  0x08,  0x23,  0x22,  0xA3,
11037   0xA2,  0x04,  0x28,  0x23,  0x22,  0xA3,  0xAE,  0x04,  0x02,  0x23,  0x22,  0xA3,  0xC4,  0x04,  0x42,  0x23,
11038   0xF8,  0x88,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA0,  0xAE,  0x04,  0x45,  0x23,  0xF8,  0x88,  0x04,  0x98,
11039   0x00,  0xA2,  0xC0,  0x04,  0xB4,  0x98,  0x00,  0x33,  0x00,  0x82,  0xC0,  0x20,  0x81,  0x62,  0xE8,  0x81,
11040   0x47,  0x23,  0xF8,  0x88,  0x04,  0x01,  0x0B,  0xDE,  0x04,  0x98,  0xB4,  0x98,  0x00,  0x33,  0x00,  0x81,
11041   0xC0,  0x20,  0x81,  0x62,  0x14,  0x01,  0x00,  0xA0,  0x00,  0x02,  0x43,  0x23,  0xF8,  0x88,  0x04,  0x23,
11042   0xA0,  0x01,  0x44,  0x23,  0xA1,  0x01,  0x80,  0x73,  0x4D,  0x00,  0x03,  0xA3,  0xF4,  0x04,  0x00,  0x33,
11043   0x27,  0x00,  0xC2,  0x88,  0x04,  0x01,  0x04,  0xDC,  0x02,  0x23,  0xA2,  0x01,  0x04,  0x23,  0xA0,  0x01,
11044   0x04,  0x98,  0x26,  0x95,  0x4B,  0x00,  0xF6,  0x00,  0x4F,  0x04,  0x4F,  0x00,  0x00,  0xA3,  0x22,  0x05,
11045   0x00,  0x05,  0x76,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x1C,  0x05,  0x0A,  0x85,  0x46,  0x97,  0xCD,  0x04,
11046   0x24,  0x85,  0x48,  0x04,  0x84,  0x80,  0x02,  0x01,  0x03,  0xDA,  0x80,  0x23,  0x82,  0x01,  0x34,  0x85,
11047   0x02,  0x23,  0xA0,  0x01,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA2,  0x40,  0x05,  0x1D,  0x01,  0x04,  0xD6,
11048   0xFF,  0x23,  0x86,  0x41,  0x4B,  0x60,  0xCB,  0x00,  0xFF,  0x23,  0x80,  0x01,  0x49,  0x00,  0x81,  0x01,
11049   0x04,  0x01,  0x02,  0xC8,  0x30,  0x01,  0x80,  0x01,  0xF7,  0x04,  0x03,  0x01,  0x49,  0x04,  0x80,  0x01,
11050   0xC9,  0x00,  0x00,  0x05,  0x00,  0x01,  0xFF,  0xA0,  0x60,  0x05,  0x77,  0x04,  0x01,  0x23,  0xEA,  0x00,
11051   0x5D,  0x00,  0xFE,  0xC7,  0x00,  0x62,  0x00,  0x23,  0xEA,  0x00,  0x00,  0x63,  0x07,  0xA4,  0xF8,  0x05,
11052   0x03,  0x03,  0x02,  0xA0,  0x8E,  0x05,  0xF4,  0x85,  0x00,  0x33,  0x2D,  0x00,  0xC2,  0x88,  0x04,  0xA0,
11053   0xB8,  0x05,  0x80,  0x63,  0x00,  0x23,  0xDF,  0x00,  0x4A,  0x00,  0x06,  0x61,  0x00,  0xA2,  0xA4,  0x05,
11054   0x1D,  0x01,  0x06,  0xD6,  0x02,  0x23,  0x02,  0x41,  0x82,  0x01,  0x50,  0x00,  0x62,  0x97,  0x04,  0x85,
11055   0x04,  0x23,  0x02,  0x41,  0x82,  0x01,  0x04,  0x85,  0x08,  0xA0,  0xBE,  0x05,  0xF4,  0x85,  0x03,  0xA0,
11056   0xC4,  0x05,  0xF4,  0x85,  0x01,  0xA0,  0xCE,  0x05,  0x88,  0x00,  0x80,  0x63,  0xCC,  0x86,  0x07,  0xA0,
11057   0xEE,  0x05,  0x5F,  0x00,  0x00,  0x2B,  0xDF,  0x08,  0x00,  0xA2,  0xE6,  0x05,  0x80,  0x67,  0x80,  0x63,
11058   0x01,  0xA2,  0x7A,  0x06,  0x7C,  0x85,  0x06,  0x23,  0x68,  0x98,  0x48,  0x23,  0xF8,  0x88,  0x07,  0x23,
11059   0x80,  0x00,  0x06,  0x87,  0x80,  0x63,  0x7C,  0x85,  0x00,  0x23,  0xDF,  0x00,  0x00,  0x63,  0x4A,  0x00,
11060   0x06,  0x61,  0x00,  0xA2,  0x36,  0x06,  0x1D,  0x01,  0x16,  0xD4,  0xC0,  0x23,  0x07,  0x41,  0x83,  0x03,
11061   0x80,  0x63,  0x06,  0xA6,  0x1C,  0x06,  0x00,  0x33,  0x37,  0x00,  0xC2,  0x88,  0x1D,  0x01,  0x01,  0xD6,
11062   0x20,  0x23,  0x63,  0x60,  0x83,  0x03,  0x80,  0x63,  0x02,  0x23,  0xDF,  0x00,  0x07,  0xA6,  0x7C,  0x05,
11063   0xEF,  0x04,  0x6F,  0x00,  0x00,  0x63,  0x4B,  0x00,  0x06,  0x41,  0xCB,  0x00,  0x52,  0x00,  0x06,  0x61,
11064   0x00,  0xA2,  0x4E,  0x06,  0x1D,  0x01,  0x03,  0xCA,  0xC0,  0x23,  0x07,  0x41,  0x00,  0x63,  0x1D,  0x01,
11065   0x04,  0xCC,  0x00,  0x33,  0x00,  0x83,  0xC0,  0x20,  0x81,  0x62,  0x80,  0x23,  0x07,  0x41,  0x00,  0x63,
11066   0x80,  0x67,  0x08,  0x23,  0x83,  0x03,  0x80,  0x63,  0x00,  0x63,  0x01,  0x23,  0xDF,  0x00,  0x06,  0xA6,
11067   0x84,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x80,  0x67,  0x80,  0x63,  0x00,  0x33,  0x00,  0x40,  0xC0,  0x20,
11068   0x81,  0x62,  0x00,  0x63,  0x00,  0x00,  0xFE,  0x95,  0x83,  0x03,  0x80,  0x63,  0x06,  0xA6,  0x94,  0x06,
11069   0x07,  0xA6,  0x7C,  0x05,  0x00,  0x00,  0x01,  0xA0,  0x14,  0x07,  0x00,  0x2B,  0x40,  0x0E,  0x80,  0x63,
11070   0x01,  0x00,  0x06,  0xA6,  0xAA,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x40,  0x0E,  0x80,  0x63,  0x00,  0x43,
11071   0x00,  0xA0,  0xA2,  0x06,  0x06,  0xA6,  0xBC,  0x06,  0x07,  0xA6,  0x7C,  0x05,  0x80,  0x67,  0x40,  0x0E,
11072   0x80,  0x63,  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x23,  0xDF,  0x00,  0x00,  0x63,  0x07,  0xA6,  0xD6,  0x06,
11073   0x00,  0x33,  0x2A,  0x00,  0xC2,  0x88,  0x03,  0x03,  0x80,  0x63,  0x89,  0x00,  0x0A,  0x2B,  0x07,  0xA6,
11074   0xE8,  0x06,  0x00,  0x33,  0x29,  0x00,  0xC2,  0x88,  0x00,  0x43,  0x00,  0xA2,  0xF4,  0x06,  0xC0,  0x0E,
11075   0x80,  0x63,  0xDE,  0x86,  0xC0,  0x0E,  0x00,  0x33,  0x00,  0x80,  0xC0,  0x20,  0x81,  0x62,  0x04,  0x01,
11076   0x02,  0xDA,  0x80,  0x63,  0x7C,  0x85,  0x80,  0x7B,  0x80,  0x63,  0x06,  0xA6,  0x8C,  0x06,  0x00,  0x33,
11077   0x2C,  0x00,  0xC2,  0x88,  0x0C,  0xA2,  0x2E,  0x07,  0xFE,  0x95,  0x83,  0x03,  0x80,  0x63,  0x06,  0xA6,
11078   0x2C,  0x07,  0x07,  0xA6,  0x7C,  0x05,  0x00,  0x33,  0x3D,  0x00,  0xC2,  0x88,  0x00,  0x00,  0x80,  0x67,
11079   0x83,  0x03,  0x80,  0x63,  0x0C,  0xA0,  0x44,  0x07,  0x07,  0xA6,  0x7C,  0x05,  0xBF,  0x23,  0x04,  0x61,
11080   0x84,  0x01,  0xE6,  0x84,  0x00,  0x63,  0xF0,  0x04,  0x01,  0x01,  0xF1,  0x00,  0x00,  0x01,  0xF2,  0x00,
11081   0x01,  0x05,  0x80,  0x01,  0x72,  0x04,  0x71,  0x00,  0x81,  0x01,  0x70,  0x04,  0x80,  0x05,  0x81,  0x05,
11082   0x00,  0x63,  0xF0,  0x04,  0xF2,  0x00,  0x72,  0x04,  0x01,  0x01,  0xF1,  0x00,  0x70,  0x00,  0x81,  0x01,
11083   0x70,  0x04,  0x71,  0x00,  0x81,  0x01,  0x72,  0x00,  0x80,  0x01,  0x71,  0x04,  0x70,  0x00,  0x80,  0x01,
11084   0x70,  0x04,  0x00,  0x63,  0xF0,  0x04,  0xF2,  0x00,  0x72,  0x04,  0x00,  0x01,  0xF1,  0x00,  0x70,  0x00,
11085   0x80,  0x01,  0x70,  0x04,  0x71,  0x00,  0x80,  0x01,  0x72,  0x00,  0x81,  0x01,  0x71,  0x04,  0x70,  0x00,
11086   0x81,  0x01,  0x70,  0x04,  0x00,  0x63,  0x00,  0x23,  0xB3,  0x01,  0x83,  0x05,  0xA3,  0x01,  0xA2,  0x01,
11087   0xA1,  0x01,  0x01,  0x23,  0xA0,  0x01,  0x00,  0x01,  0xC8,  0x00,  0x03,  0xA1,  0xC4,  0x07,  0x00,  0x33,
11088   0x07,  0x00,  0xC2,  0x88,  0x80,  0x05,  0x81,  0x05,  0x04,  0x01,  0x11,  0xC8,  0x48,  0x00,  0xB0,  0x01,
11089   0xB1,  0x01,  0x08,  0x23,  0xB2,  0x01,  0x05,  0x01,  0x48,  0x04,  0x00,  0x43,  0x00,  0xA2,  0xE4,  0x07,
11090   0x00,  0x05,  0xDA,  0x87,  0x00,  0x01,  0xC8,  0x00,  0xFF,  0x23,  0x80,  0x01,  0x05,  0x05,  0x00,  0x63,
11091   0xF7,  0x04,  0x1A,  0x09,  0xF6,  0x08,  0x6E,  0x04,  0x00,  0x02,  0x80,  0x43,  0x76,  0x08,  0x80,  0x02,
11092   0x77,  0x04,  0x00,  0x63,  0xF7,  0x04,  0x1A,  0x09,  0xF6,  0x08,  0x6E,  0x04,  0x00,  0x02,  0x00,  0xA0,
11093   0x14,  0x08,  0x16,  0x88,  0x00,  0x43,  0x76,  0x08,  0x80,  0x02,  0x77,  0x04,  0x00,  0x63,  0xF3,  0x04,
11094   0x00,  0x23,  0xF4,  0x00,  0x74,  0x00,  0x80,  0x43,  0xF4,  0x00,  0xCF,  0x40,  0x00,  0xA2,  0x44,  0x08,
11095   0x74,  0x04,  0x02,  0x01,  0xF7,  0xC9,  0xF6,  0xD9,  0x00,  0x01,  0x01,  0xA1,  0x24,  0x08,  0x04,  0x98,
11096   0x26,  0x95,  0x24,  0x88,  0x73,  0x04,  0x00,  0x63,  0xF3,  0x04,  0x75,  0x04,  0x5A,  0x88,  0x02,  0x01,
11097   0x04,  0xD8,  0x46,  0x97,  0x04,  0x98,  0x26,  0x95,  0x4A,  0x88,  0x75,  0x00,  0x00,  0xA3,  0x64,  0x08,
11098   0x00,  0x05,  0x4E,  0x88,  0x73,  0x04,  0x00,  0x63,  0x80,  0x7B,  0x80,  0x63,  0x06,  0xA6,  0x76,  0x08,
11099   0x00,  0x33,  0x3E,  0x00,  0xC2,  0x88,  0x80,  0x67,  0x83,  0x03,  0x80,  0x63,  0x00,  0x63,  0x38,  0x2B,
11100   0x9C,  0x88,  0x38,  0x2B,  0x92,  0x88,  0x32,  0x09,  0x31,  0x05,  0x92,  0x98,  0x05,  0x05,  0xB2,  0x09,
11101   0x00,  0x63,  0x00,  0x32,  0x00,  0x36,  0x00,  0x3A,  0x00,  0x3E,  0x00,  0x63,  0x80,  0x32,  0x80,  0x36,
11102   0x80,  0x3A,  0x80,  0x3E,  0xB4,  0x3D,  0x00,  0x63,  0x38,  0x2B,  0x40,  0x32,  0x40,  0x36,  0x40,  0x3A,
11103   0x40,  0x3E,  0x00,  0x63,  0x5A,  0x20,  0xC9,  0x40,  0x00,  0xA0,  0xB4,  0x08,  0x5D,  0x00,  0xFE,  0xC3,
11104   0x00,  0x63,  0x80,  0x73,  0xE6,  0x20,  0x02,  0x23,  0xE8,  0x00,  0x82,  0x73,  0xFF,  0xFD,  0x80,  0x73,
11105   0x13,  0x23,  0xF8,  0x88,  0x66,  0x20,  0xC0,  0x20,  0x04,  0x23,  0xA0,  0x01,  0xA1,  0x23,  0xA1,  0x01,
11106   0x81,  0x62,  0xE2,  0x88,  0x80,  0x73,  0x80,  0x77,  0x68,  0x00,  0x00,  0xA2,  0x80,  0x00,  0x03,  0xC2,
11107   0xF1,  0xC7,  0x41,  0x23,  0xF8,  0x88,  0x11,  0x23,  0xA1,  0x01,  0x04,  0x23,  0xA0,  0x01,  0xE6,  0x84,
11108 };
11109 
11110 STATIC ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
11111 STATIC ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
11112 
11113 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST  16
11114 STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] =
11115 {
11116     SCSICMD_Inquiry,
11117     SCSICMD_RequestSense,
11118     SCSICMD_ReadCapacity,
11119     SCSICMD_ReadTOC,
11120     SCSICMD_ModeSelect6,
11121     SCSICMD_ModeSense6,
11122     SCSICMD_ModeSelect10,
11123     SCSICMD_ModeSense10,
11124     0xFF,
11125     0xFF,
11126     0xFF,
11127     0xFF,
11128     0xFF,
11129     0xFF,
11130     0xFF,
11131     0xFF
11132 };
11133 
11134 STATIC int
AscExeScsiQueue(ASC_DVC_VAR * asc_dvc,ASC_SCSI_Q * scsiq)11135 AscExeScsiQueue(
11136                    ASC_DVC_VAR *asc_dvc,
11137                    ASC_SCSI_Q *scsiq
11138 )
11139 {
11140     PortAddr            iop_base;
11141     ulong               last_int_level;
11142     int                 sta;
11143     int                 n_q_required;
11144     int                 disable_syn_offset_one_fix;
11145     int                 i;
11146     ASC_PADDR           addr;
11147     ASC_EXE_CALLBACK    asc_exe_callback;
11148     ushort              sg_entry_cnt = 0;
11149     ushort              sg_entry_cnt_minus_one = 0;
11150     uchar               target_ix;
11151     uchar               tid_no;
11152     uchar               sdtr_data;
11153     uchar               extra_bytes;
11154     uchar               scsi_cmd;
11155     uchar               disable_cmd;
11156     ASC_SG_HEAD         *sg_head;
11157     ASC_DCNT            data_cnt;
11158 
11159     iop_base = asc_dvc->iop_base;
11160     sg_head = scsiq->sg_head;
11161     asc_exe_callback = asc_dvc->exe_callback;
11162     if (asc_dvc->err_code != 0)
11163         return (ERR);
11164     if (scsiq == (ASC_SCSI_Q *) 0L) {
11165         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
11166         return (ERR);
11167     }
11168     scsiq->q1.q_no = 0;
11169     if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
11170         scsiq->q1.extra_bytes = 0;
11171     }
11172     sta = 0;
11173     target_ix = scsiq->q2.target_ix;
11174     tid_no = ASC_TIX_TO_TID(target_ix);
11175     n_q_required = 1;
11176     if (scsiq->cdbptr[0] == SCSICMD_RequestSense) {
11177         if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
11178             asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
11179             sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
11180             AscMsgOutSDTR(asc_dvc,
11181                           asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
11182                           (uchar) (asc_dvc->max_sdtr_index - 1)],
11183                           (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
11184             scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
11185         }
11186     }
11187     last_int_level = DvcEnterCritical();
11188     if (asc_dvc->in_critical_cnt != 0) {
11189         DvcLeaveCritical(last_int_level);
11190         AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
11191         return (ERR);
11192     }
11193     asc_dvc->in_critical_cnt++;
11194     if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
11195         if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
11196             asc_dvc->in_critical_cnt--;
11197             DvcLeaveCritical(last_int_level);
11198             return (ERR);
11199         }
11200 #if !CC_VERY_LONG_SG_LIST
11201         if (sg_entry_cnt > ASC_MAX_SG_LIST)
11202         {
11203             asc_dvc->in_critical_cnt--;
11204             DvcLeaveCritical(last_int_level);
11205             return(ERR);
11206         }
11207 #endif /* !CC_VERY_LONG_SG_LIST */
11208         if (sg_entry_cnt == 1) {
11209             scsiq->q1.data_addr = (ADV_PADDR) sg_head->sg_list[0].addr;
11210             scsiq->q1.data_cnt = (ADV_DCNT) sg_head->sg_list[0].bytes;
11211             scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
11212         }
11213         sg_entry_cnt_minus_one = sg_entry_cnt - 1;
11214     }
11215     scsi_cmd = scsiq->cdbptr[0];
11216     disable_syn_offset_one_fix = FALSE;
11217     if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
11218         !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
11219         if (scsiq->q1.cntl & QC_SG_HEAD) {
11220             data_cnt = 0;
11221             for (i = 0; i < sg_entry_cnt; i++) {
11222                 data_cnt += (ADV_DCNT) le32_to_cpu(sg_head->sg_list[i].bytes);
11223             }
11224         } else {
11225             data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
11226         }
11227         if (data_cnt != 0UL) {
11228             if (data_cnt < 512UL) {
11229                 disable_syn_offset_one_fix = TRUE;
11230             } else {
11231                 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST; i++) {
11232                     disable_cmd = _syn_offset_one_disable_cmd[i];
11233                     if (disable_cmd == 0xFF) {
11234                         break;
11235                     }
11236                     if (scsi_cmd == disable_cmd) {
11237                         disable_syn_offset_one_fix = TRUE;
11238                         break;
11239                     }
11240                 }
11241             }
11242         }
11243     }
11244     if (disable_syn_offset_one_fix) {
11245         scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
11246         scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
11247                                ASC_TAG_FLAG_DISABLE_DISCONNECT);
11248     } else {
11249         scsiq->q2.tag_code &= 0x27;
11250     }
11251     if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
11252         if (asc_dvc->bug_fix_cntl) {
11253             if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
11254                 if ((scsi_cmd == SCSICMD_Read6) ||
11255                     (scsi_cmd == SCSICMD_Read10)) {
11256                     addr =
11257                         (ADV_PADDR) le32_to_cpu(
11258                             sg_head->sg_list[sg_entry_cnt_minus_one].addr) +
11259                         (ADV_DCNT) le32_to_cpu(
11260                             sg_head->sg_list[sg_entry_cnt_minus_one].bytes);
11261                     extra_bytes = (uchar) ((ushort) addr & 0x0003);
11262                     if ((extra_bytes != 0) &&
11263                         ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
11264                          == 0)) {
11265                         scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
11266                         scsiq->q1.extra_bytes = extra_bytes;
11267                         data_cnt = le32_to_cpu(
11268                             sg_head->sg_list[sg_entry_cnt_minus_one].bytes);
11269                         data_cnt -= (ASC_DCNT) extra_bytes;
11270                         sg_head->sg_list[sg_entry_cnt_minus_one].bytes =
11271                             cpu_to_le32(data_cnt);
11272                     }
11273                 }
11274             }
11275         }
11276         sg_head->entry_to_copy = sg_head->entry_cnt;
11277 #if CC_VERY_LONG_SG_LIST
11278         /*
11279          * Set the sg_entry_cnt to the maximum possible. The rest of
11280          * the SG elements will be copied when the RISC completes the
11281          * SG elements that fit and halts.
11282          */
11283         if (sg_entry_cnt > ASC_MAX_SG_LIST)
11284         {
11285              sg_entry_cnt = ASC_MAX_SG_LIST;
11286         }
11287 #endif /* CC_VERY_LONG_SG_LIST */
11288         n_q_required = AscSgListToQueue(sg_entry_cnt);
11289         if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
11290             (uint) n_q_required) || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
11291             if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
11292                                         n_q_required)) == 1) {
11293                 asc_dvc->in_critical_cnt--;
11294                 if (asc_exe_callback != 0) {
11295                     (*asc_exe_callback) (asc_dvc, scsiq);
11296                 }
11297                 DvcLeaveCritical(last_int_level);
11298                 return (sta);
11299             }
11300         }
11301     } else {
11302         if (asc_dvc->bug_fix_cntl) {
11303             if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
11304                 if ((scsi_cmd == SCSICMD_Read6) ||
11305                     (scsi_cmd == SCSICMD_Read10)) {
11306                     addr = le32_to_cpu(scsiq->q1.data_addr) +
11307                         le32_to_cpu(scsiq->q1.data_cnt);
11308                     extra_bytes = (uchar) ((ushort) addr & 0x0003);
11309                     if ((extra_bytes != 0) &&
11310                         ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
11311                           == 0)) {
11312                         data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
11313                         if (((ushort) data_cnt & 0x01FF) == 0) {
11314                             scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
11315                             data_cnt -= (ASC_DCNT) extra_bytes;
11316                             scsiq->q1.data_cnt = cpu_to_le32(data_cnt);
11317                             scsiq->q1.extra_bytes = extra_bytes;
11318                         }
11319                     }
11320                 }
11321             }
11322         }
11323         n_q_required = 1;
11324         if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
11325             ((scsiq->q1.cntl & QC_URGENT) != 0)) {
11326             if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
11327                                         n_q_required)) == 1) {
11328                 asc_dvc->in_critical_cnt--;
11329                 if (asc_exe_callback != 0) {
11330                     (*asc_exe_callback) (asc_dvc, scsiq);
11331                 }
11332                 DvcLeaveCritical(last_int_level);
11333                 return (sta);
11334             }
11335         }
11336     }
11337     asc_dvc->in_critical_cnt--;
11338     DvcLeaveCritical(last_int_level);
11339     return (sta);
11340 }
11341 
11342 STATIC int
AscSendScsiQueue(ASC_DVC_VAR * asc_dvc,ASC_SCSI_Q * scsiq,uchar n_q_required)11343 AscSendScsiQueue(
11344                     ASC_DVC_VAR *asc_dvc,
11345                     ASC_SCSI_Q *scsiq,
11346                     uchar n_q_required
11347 )
11348 {
11349     PortAddr            iop_base;
11350     uchar               free_q_head;
11351     uchar               next_qp;
11352     uchar               tid_no;
11353     uchar               target_ix;
11354     int                 sta;
11355 
11356     iop_base = asc_dvc->iop_base;
11357     target_ix = scsiq->q2.target_ix;
11358     tid_no = ASC_TIX_TO_TID(target_ix);
11359     sta = 0;
11360     free_q_head = (uchar) AscGetVarFreeQHead(iop_base);
11361     if (n_q_required > 1) {
11362         if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
11363                                        free_q_head, (uchar) (n_q_required)))
11364             != (uchar) ASC_QLINK_END) {
11365             asc_dvc->last_q_shortage = 0;
11366             scsiq->sg_head->queue_cnt = n_q_required - 1;
11367             scsiq->q1.q_no = free_q_head;
11368             if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
11369                                               free_q_head)) == 1) {
11370                 AscPutVarFreeQHead(iop_base, next_qp);
11371                 asc_dvc->cur_total_qng += (uchar) (n_q_required);
11372                 asc_dvc->cur_dvc_qng[tid_no]++;
11373             }
11374             return (sta);
11375         }
11376     } else if (n_q_required == 1) {
11377         if ((next_qp = AscAllocFreeQueue(iop_base,
11378                                          free_q_head)) != ASC_QLINK_END) {
11379             scsiq->q1.q_no = free_q_head;
11380             if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
11381                                         free_q_head)) == 1) {
11382                 AscPutVarFreeQHead(iop_base, next_qp);
11383                 asc_dvc->cur_total_qng++;
11384                 asc_dvc->cur_dvc_qng[tid_no]++;
11385             }
11386             return (sta);
11387         }
11388     }
11389     return (sta);
11390 }
11391 
11392 STATIC int
AscSgListToQueue(int sg_list)11393 AscSgListToQueue(
11394                     int sg_list
11395 )
11396 {
11397     int                 n_sg_list_qs;
11398 
11399     n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
11400     if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
11401         n_sg_list_qs++;
11402     return (n_sg_list_qs + 1);
11403 }
11404 
11405 
11406 STATIC uint
AscGetNumOfFreeQueue(ASC_DVC_VAR * asc_dvc,uchar target_ix,uchar n_qs)11407 AscGetNumOfFreeQueue(
11408                         ASC_DVC_VAR *asc_dvc,
11409                         uchar target_ix,
11410                         uchar n_qs
11411 )
11412 {
11413     uint                cur_used_qs;
11414     uint                cur_free_qs;
11415     ASC_SCSI_BIT_ID_TYPE target_id;
11416     uchar               tid_no;
11417 
11418     target_id = ASC_TIX_TO_TARGET_ID(target_ix);
11419     tid_no = ASC_TIX_TO_TID(target_ix);
11420     if ((asc_dvc->unit_not_ready & target_id) ||
11421         (asc_dvc->queue_full_or_busy & target_id)) {
11422         return (0);
11423     }
11424     if (n_qs == 1) {
11425         cur_used_qs = (uint) asc_dvc->cur_total_qng +
11426           (uint) asc_dvc->last_q_shortage +
11427           (uint) ASC_MIN_FREE_Q;
11428     } else {
11429         cur_used_qs = (uint) asc_dvc->cur_total_qng +
11430           (uint) ASC_MIN_FREE_Q;
11431     }
11432     if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
11433         cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
11434         if (asc_dvc->cur_dvc_qng[tid_no] >=
11435             asc_dvc->max_dvc_qng[tid_no]) {
11436             return (0);
11437         }
11438         return (cur_free_qs);
11439     }
11440     if (n_qs > 1) {
11441         if ((n_qs > asc_dvc->last_q_shortage) && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
11442             asc_dvc->last_q_shortage = n_qs;
11443         }
11444     }
11445     return (0);
11446 }
11447 
11448 STATIC int
AscPutReadyQueue(ASC_DVC_VAR * asc_dvc,ASC_SCSI_Q * scsiq,uchar q_no)11449 AscPutReadyQueue(
11450                     ASC_DVC_VAR *asc_dvc,
11451                     ASC_SCSI_Q *scsiq,
11452                     uchar q_no
11453 )
11454 {
11455     ushort              q_addr;
11456     uchar               tid_no;
11457     uchar               sdtr_data;
11458     uchar               syn_period_ix;
11459     uchar               syn_offset;
11460     PortAddr            iop_base;
11461 
11462     iop_base = asc_dvc->iop_base;
11463     if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
11464         ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
11465         tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
11466         sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
11467         syn_period_ix = (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
11468         syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
11469         AscMsgOutSDTR(asc_dvc,
11470                       asc_dvc->sdtr_period_tbl[syn_period_ix],
11471                       syn_offset);
11472         scsiq->q1.cntl |= QC_MSG_OUT;
11473     }
11474     q_addr = ASC_QNO_TO_QADDR(q_no);
11475     if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
11476         scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
11477     }
11478     scsiq->q1.status = QS_FREE;
11479     AscMemWordCopyPtrToLram(iop_base,
11480                          q_addr + ASC_SCSIQ_CDB_BEG,
11481                          (uchar *) scsiq->cdbptr,
11482                          scsiq->q2.cdb_len >> 1);
11483 
11484     DvcPutScsiQ(iop_base,
11485                 q_addr + ASC_SCSIQ_CPY_BEG,
11486                 (uchar *) &scsiq->q1.cntl,
11487                 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
11488     AscWriteLramWord(iop_base,
11489                      (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
11490              (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY));
11491     return (1);
11492 }
11493 
11494 STATIC int
AscPutReadySgListQueue(ASC_DVC_VAR * asc_dvc,ASC_SCSI_Q * scsiq,uchar q_no)11495 AscPutReadySgListQueue(
11496                           ASC_DVC_VAR *asc_dvc,
11497                           ASC_SCSI_Q *scsiq,
11498                           uchar q_no
11499 )
11500 {
11501     int                 sta;
11502     int                 i;
11503     ASC_SG_HEAD *sg_head;
11504     ASC_SG_LIST_Q       scsi_sg_q;
11505     ASC_DCNT            saved_data_addr;
11506     ASC_DCNT            saved_data_cnt;
11507     PortAddr            iop_base;
11508     ushort              sg_list_dwords;
11509     ushort              sg_index;
11510     ushort              sg_entry_cnt;
11511     ushort              q_addr;
11512     uchar               next_qp;
11513 
11514     iop_base = asc_dvc->iop_base;
11515     sg_head = scsiq->sg_head;
11516     saved_data_addr = scsiq->q1.data_addr;
11517     saved_data_cnt = scsiq->q1.data_cnt;
11518     scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
11519     scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
11520 #if CC_VERY_LONG_SG_LIST
11521     /*
11522      * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
11523      * then not all SG elements will fit in the allocated queues.
11524      * The rest of the SG elements will be copied when the RISC
11525      * completes the SG elements that fit and halts.
11526      */
11527     if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
11528     {
11529          /*
11530           * Set sg_entry_cnt to be the number of SG elements that
11531           * will fit in the allocated SG queues. It is minus 1, because
11532           * the first SG element is handled above. ASC_MAX_SG_LIST is
11533           * already inflated by 1 to account for this. For example it
11534           * may be 50 which is 1 + 7 queues * 7 SG elements.
11535           */
11536          sg_entry_cnt = ASC_MAX_SG_LIST - 1;
11537 
11538          /*
11539           * Keep track of remaining number of SG elements that will
11540           * need to be handled from a_isr.c.
11541           */
11542          scsiq->remain_sg_entry_cnt = sg_head->entry_cnt - ASC_MAX_SG_LIST;
11543     } else
11544     {
11545 #endif /* CC_VERY_LONG_SG_LIST */
11546          /*
11547           * Set sg_entry_cnt to be the number of SG elements that
11548           * will fit in the allocated SG queues. It is minus 1, because
11549           * the first SG element is handled above.
11550           */
11551          sg_entry_cnt = sg_head->entry_cnt - 1;
11552 #if CC_VERY_LONG_SG_LIST
11553     }
11554 #endif /* CC_VERY_LONG_SG_LIST */
11555     if (sg_entry_cnt != 0) {
11556         scsiq->q1.cntl |= QC_SG_HEAD;
11557         q_addr = ASC_QNO_TO_QADDR(q_no);
11558         sg_index = 1;
11559         scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
11560         scsi_sg_q.sg_head_qp = q_no;
11561         scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
11562         for (i = 0; i < sg_head->queue_cnt; i++) {
11563             scsi_sg_q.seq_no = i + 1;
11564             if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
11565                 sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
11566                 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
11567                 if (i == 0) {
11568                     scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q;
11569                     scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q;
11570                 } else {
11571                     scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
11572                     scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
11573                 }
11574             } else {
11575 #if CC_VERY_LONG_SG_LIST
11576                 /*
11577                  * This is the last SG queue in the list of
11578                  * allocated SG queues. If there are more
11579                  * SG elements than will fit in the allocated
11580                  * queues, then set the QCSG_SG_XFER_MORE flag.
11581                  */
11582                 if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
11583                 {
11584                     scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
11585                 } else
11586                 {
11587 #endif /* CC_VERY_LONG_SG_LIST */
11588                     scsi_sg_q.cntl |= QCSG_SG_XFER_END;
11589 #if CC_VERY_LONG_SG_LIST
11590                 }
11591 #endif /* CC_VERY_LONG_SG_LIST */
11592                 sg_list_dwords = sg_entry_cnt << 1;
11593                 if (i == 0) {
11594                     scsi_sg_q.sg_list_cnt = sg_entry_cnt;
11595                     scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt;
11596                 } else {
11597                     scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
11598                     scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
11599                 }
11600                 sg_entry_cnt = 0;
11601             }
11602             next_qp = AscReadLramByte(iop_base,
11603                                       (ushort) (q_addr + ASC_SCSIQ_B_FWD));
11604             scsi_sg_q.q_no = next_qp;
11605             q_addr = ASC_QNO_TO_QADDR(next_qp);
11606             AscMemWordCopyPtrToLram(iop_base,
11607                                 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
11608                                 (uchar *) &scsi_sg_q,
11609                                 sizeof(ASC_SG_LIST_Q) >> 1);
11610             AscMemDWordCopyPtrToLram(iop_base,
11611                                 q_addr + ASC_SGQ_LIST_BEG,
11612                                 (uchar *) &sg_head->sg_list[sg_index],
11613                                 sg_list_dwords);
11614             sg_index += ASC_SG_LIST_PER_Q;
11615             scsiq->next_sg_index = sg_index;
11616         }
11617     } else {
11618         scsiq->q1.cntl &= ~QC_SG_HEAD;
11619     }
11620     sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
11621     scsiq->q1.data_addr = saved_data_addr;
11622     scsiq->q1.data_cnt = saved_data_cnt;
11623     return (sta);
11624 }
11625 
11626 STATIC int
AscSetRunChipSynRegAtID(PortAddr iop_base,uchar tid_no,uchar sdtr_data)11627 AscSetRunChipSynRegAtID(
11628                            PortAddr iop_base,
11629                            uchar tid_no,
11630                            uchar sdtr_data
11631 )
11632 {
11633     int                 sta = FALSE;
11634 
11635     if (AscHostReqRiscHalt(iop_base)) {
11636         sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
11637         AscStartChip(iop_base);
11638         return (sta);
11639     }
11640     return (sta);
11641 }
11642 
11643 STATIC int
AscSetChipSynRegAtID(PortAddr iop_base,uchar id,uchar sdtr_data)11644 AscSetChipSynRegAtID(
11645                         PortAddr iop_base,
11646                         uchar id,
11647                         uchar sdtr_data
11648 )
11649 {
11650     ASC_SCSI_BIT_ID_TYPE org_id;
11651     int                 i;
11652     int                 sta = TRUE;
11653 
11654     AscSetBank(iop_base, 1);
11655     org_id = AscReadChipDvcID(iop_base);
11656     for (i = 0; i <= ASC_MAX_TID; i++) {
11657         if (org_id == (0x01 << i))
11658             break;
11659     }
11660     org_id = (ASC_SCSI_BIT_ID_TYPE) i;
11661     AscWriteChipDvcID(iop_base, id);
11662     if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
11663         AscSetBank(iop_base, 0);
11664         AscSetChipSyn(iop_base, sdtr_data);
11665         if (AscGetChipSyn(iop_base) != sdtr_data) {
11666             sta = FALSE;
11667         }
11668     } else {
11669         sta = FALSE;
11670     }
11671     AscSetBank(iop_base, 1);
11672     AscWriteChipDvcID(iop_base, org_id);
11673     AscSetBank(iop_base, 0);
11674     return (sta);
11675 }
11676 
11677 STATIC ushort
AscInitLram(ASC_DVC_VAR * asc_dvc)11678 AscInitLram(
11679                ASC_DVC_VAR *asc_dvc
11680 )
11681 {
11682     uchar               i;
11683     ushort              s_addr;
11684     PortAddr            iop_base;
11685     ushort              warn_code;
11686 
11687     iop_base = asc_dvc->iop_base;
11688     warn_code = 0;
11689     AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
11690                (ushort) (((int) (asc_dvc->max_total_qng + 2 + 1) * 64) >> 1)
11691 );
11692     i = ASC_MIN_ACTIVE_QNO;
11693     s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
11694     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11695                      (uchar) (i + 1));
11696     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11697                      (uchar) (asc_dvc->max_total_qng));
11698     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11699                      (uchar) i);
11700     i++;
11701     s_addr += ASC_QBLK_SIZE;
11702     for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
11703         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11704                          (uchar) (i + 1));
11705         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11706                          (uchar) (i - 1));
11707         AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11708                          (uchar) i);
11709     }
11710     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11711                      (uchar) ASC_QLINK_END);
11712     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11713                      (uchar) (asc_dvc->max_total_qng - 1));
11714     AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11715                      (uchar) asc_dvc->max_total_qng);
11716     i++;
11717     s_addr += ASC_QBLK_SIZE;
11718     for (; i <= (uchar) (asc_dvc->max_total_qng + 3);
11719          i++, s_addr += ASC_QBLK_SIZE) {
11720         AscWriteLramByte(iop_base,
11721                          (ushort) (s_addr + (ushort) ASC_SCSIQ_B_FWD), i);
11722         AscWriteLramByte(iop_base,
11723                          (ushort) (s_addr + (ushort) ASC_SCSIQ_B_BWD), i);
11724         AscWriteLramByte(iop_base,
11725                          (ushort) (s_addr + (ushort) ASC_SCSIQ_B_QNO), i);
11726     }
11727     return (warn_code);
11728 }
11729 
11730 STATIC ushort
AscInitQLinkVar(ASC_DVC_VAR * asc_dvc)11731 AscInitQLinkVar(
11732                    ASC_DVC_VAR *asc_dvc
11733 )
11734 {
11735     PortAddr            iop_base;
11736     int                 i;
11737     ushort              lram_addr;
11738 
11739     iop_base = asc_dvc->iop_base;
11740     AscPutRiscVarFreeQHead(iop_base, 1);
11741     AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
11742     AscPutVarFreeQHead(iop_base, 1);
11743     AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
11744     AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
11745                      (uchar) ((int) asc_dvc->max_total_qng + 1));
11746     AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
11747                      (uchar) ((int) asc_dvc->max_total_qng + 2));
11748     AscWriteLramByte(iop_base, (ushort) ASCV_TOTAL_READY_Q_B,
11749                      asc_dvc->max_total_qng);
11750     AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
11751     AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
11752     AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
11753     AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
11754     AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
11755     AscPutQDoneInProgress(iop_base, 0);
11756     lram_addr = ASC_QADR_BEG;
11757     for (i = 0; i < 32; i++, lram_addr += 2) {
11758         AscWriteLramWord(iop_base, lram_addr, 0);
11759     }
11760     return (0);
11761 }
11762 
11763 STATIC int
AscSetLibErrorCode(ASC_DVC_VAR * asc_dvc,ushort err_code)11764 AscSetLibErrorCode(
11765                       ASC_DVC_VAR *asc_dvc,
11766                       ushort err_code
11767 )
11768 {
11769     if (asc_dvc->err_code == 0) {
11770         asc_dvc->err_code = err_code;
11771         AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
11772                          err_code);
11773     }
11774     return (err_code);
11775 }
11776 
11777 
11778 STATIC uchar
AscMsgOutSDTR(ASC_DVC_VAR * asc_dvc,uchar sdtr_period,uchar sdtr_offset)11779 AscMsgOutSDTR(
11780                  ASC_DVC_VAR *asc_dvc,
11781                  uchar sdtr_period,
11782                  uchar sdtr_offset
11783 )
11784 {
11785     EXT_MSG             sdtr_buf;
11786     uchar               sdtr_period_index;
11787     PortAddr            iop_base;
11788 
11789     iop_base = asc_dvc->iop_base;
11790     sdtr_buf.msg_type = MS_EXTEND;
11791     sdtr_buf.msg_len = MS_SDTR_LEN;
11792     sdtr_buf.msg_req = MS_SDTR_CODE;
11793     sdtr_buf.xfer_period = sdtr_period;
11794     sdtr_offset &= ASC_SYN_MAX_OFFSET;
11795     sdtr_buf.req_ack_offset = sdtr_offset;
11796     if ((sdtr_period_index =
11797          AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
11798         asc_dvc->max_sdtr_index) {
11799         AscMemWordCopyPtrToLram(iop_base,
11800                              ASCV_MSGOUT_BEG,
11801                              (uchar *) &sdtr_buf,
11802                              sizeof (EXT_MSG) >> 1);
11803         return ((sdtr_period_index << 4) | sdtr_offset);
11804     } else {
11805 
11806         sdtr_buf.req_ack_offset = 0;
11807         AscMemWordCopyPtrToLram(iop_base,
11808                              ASCV_MSGOUT_BEG,
11809                              (uchar *) &sdtr_buf,
11810                              sizeof (EXT_MSG) >> 1);
11811         return (0);
11812     }
11813 }
11814 
11815 STATIC uchar
AscCalSDTRData(ASC_DVC_VAR * asc_dvc,uchar sdtr_period,uchar syn_offset)11816 AscCalSDTRData(
11817                   ASC_DVC_VAR *asc_dvc,
11818                   uchar sdtr_period,
11819                   uchar syn_offset
11820 )
11821 {
11822     uchar               byte;
11823     uchar               sdtr_period_ix;
11824 
11825     sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
11826     if (
11827            (sdtr_period_ix > asc_dvc->max_sdtr_index)
11828 ) {
11829         return (0xFF);
11830     }
11831     byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
11832     return (byte);
11833 }
11834 
11835 STATIC void
AscSetChipSDTR(PortAddr iop_base,uchar sdtr_data,uchar tid_no)11836 AscSetChipSDTR(
11837                   PortAddr iop_base,
11838                   uchar sdtr_data,
11839                   uchar tid_no
11840 )
11841 {
11842     AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
11843     AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
11844     return;
11845 }
11846 
11847 STATIC uchar
AscGetSynPeriodIndex(ASC_DVC_VAR * asc_dvc,uchar syn_time)11848 AscGetSynPeriodIndex(
11849                         ASC_DVC_VAR *asc_dvc,
11850                         uchar syn_time
11851 )
11852 {
11853     uchar             *period_table;
11854     int                 max_index;
11855     int                 min_index;
11856     int                 i;
11857 
11858     period_table = asc_dvc->sdtr_period_tbl;
11859     max_index = (int) asc_dvc->max_sdtr_index;
11860     min_index = (int)asc_dvc->host_init_sdtr_index;
11861     if ((syn_time <= period_table[max_index])) {
11862         for (i = min_index; i < (max_index - 1); i++) {
11863             if (syn_time <= period_table[i]) {
11864                 return ((uchar) i);
11865             }
11866         }
11867         return ((uchar) max_index);
11868     } else {
11869         return ((uchar) (max_index + 1));
11870     }
11871 }
11872 
11873 STATIC uchar
AscAllocFreeQueue(PortAddr iop_base,uchar free_q_head)11874 AscAllocFreeQueue(
11875                      PortAddr iop_base,
11876                      uchar free_q_head
11877 )
11878 {
11879     ushort              q_addr;
11880     uchar               next_qp;
11881     uchar               q_status;
11882 
11883     q_addr = ASC_QNO_TO_QADDR(free_q_head);
11884     q_status = (uchar) AscReadLramByte(iop_base,
11885                                     (ushort) (q_addr + ASC_SCSIQ_B_STATUS));
11886     next_qp = AscReadLramByte(iop_base,
11887                               (ushort) (q_addr + ASC_SCSIQ_B_FWD));
11888     if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
11889         return (next_qp);
11890     }
11891     return (ASC_QLINK_END);
11892 }
11893 
11894 STATIC uchar
AscAllocMultipleFreeQueue(PortAddr iop_base,uchar free_q_head,uchar n_free_q)11895 AscAllocMultipleFreeQueue(
11896                              PortAddr iop_base,
11897                              uchar free_q_head,
11898                              uchar n_free_q
11899 )
11900 {
11901     uchar               i;
11902 
11903     for (i = 0; i < n_free_q; i++) {
11904         if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
11905             == ASC_QLINK_END) {
11906             return (ASC_QLINK_END);
11907         }
11908     }
11909     return (free_q_head);
11910 }
11911 
11912 STATIC int
AscHostReqRiscHalt(PortAddr iop_base)11913 AscHostReqRiscHalt(
11914                       PortAddr iop_base
11915 )
11916 {
11917     int                 count = 0;
11918     int                 sta = 0;
11919     uchar               saved_stop_code;
11920 
11921     if (AscIsChipHalted(iop_base))
11922         return (1);
11923     saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
11924     AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11925                      ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP
11926 );
11927     do {
11928         if (AscIsChipHalted(iop_base)) {
11929             sta = 1;
11930             break;
11931         }
11932         DvcSleepMilliSecond(100);
11933     } while (count++ < 20);
11934     AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
11935     return (sta);
11936 }
11937 
11938 STATIC int
AscStopQueueExe(PortAddr iop_base)11939 AscStopQueueExe(
11940                    PortAddr iop_base
11941 )
11942 {
11943     int                 count = 0;
11944 
11945     if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
11946         AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11947                          ASC_STOP_REQ_RISC_STOP);
11948         do {
11949             if (
11950                    AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
11951                    ASC_STOP_ACK_RISC_STOP) {
11952                 return (1);
11953             }
11954             DvcSleepMilliSecond(100);
11955         } while (count++ < 20);
11956     }
11957     return (0);
11958 }
11959 
11960 STATIC void
DvcDelayMicroSecond(ADV_DVC_VAR * asc_dvc,ushort micro_sec)11961 DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
11962 {
11963     udelay(micro_sec);
11964 }
11965 
11966 STATIC void
DvcDelayNanoSecond(ASC_DVC_VAR * asc_dvc,ASC_DCNT nano_sec)11967 DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
11968 {
11969     udelay((nano_sec + 999)/1000);
11970 }
11971 
11972 #ifdef CONFIG_ISA
ASC_INITFUNC(STATIC ASC_DCNT,AscGetEisaProductID (PortAddr iop_base))11973 ASC_INITFUNC(
11974 STATIC ASC_DCNT,
11975 AscGetEisaProductID(
11976                        PortAddr iop_base
11977 )
11978 )
11979 {
11980     PortAddr            eisa_iop;
11981     ushort              product_id_high, product_id_low;
11982     ASC_DCNT            product_id;
11983 
11984     eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
11985     product_id_low = inpw(eisa_iop);
11986     product_id_high = inpw(eisa_iop + 2);
11987     product_id = ((ASC_DCNT) product_id_high << 16) |
11988         (ASC_DCNT) product_id_low;
11989     return (product_id);
11990 }
11991 
ASC_INITFUNC(STATIC PortAddr,AscSearchIOPortAddrEISA (PortAddr iop_base))11992 ASC_INITFUNC(
11993 STATIC PortAddr,
11994 AscSearchIOPortAddrEISA(
11995                            PortAddr iop_base
11996 )
11997 )
11998 {
11999     ASC_DCNT            eisa_product_id;
12000 
12001     if (iop_base == 0) {
12002         iop_base = ASC_EISA_MIN_IOP_ADDR;
12003     } else {
12004         if (iop_base == ASC_EISA_MAX_IOP_ADDR)
12005             return (0);
12006         if ((iop_base & 0x0050) == 0x0050) {
12007             iop_base += ASC_EISA_BIG_IOP_GAP;
12008         } else {
12009             iop_base += ASC_EISA_SMALL_IOP_GAP;
12010         }
12011     }
12012     while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
12013         eisa_product_id = AscGetEisaProductID(iop_base);
12014         if ((eisa_product_id == ASC_EISA_ID_740) ||
12015             (eisa_product_id == ASC_EISA_ID_750)) {
12016             if (AscFindSignature(iop_base)) {
12017                 inpw(iop_base + 4);
12018                 return (iop_base);
12019             }
12020         }
12021         if (iop_base == ASC_EISA_MAX_IOP_ADDR)
12022             return (0);
12023         if ((iop_base & 0x0050) == 0x0050) {
12024             iop_base += ASC_EISA_BIG_IOP_GAP;
12025         } else {
12026             iop_base += ASC_EISA_SMALL_IOP_GAP;
12027         }
12028     }
12029     return (0);
12030 }
12031 #endif /* CONFIG_ISA */
12032 
12033 STATIC int
AscStartChip(PortAddr iop_base)12034 AscStartChip(
12035                 PortAddr iop_base
12036 )
12037 {
12038     AscSetChipControl(iop_base, 0);
12039     if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
12040         return (0);
12041     }
12042     return (1);
12043 }
12044 
12045 STATIC int
AscStopChip(PortAddr iop_base)12046 AscStopChip(
12047                PortAddr iop_base
12048 )
12049 {
12050     uchar               cc_val;
12051 
12052     cc_val = AscGetChipControl(iop_base) & (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
12053     AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT));
12054     AscSetChipIH(iop_base, INS_HALT);
12055     AscSetChipIH(iop_base, INS_RFLAG_WTM);
12056     if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
12057         return (0);
12058     }
12059     return (1);
12060 }
12061 
12062 STATIC int
AscIsChipHalted(PortAddr iop_base)12063 AscIsChipHalted(
12064                    PortAddr iop_base
12065 )
12066 {
12067     if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
12068         if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
12069             return (1);
12070         }
12071     }
12072     return (0);
12073 }
12074 
12075 STATIC void
AscSetChipIH(PortAddr iop_base,ushort ins_code)12076 AscSetChipIH(
12077                 PortAddr iop_base,
12078                 ushort ins_code
12079 )
12080 {
12081     AscSetBank(iop_base, 1);
12082     AscWriteChipIH(iop_base, ins_code);
12083     AscSetBank(iop_base, 0);
12084     return;
12085 }
12086 
12087 STATIC void
AscAckInterrupt(PortAddr iop_base)12088 AscAckInterrupt(
12089                    PortAddr iop_base
12090 )
12091 {
12092     uchar               host_flag;
12093     uchar               risc_flag;
12094     ushort              loop;
12095 
12096     loop = 0;
12097     do {
12098         risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
12099         if (loop++ > 0x7FFF) {
12100             break;
12101         }
12102     } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
12103     host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
12104     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
12105                      (uchar) (host_flag | ASC_HOST_FLAG_ACK_INT));
12106     AscSetChipStatus(iop_base, CIW_INT_ACK);
12107     loop = 0;
12108     while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
12109         AscSetChipStatus(iop_base, CIW_INT_ACK);
12110         if (loop++ > 3) {
12111             break;
12112         }
12113     }
12114     AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
12115     return;
12116 }
12117 
12118 STATIC void
AscDisableInterrupt(PortAddr iop_base)12119 AscDisableInterrupt(
12120                        PortAddr iop_base
12121 )
12122 {
12123     ushort              cfg;
12124 
12125     cfg = AscGetChipCfgLsw(iop_base);
12126     AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
12127     return;
12128 }
12129 
12130 STATIC void
AscEnableInterrupt(PortAddr iop_base)12131 AscEnableInterrupt(
12132                       PortAddr iop_base
12133 )
12134 {
12135     ushort              cfg;
12136 
12137     cfg = AscGetChipCfgLsw(iop_base);
12138     AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
12139     return;
12140 }
12141 
12142 
12143 
12144 STATIC void
AscSetBank(PortAddr iop_base,uchar bank)12145 AscSetBank(
12146               PortAddr iop_base,
12147               uchar bank
12148 )
12149 {
12150     uchar               val;
12151 
12152     val = AscGetChipControl(iop_base) &
12153       (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | CC_CHIP_RESET));
12154     if (bank == 1) {
12155         val |= CC_BANK_ONE;
12156     } else if (bank == 2) {
12157         val |= CC_DIAG | CC_BANK_ONE;
12158     } else {
12159         val &= ~CC_BANK_ONE;
12160     }
12161     AscSetChipControl(iop_base, val);
12162     return;
12163 }
12164 
12165 STATIC int
AscResetChipAndScsiBus(ASC_DVC_VAR * asc_dvc)12166 AscResetChipAndScsiBus(
12167                           ASC_DVC_VAR *asc_dvc
12168 )
12169 {
12170     PortAddr    iop_base;
12171     int         i = 10;
12172 
12173     iop_base = asc_dvc->iop_base;
12174     while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) && (i-- > 0))
12175     {
12176           DvcSleepMilliSecond(100);
12177     }
12178     AscStopChip(iop_base);
12179     AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
12180     DvcDelayNanoSecond(asc_dvc, 60000);
12181     AscSetChipIH(iop_base, INS_RFLAG_WTM);
12182     AscSetChipIH(iop_base, INS_HALT);
12183     AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
12184     AscSetChipControl(iop_base, CC_HALT);
12185     DvcSleepMilliSecond(200);
12186     AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
12187     AscSetChipStatus(iop_base, 0);
12188     return (AscIsChipHalted(iop_base));
12189 }
12190 
ASC_INITFUNC(STATIC ASC_DCNT,AscGetMaxDmaCount (ushort bus_type))12191 ASC_INITFUNC(
12192 STATIC ASC_DCNT,
12193 AscGetMaxDmaCount(
12194                      ushort bus_type
12195 )
12196 )
12197 {
12198     if (bus_type & ASC_IS_ISA)
12199         return (ASC_MAX_ISA_DMA_COUNT);
12200     else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
12201         return (ASC_MAX_VL_DMA_COUNT);
12202     return (ASC_MAX_PCI_DMA_COUNT);
12203 }
12204 
12205 #ifdef CONFIG_ISA
ASC_INITFUNC(STATIC ushort,AscGetIsaDmaChannel (PortAddr iop_base))12206 ASC_INITFUNC(
12207 STATIC ushort,
12208 AscGetIsaDmaChannel(
12209                        PortAddr iop_base
12210 )
12211 )
12212 {
12213     ushort              channel;
12214 
12215     channel = AscGetChipCfgLsw(iop_base) & 0x0003;
12216     if (channel == 0x03)
12217         return (0);
12218     else if (channel == 0x00)
12219         return (7);
12220     return (channel + 4);
12221 }
12222 
ASC_INITFUNC(STATIC ushort,AscSetIsaDmaChannel (PortAddr iop_base,ushort dma_channel))12223 ASC_INITFUNC(
12224 STATIC ushort,
12225 AscSetIsaDmaChannel(
12226                        PortAddr iop_base,
12227                        ushort dma_channel
12228 )
12229 )
12230 {
12231     ushort              cfg_lsw;
12232     uchar               value;
12233 
12234     if ((dma_channel >= 5) && (dma_channel <= 7)) {
12235         if (dma_channel == 7)
12236             value = 0x00;
12237         else
12238             value = dma_channel - 4;
12239         cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
12240         cfg_lsw |= value;
12241         AscSetChipCfgLsw(iop_base, cfg_lsw);
12242         return (AscGetIsaDmaChannel(iop_base));
12243     }
12244     return (0);
12245 }
12246 
ASC_INITFUNC(STATIC uchar,AscSetIsaDmaSpeed (PortAddr iop_base,uchar speed_value))12247 ASC_INITFUNC(
12248 STATIC uchar,
12249 AscSetIsaDmaSpeed(
12250                      PortAddr iop_base,
12251                      uchar speed_value
12252 )
12253 )
12254 {
12255     speed_value &= 0x07;
12256     AscSetBank(iop_base, 1);
12257     AscWriteChipDmaSpeed(iop_base, speed_value);
12258     AscSetBank(iop_base, 0);
12259     return (AscGetIsaDmaSpeed(iop_base));
12260 }
12261 
ASC_INITFUNC(STATIC uchar,AscGetIsaDmaSpeed (PortAddr iop_base))12262 ASC_INITFUNC(
12263 STATIC uchar,
12264 AscGetIsaDmaSpeed(
12265                      PortAddr iop_base
12266 )
12267 )
12268 {
12269     uchar               speed_value;
12270 
12271     AscSetBank(iop_base, 1);
12272     speed_value = AscReadChipDmaSpeed(iop_base);
12273     speed_value &= 0x07;
12274     AscSetBank(iop_base, 0);
12275     return (speed_value);
12276 }
12277 #endif /* CONFIG_ISA */
12278 
ASC_INITFUNC(STATIC ushort,AscReadPCIConfigWord (ASC_DVC_VAR * asc_dvc,ushort pci_config_offset))12279 ASC_INITFUNC(
12280 STATIC ushort,
12281 AscReadPCIConfigWord(
12282     ASC_DVC_VAR *asc_dvc,
12283     ushort pci_config_offset)
12284 )
12285 {
12286     uchar       lsb, msb;
12287 
12288     lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
12289     msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
12290     return ((ushort) ((msb << 8) | lsb));
12291 }
12292 
ASC_INITFUNC(STATIC ushort,AscInitGetConfig (ASC_DVC_VAR * asc_dvc))12293 ASC_INITFUNC(
12294 STATIC ushort,
12295 AscInitGetConfig(
12296         ASC_DVC_VAR *asc_dvc
12297 )
12298 )
12299 {
12300     ushort              warn_code;
12301     PortAddr            iop_base;
12302     ushort              PCIDeviceID;
12303     ushort              PCIVendorID;
12304     uchar               PCIRevisionID;
12305     uchar               prevCmdRegBits;
12306 
12307     warn_code = 0;
12308     iop_base = asc_dvc->iop_base;
12309     asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
12310     if (asc_dvc->err_code != 0) {
12311         return (UW_ERR);
12312     }
12313     if (asc_dvc->bus_type == ASC_IS_PCI) {
12314         PCIVendorID = AscReadPCIConfigWord(asc_dvc,
12315                                     AscPCIConfigVendorIDRegister);
12316 
12317         PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
12318                                     AscPCIConfigDeviceIDRegister);
12319 
12320         PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
12321                                     AscPCIConfigRevisionIDRegister);
12322 
12323         if (PCIVendorID != ASC_PCI_VENDORID) {
12324             warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
12325         }
12326         prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
12327                                     AscPCIConfigCommandRegister);
12328 
12329         if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
12330             AscPCICmdRegBits_IOMemBusMaster) {
12331             DvcWritePCIConfigByte(asc_dvc,
12332                             AscPCIConfigCommandRegister,
12333                             (prevCmdRegBits |
12334                              AscPCICmdRegBits_IOMemBusMaster));
12335 
12336             if ((DvcReadPCIConfigByte(asc_dvc,
12337                                 AscPCIConfigCommandRegister)
12338                  & AscPCICmdRegBits_IOMemBusMaster)
12339                 != AscPCICmdRegBits_IOMemBusMaster) {
12340                 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
12341             }
12342         }
12343         if ((PCIDeviceID == ASC_PCI_DEVICEID_1200A) ||
12344             (PCIDeviceID == ASC_PCI_DEVICEID_1200B)) {
12345             DvcWritePCIConfigByte(asc_dvc,
12346                             AscPCIConfigLatencyTimer, 0x00);
12347             if (DvcReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer)
12348                 != 0x00) {
12349                 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
12350             }
12351         } else if (PCIDeviceID == ASC_PCI_DEVICEID_ULTRA) {
12352             if (DvcReadPCIConfigByte(asc_dvc,
12353                                 AscPCIConfigLatencyTimer) < 0x20) {
12354                 DvcWritePCIConfigByte(asc_dvc,
12355                                     AscPCIConfigLatencyTimer, 0x20);
12356 
12357                 if (DvcReadPCIConfigByte(asc_dvc,
12358                                     AscPCIConfigLatencyTimer) < 0x20) {
12359                     warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
12360                 }
12361             }
12362         }
12363     }
12364 
12365     if (AscFindSignature(iop_base)) {
12366         warn_code |= AscInitAscDvcVar(asc_dvc);
12367         warn_code |= AscInitFromEEP(asc_dvc);
12368         asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
12369         if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
12370             asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
12371         }
12372     } else {
12373         asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12374     }
12375     return(warn_code);
12376 }
12377 
ASC_INITFUNC(STATIC ushort,AscInitSetConfig (ASC_DVC_VAR * asc_dvc))12378 ASC_INITFUNC(
12379 STATIC ushort,
12380 AscInitSetConfig(
12381                     ASC_DVC_VAR *asc_dvc
12382 )
12383 )
12384 {
12385     ushort              warn_code = 0;
12386 
12387     asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
12388     if (asc_dvc->err_code != 0)
12389         return (UW_ERR);
12390     if (AscFindSignature(asc_dvc->iop_base)) {
12391         warn_code |= AscInitFromAscDvcVar(asc_dvc);
12392         asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
12393     } else {
12394         asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12395     }
12396     return (warn_code);
12397 }
12398 
ASC_INITFUNC(STATIC ushort,AscInitFromAscDvcVar (ASC_DVC_VAR * asc_dvc))12399 ASC_INITFUNC(
12400 STATIC ushort,
12401 AscInitFromAscDvcVar(
12402                         ASC_DVC_VAR *asc_dvc
12403 )
12404 )
12405 {
12406     PortAddr            iop_base;
12407     ushort              cfg_msw;
12408     ushort              warn_code;
12409     ushort              pci_device_id;
12410 
12411     iop_base = asc_dvc->iop_base;
12412     pci_device_id = asc_dvc->cfg->pci_device_id;
12413     warn_code = 0;
12414     cfg_msw = AscGetChipCfgMsw(iop_base);
12415     if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12416         cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
12417         warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12418         AscSetChipCfgMsw(iop_base, cfg_msw);
12419     }
12420     if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
12421         asc_dvc->cfg->cmd_qng_enabled) {
12422         asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
12423         warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12424     }
12425     if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12426         warn_code |= ASC_WARN_AUTO_CONFIG;
12427     }
12428     if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
12429         if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
12430             != asc_dvc->irq_no) {
12431             asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
12432         }
12433     }
12434     if (asc_dvc->bus_type & ASC_IS_PCI) {
12435         cfg_msw &= 0xFFC0;
12436         AscSetChipCfgMsw(iop_base, cfg_msw);
12437         if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
12438         } else {
12439             if ((pci_device_id == ASC_PCI_DEVICE_ID_REV_A) ||
12440                 (pci_device_id == ASC_PCI_DEVICE_ID_REV_B)) {
12441                 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
12442                 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
12443             }
12444         }
12445     } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
12446         if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
12447             == ASC_CHIP_VER_ASYN_BUG) {
12448             asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
12449         }
12450     }
12451     if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
12452         asc_dvc->cfg->chip_scsi_id) {
12453         asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
12454     }
12455 #ifdef CONFIG_ISA
12456     if (asc_dvc->bus_type & ASC_IS_ISA) {
12457         AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
12458         AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
12459     }
12460 #endif /* CONFIG_ISA */
12461     return (warn_code);
12462 }
12463 
12464 STATIC ushort
AscInitAsc1000Driver(ASC_DVC_VAR * asc_dvc)12465 AscInitAsc1000Driver(
12466                         ASC_DVC_VAR *asc_dvc
12467 )
12468 {
12469     ushort              warn_code;
12470     PortAddr            iop_base;
12471 
12472     iop_base = asc_dvc->iop_base;
12473     warn_code = 0;
12474     if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
12475         !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
12476         AscResetChipAndScsiBus(asc_dvc);
12477         DvcSleepMilliSecond((ASC_DCNT)
12478             ((ushort) asc_dvc->scsi_reset_wait * 1000));
12479     }
12480     asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
12481     if (asc_dvc->err_code != 0)
12482         return (UW_ERR);
12483     if (!AscFindSignature(asc_dvc->iop_base)) {
12484         asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12485         return (warn_code);
12486     }
12487     AscDisableInterrupt(iop_base);
12488     warn_code |= AscInitLram(asc_dvc);
12489     if (asc_dvc->err_code != 0)
12490         return (UW_ERR);
12491     ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
12492         (ulong) _asc_mcode_chksum);
12493     if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
12494                          _asc_mcode_size) != _asc_mcode_chksum) {
12495         asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
12496         return (warn_code);
12497     }
12498     warn_code |= AscInitMicroCodeVar(asc_dvc);
12499     asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
12500     AscEnableInterrupt(iop_base);
12501     return (warn_code);
12502 }
12503 
ASC_INITFUNC(STATIC ushort,AscInitAscDvcVar (ASC_DVC_VAR * asc_dvc))12504 ASC_INITFUNC(
12505 STATIC ushort,
12506 AscInitAscDvcVar(
12507                     ASC_DVC_VAR *asc_dvc
12508 )
12509 )
12510 {
12511     int                 i;
12512     PortAddr            iop_base;
12513     ushort              warn_code;
12514     uchar               chip_version;
12515 
12516     iop_base = asc_dvc->iop_base;
12517     warn_code = 0;
12518     asc_dvc->err_code = 0;
12519     if ((asc_dvc->bus_type &
12520          (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
12521         asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
12522     }
12523     AscSetChipControl(iop_base, CC_HALT);
12524     AscSetChipStatus(iop_base, 0);
12525     asc_dvc->bug_fix_cntl = 0;
12526     asc_dvc->pci_fix_asyn_xfer = 0;
12527     asc_dvc->pci_fix_asyn_xfer_always = 0;
12528     /* asc_dvc->init_state initalized in AscInitGetConfig(). */
12529     asc_dvc->sdtr_done = 0;
12530     asc_dvc->cur_total_qng = 0;
12531     asc_dvc->is_in_int = 0;
12532     asc_dvc->in_critical_cnt = 0;
12533     asc_dvc->last_q_shortage = 0;
12534     asc_dvc->use_tagged_qng = 0;
12535     asc_dvc->no_scam = 0;
12536     asc_dvc->unit_not_ready = 0;
12537     asc_dvc->queue_full_or_busy = 0;
12538     asc_dvc->redo_scam = 0;
12539     asc_dvc->res2 = 0;
12540     asc_dvc->host_init_sdtr_index = 0;
12541     asc_dvc->cfg->can_tagged_qng = 0;
12542     asc_dvc->cfg->cmd_qng_enabled = 0;
12543     asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
12544     asc_dvc->init_sdtr = 0;
12545     asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
12546     asc_dvc->scsi_reset_wait = 3;
12547     asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
12548     asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
12549     asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
12550     asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
12551     asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
12552     asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
12553     asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
12554       ASC_LIB_VERSION_MINOR;
12555     chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
12556     asc_dvc->cfg->chip_version = chip_version;
12557     asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
12558     asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
12559     asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
12560     asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
12561     asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
12562     asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
12563     asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
12564     asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
12565     asc_dvc->max_sdtr_index = 7;
12566     if ((asc_dvc->bus_type & ASC_IS_PCI) &&
12567         (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
12568         asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
12569         asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
12570         asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
12571         asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
12572         asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
12573         asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
12574         asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
12575         asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
12576         asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
12577         asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
12578         asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
12579         asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
12580         asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
12581         asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
12582         asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
12583         asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
12584         asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
12585         asc_dvc->max_sdtr_index = 15;
12586         if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150)
12587         {
12588             AscSetExtraControl(iop_base,
12589                 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
12590         } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
12591             AscSetExtraControl(iop_base,
12592                 (SEC_ACTIVE_NEGATE | SEC_ENABLE_FILTER));
12593         }
12594     }
12595     if (asc_dvc->bus_type == ASC_IS_PCI) {
12596            AscSetExtraControl(iop_base, (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
12597     }
12598 
12599     asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
12600     if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
12601         AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
12602         asc_dvc->bus_type = ASC_IS_ISAPNP;
12603     }
12604 #ifdef CONFIG_ISA
12605     if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
12606         asc_dvc->cfg->isa_dma_channel = (uchar) AscGetIsaDmaChannel(iop_base);
12607     }
12608 #endif /* CONFIG_ISA */
12609     for (i = 0; i <= ASC_MAX_TID; i++) {
12610         asc_dvc->cur_dvc_qng[i] = 0;
12611         asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
12612         asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *) 0L;
12613         asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *) 0L;
12614         asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
12615     }
12616     return (warn_code);
12617 }
12618 
ASC_INITFUNC(STATIC ushort,AscInitFromEEP (ASC_DVC_VAR * asc_dvc))12619 ASC_INITFUNC(
12620 STATIC ushort,
12621 AscInitFromEEP(
12622                   ASC_DVC_VAR *asc_dvc
12623 )
12624 )
12625 {
12626     ASCEEP_CONFIG       eep_config_buf;
12627     ASCEEP_CONFIG       *eep_config;
12628     PortAddr            iop_base;
12629     ushort              chksum;
12630     ushort              warn_code;
12631     ushort              cfg_msw, cfg_lsw;
12632     int                 i;
12633     int                 write_eep = 0;
12634 
12635     iop_base = asc_dvc->iop_base;
12636     warn_code = 0;
12637     AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
12638     AscStopQueueExe(iop_base);
12639     if ((AscStopChip(iop_base) == FALSE) ||
12640         (AscGetChipScsiCtrl(iop_base) != 0)) {
12641         asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
12642         AscResetChipAndScsiBus(asc_dvc);
12643         DvcSleepMilliSecond((ASC_DCNT)
12644             ((ushort) asc_dvc->scsi_reset_wait * 1000));
12645     }
12646     if (AscIsChipHalted(iop_base) == FALSE) {
12647         asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
12648         return (warn_code);
12649     }
12650     AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
12651     if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
12652         asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
12653         return (warn_code);
12654     }
12655     eep_config = (ASCEEP_CONFIG *) &eep_config_buf;
12656     cfg_msw = AscGetChipCfgMsw(iop_base);
12657     cfg_lsw = AscGetChipCfgLsw(iop_base);
12658     if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12659         cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
12660         warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12661         AscSetChipCfgMsw(iop_base, cfg_msw);
12662     }
12663     chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
12664     ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
12665     if (chksum == 0) {
12666         chksum = 0xaa55;
12667     }
12668     if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12669         warn_code |= ASC_WARN_AUTO_CONFIG;
12670         if (asc_dvc->cfg->chip_version == 3) {
12671             if (eep_config->cfg_lsw != cfg_lsw) {
12672                 warn_code |= ASC_WARN_EEPROM_RECOVER;
12673                 eep_config->cfg_lsw = AscGetChipCfgLsw(iop_base);
12674             }
12675             if (eep_config->cfg_msw != cfg_msw) {
12676                 warn_code |= ASC_WARN_EEPROM_RECOVER;
12677                 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
12678             }
12679         }
12680     }
12681     eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
12682     eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
12683     ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
12684         eep_config->chksum);
12685     if (chksum != eep_config->chksum) {
12686             if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
12687                     ASC_CHIP_VER_PCI_ULTRA_3050 )
12688             {
12689                 ASC_DBG(1,
12690 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
12691                 eep_config->init_sdtr = 0xFF;
12692                 eep_config->disc_enable = 0xFF;
12693                 eep_config->start_motor = 0xFF;
12694                 eep_config->use_cmd_qng = 0;
12695                 eep_config->max_total_qng = 0xF0;
12696                 eep_config->max_tag_qng = 0x20;
12697                 eep_config->cntl = 0xBFFF;
12698                 ASC_EEP_SET_CHIP_ID(eep_config, 7);
12699                 eep_config->no_scam = 0;
12700                 eep_config->adapter_info[0] = 0;
12701                 eep_config->adapter_info[1] = 0;
12702                 eep_config->adapter_info[2] = 0;
12703                 eep_config->adapter_info[3] = 0;
12704                 eep_config->adapter_info[4] = 0;
12705                 /* Indicate EEPROM-less board. */
12706                 eep_config->adapter_info[5] = 0xBB;
12707             } else {
12708                 ASC_PRINT(
12709 "AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
12710                 write_eep = 1;
12711                 warn_code |= ASC_WARN_EEPROM_CHKSUM;
12712             }
12713     }
12714     asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
12715     asc_dvc->cfg->disc_enable = eep_config->disc_enable;
12716     asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
12717     asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
12718     asc_dvc->start_motor = eep_config->start_motor;
12719     asc_dvc->dvc_cntl = eep_config->cntl;
12720     asc_dvc->no_scam = eep_config->no_scam;
12721     asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
12722     asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
12723     asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
12724     asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
12725     asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
12726     asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
12727     if (!AscTestExternalLram(asc_dvc)) {
12728         if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA)) {
12729             eep_config->max_total_qng = ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
12730             eep_config->max_tag_qng = ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
12731         } else {
12732             eep_config->cfg_msw |= 0x0800;
12733             cfg_msw |= 0x0800;
12734             AscSetChipCfgMsw(iop_base, cfg_msw);
12735             eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
12736             eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
12737         }
12738     } else {
12739     }
12740     if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
12741         eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
12742     }
12743     if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
12744         eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
12745     }
12746     if (eep_config->max_tag_qng > eep_config->max_total_qng) {
12747         eep_config->max_tag_qng = eep_config->max_total_qng;
12748     }
12749     if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
12750         eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
12751     }
12752     asc_dvc->max_total_qng = eep_config->max_total_qng;
12753     if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
12754         eep_config->use_cmd_qng) {
12755         eep_config->disc_enable = eep_config->use_cmd_qng;
12756         warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12757     }
12758     if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
12759         asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
12760     }
12761     ASC_EEP_SET_CHIP_ID(eep_config, ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
12762     asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
12763     if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
12764         !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
12765         asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
12766     }
12767 
12768     for (i = 0; i <= ASC_MAX_TID; i++) {
12769         asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
12770         asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
12771         asc_dvc->cfg->sdtr_period_offset[i] =
12772             (uchar) (ASC_DEF_SDTR_OFFSET |
12773                      (asc_dvc->host_init_sdtr_index << 4));
12774     }
12775     eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
12776     if (write_eep) {
12777         if ((i = AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type)) !=
12778              0) {
12779                 ASC_PRINT1(
12780 "AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n", i);
12781         } else {
12782                 ASC_PRINT("AscInitFromEEP: Succesfully re-wrote EEPROM.");
12783         }
12784     }
12785     return (warn_code);
12786 }
12787 
12788 STATIC ushort
AscInitMicroCodeVar(ASC_DVC_VAR * asc_dvc)12789 AscInitMicroCodeVar(
12790                        ASC_DVC_VAR *asc_dvc
12791 )
12792 {
12793     int                 i;
12794     ushort              warn_code;
12795     PortAddr            iop_base;
12796     ASC_PADDR           phy_addr;
12797     ASC_DCNT            phy_size;
12798 
12799     iop_base = asc_dvc->iop_base;
12800     warn_code = 0;
12801     for (i = 0; i <= ASC_MAX_TID; i++) {
12802         AscPutMCodeInitSDTRAtID(iop_base, i,
12803                                 asc_dvc->cfg->sdtr_period_offset[i]
12804 );
12805     }
12806 
12807     AscInitQLinkVar(asc_dvc);
12808     AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
12809                      asc_dvc->cfg->disc_enable);
12810     AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
12811                      ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
12812 
12813     /* Align overrun buffer on an 8 byte boundary. */
12814     phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
12815     phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
12816     AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
12817         (uchar *) &phy_addr, 1);
12818     phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
12819     AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
12820         (uchar *) &phy_size, 1);
12821 
12822     asc_dvc->cfg->mcode_date =
12823         AscReadLramWord(iop_base, (ushort) ASCV_MC_DATE_W);
12824     asc_dvc->cfg->mcode_version =
12825         AscReadLramWord(iop_base, (ushort) ASCV_MC_VER_W);
12826 
12827     AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
12828     if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
12829         asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
12830         return (warn_code);
12831     }
12832     if (AscStartChip(iop_base) != 1) {
12833         asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
12834         return (warn_code);
12835     }
12836 
12837     return (warn_code);
12838 }
12839 
ASC_INITFUNC(STATIC int,AscTestExternalLram (ASC_DVC_VAR * asc_dvc))12840 ASC_INITFUNC(
12841 STATIC int,
12842 AscTestExternalLram(
12843                        ASC_DVC_VAR *asc_dvc
12844 )
12845 )
12846 {
12847     PortAddr            iop_base;
12848     ushort              q_addr;
12849     ushort              saved_word;
12850     int                 sta;
12851 
12852     iop_base = asc_dvc->iop_base;
12853     sta = 0;
12854     q_addr = ASC_QNO_TO_QADDR(241);
12855     saved_word = AscReadLramWord(iop_base, q_addr);
12856     AscSetChipLramAddr(iop_base, q_addr);
12857     AscSetChipLramData(iop_base, 0x55AA);
12858     DvcSleepMilliSecond(10);
12859     AscSetChipLramAddr(iop_base, q_addr);
12860     if (AscGetChipLramData(iop_base) == 0x55AA) {
12861         sta = 1;
12862         AscWriteLramWord(iop_base, q_addr, saved_word);
12863     }
12864     return (sta);
12865 }
12866 
ASC_INITFUNC(STATIC int,AscWriteEEPCmdReg (PortAddr iop_base,uchar cmd_reg))12867 ASC_INITFUNC(
12868 STATIC int,
12869 AscWriteEEPCmdReg(
12870                      PortAddr iop_base,
12871                      uchar cmd_reg
12872 )
12873 )
12874 {
12875     uchar               read_back;
12876     int                 retry;
12877 
12878     retry = 0;
12879     while (TRUE) {
12880         AscSetChipEEPCmd(iop_base, cmd_reg);
12881         DvcSleepMilliSecond(1);
12882         read_back = AscGetChipEEPCmd(iop_base);
12883         if (read_back == cmd_reg) {
12884             return (1);
12885         }
12886         if (retry++ > ASC_EEP_MAX_RETRY) {
12887             return (0);
12888         }
12889     }
12890 }
12891 
ASC_INITFUNC(STATIC int,AscWriteEEPDataReg (PortAddr iop_base,ushort data_reg))12892 ASC_INITFUNC(
12893 STATIC int,
12894 AscWriteEEPDataReg(
12895                       PortAddr iop_base,
12896                       ushort data_reg
12897 )
12898 )
12899 {
12900     ushort              read_back;
12901     int                 retry;
12902 
12903     retry = 0;
12904     while (TRUE) {
12905         AscSetChipEEPData(iop_base, data_reg);
12906         DvcSleepMilliSecond(1);
12907         read_back = AscGetChipEEPData(iop_base);
12908         if (read_back == data_reg) {
12909             return (1);
12910         }
12911         if (retry++ > ASC_EEP_MAX_RETRY) {
12912             return (0);
12913         }
12914     }
12915 }
12916 
ASC_INITFUNC(STATIC void,AscWaitEEPRead (void))12917 ASC_INITFUNC(
12918 STATIC void,
12919 AscWaitEEPRead(
12920                   void
12921 )
12922 )
12923 {
12924     DvcSleepMilliSecond(1);
12925     return;
12926 }
12927 
ASC_INITFUNC(STATIC void,AscWaitEEPWrite (void))12928 ASC_INITFUNC(
12929 STATIC void,
12930 AscWaitEEPWrite(
12931                    void
12932 )
12933 )
12934 {
12935     DvcSleepMilliSecond(20);
12936     return;
12937 }
12938 
ASC_INITFUNC(STATIC ushort,AscReadEEPWord (PortAddr iop_base,uchar addr))12939 ASC_INITFUNC(
12940 STATIC ushort,
12941 AscReadEEPWord(
12942                   PortAddr iop_base,
12943                   uchar addr
12944 )
12945 )
12946 {
12947     ushort              read_wval;
12948     uchar               cmd_reg;
12949 
12950     AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
12951     AscWaitEEPRead();
12952     cmd_reg = addr | ASC_EEP_CMD_READ;
12953     AscWriteEEPCmdReg(iop_base, cmd_reg);
12954     AscWaitEEPRead();
12955     read_wval = AscGetChipEEPData(iop_base);
12956     AscWaitEEPRead();
12957     return (read_wval);
12958 }
12959 
ASC_INITFUNC(STATIC ushort,AscWriteEEPWord (PortAddr iop_base,uchar addr,ushort word_val))12960 ASC_INITFUNC(
12961 STATIC ushort,
12962 AscWriteEEPWord(
12963                    PortAddr iop_base,
12964                    uchar addr,
12965                    ushort word_val
12966 )
12967 )
12968 {
12969     ushort              read_wval;
12970 
12971     read_wval = AscReadEEPWord(iop_base, addr);
12972     if (read_wval != word_val) {
12973         AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
12974         AscWaitEEPRead();
12975         AscWriteEEPDataReg(iop_base, word_val);
12976         AscWaitEEPRead();
12977         AscWriteEEPCmdReg(iop_base,
12978                           (uchar) ((uchar) ASC_EEP_CMD_WRITE | addr));
12979         AscWaitEEPWrite();
12980         AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
12981         AscWaitEEPRead();
12982         return (AscReadEEPWord(iop_base, addr));
12983     }
12984     return (read_wval);
12985 }
12986 
ASC_INITFUNC(STATIC ushort,AscGetEEPConfig (PortAddr iop_base,ASCEEP_CONFIG * cfg_buf,ushort bus_type))12987 ASC_INITFUNC(
12988 STATIC ushort,
12989 AscGetEEPConfig(
12990                    PortAddr iop_base,
12991                    ASCEEP_CONFIG * cfg_buf, ushort bus_type
12992 )
12993 )
12994 {
12995     ushort              wval;
12996     ushort              sum;
12997     ushort              *wbuf;
12998     int                 cfg_beg;
12999     int                 cfg_end;
13000     int                 uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
13001     int                 s_addr;
13002 
13003     wbuf = (ushort *) cfg_buf;
13004     sum = 0;
13005     /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
13006     for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
13007         *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
13008         sum += *wbuf;
13009     }
13010     if (bus_type & ASC_IS_VL) {
13011         cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
13012         cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
13013     } else {
13014         cfg_beg = ASC_EEP_DVC_CFG_BEG;
13015         cfg_end = ASC_EEP_MAX_DVC_ADDR;
13016     }
13017     for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
13018         wval = AscReadEEPWord( iop_base, ( uchar )s_addr ) ;
13019         if (s_addr <= uchar_end_in_config) {
13020             /*
13021              * Swap all char fields - must unswap bytes already swapped
13022              * by AscReadEEPWord().
13023              */
13024             *wbuf = le16_to_cpu(wval);
13025         } else {
13026             /* Don't swap word field at the end - cntl field. */
13027             *wbuf = wval;
13028         }
13029         sum += wval; /* Checksum treats all EEPROM data as words. */
13030     }
13031     /*
13032      * Read the checksum word which will be compared against 'sum'
13033      * by the caller. Word field already swapped.
13034      */
13035     *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
13036     return (sum);
13037 }
13038 
ASC_INITFUNC(STATIC int,AscSetEEPConfigOnce (PortAddr iop_base,ASCEEP_CONFIG * cfg_buf,ushort bus_type))13039 ASC_INITFUNC(
13040 STATIC int,
13041 AscSetEEPConfigOnce(
13042                        PortAddr iop_base,
13043                        ASCEEP_CONFIG * cfg_buf, ushort bus_type
13044 )
13045 )
13046 {
13047     int                 n_error;
13048     ushort              *wbuf;
13049     ushort              word;
13050     ushort              sum;
13051     int                 s_addr;
13052     int                 cfg_beg;
13053     int                 cfg_end;
13054     int                 uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
13055 
13056 
13057     wbuf = (ushort *) cfg_buf;
13058     n_error = 0;
13059     sum = 0;
13060     /* Write two config words; AscWriteEEPWord() will swap bytes. */
13061     for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
13062         sum += *wbuf;
13063         if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
13064             n_error++;
13065         }
13066     }
13067     if (bus_type & ASC_IS_VL) {
13068         cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
13069         cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
13070     } else {
13071         cfg_beg = ASC_EEP_DVC_CFG_BEG;
13072         cfg_end = ASC_EEP_MAX_DVC_ADDR;
13073     }
13074     for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
13075         if (s_addr <= uchar_end_in_config) {
13076             /*
13077              * This is a char field. Swap char fields before they are
13078              * swapped again by AscWriteEEPWord().
13079              */
13080             word = cpu_to_le16(*wbuf);
13081             if (word != AscWriteEEPWord( iop_base, (uchar) s_addr, word)) {
13082                 n_error++;
13083             }
13084         } else {
13085             /* Don't swap word field at the end - cntl field. */
13086             if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
13087                 n_error++;
13088             }
13089         }
13090         sum += *wbuf; /* Checksum calculated from word values. */
13091     }
13092     /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
13093     *wbuf = sum;
13094     if (sum != AscWriteEEPWord(iop_base, (uchar) s_addr, sum)) {
13095         n_error++;
13096     }
13097 
13098     /* Read EEPROM back again. */
13099     wbuf = (ushort *) cfg_buf;
13100     /*
13101      * Read two config words; Byte-swapping done by AscReadEEPWord().
13102      */
13103     for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
13104         if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
13105             n_error++;
13106         }
13107     }
13108     if (bus_type & ASC_IS_VL) {
13109         cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
13110         cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
13111     } else {
13112         cfg_beg = ASC_EEP_DVC_CFG_BEG;
13113         cfg_end = ASC_EEP_MAX_DVC_ADDR;
13114     }
13115     for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
13116         if (s_addr <= uchar_end_in_config) {
13117             /*
13118              * Swap all char fields. Must unswap bytes already swapped
13119              * by AscReadEEPWord().
13120              */
13121             word = le16_to_cpu(AscReadEEPWord(iop_base, (uchar) s_addr));
13122         } else {
13123             /* Don't swap word field at the end - cntl field. */
13124             word = AscReadEEPWord(iop_base, (uchar) s_addr);
13125         }
13126         if (*wbuf != word) {
13127             n_error++;
13128         }
13129     }
13130     /* Read checksum; Byte swapping not needed. */
13131     if (AscReadEEPWord(iop_base, (uchar) s_addr) != sum) {
13132         n_error++;
13133     }
13134     return (n_error);
13135 }
13136 
ASC_INITFUNC(STATIC int,AscSetEEPConfig (PortAddr iop_base,ASCEEP_CONFIG * cfg_buf,ushort bus_type))13137 ASC_INITFUNC(
13138 STATIC int,
13139 AscSetEEPConfig(
13140                    PortAddr iop_base,
13141                    ASCEEP_CONFIG * cfg_buf, ushort bus_type
13142 )
13143 )
13144 {
13145     int            retry;
13146     int            n_error;
13147 
13148     retry = 0;
13149     while (TRUE) {
13150         if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
13151                                            bus_type)) == 0) {
13152             break;
13153         }
13154         if (++retry > ASC_EEP_MAX_RETRY) {
13155             break;
13156         }
13157     }
13158     return (n_error);
13159 }
13160 
13161 STATIC void
AscAsyncFix(ASC_DVC_VAR * asc_dvc,uchar tid_no,ASC_SCSI_INQUIRY * inq)13162 AscAsyncFix(
13163                ASC_DVC_VAR *asc_dvc,
13164                uchar tid_no,
13165                ASC_SCSI_INQUIRY *inq)
13166 {
13167     uchar                       dvc_type;
13168     ASC_SCSI_BIT_ID_TYPE        tid_bits;
13169 
13170     dvc_type = ASC_INQ_DVC_TYPE(inq);
13171     tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
13172 
13173     if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN)
13174     {
13175         if (!(asc_dvc->init_sdtr & tid_bits))
13176         {
13177             if ((dvc_type == SCSI_TYPE_CDROM) &&
13178                 (AscCompareString((uchar *) inq->vendor_id,
13179                     (uchar *) "HP ", 3) == 0))
13180             {
13181                 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
13182             }
13183             asc_dvc->pci_fix_asyn_xfer |= tid_bits;
13184             if ((dvc_type == SCSI_TYPE_PROC) ||
13185                 (dvc_type == SCSI_TYPE_SCANNER) ||
13186                 (dvc_type == SCSI_TYPE_CDROM) ||
13187                 (dvc_type == SCSI_TYPE_SASD))
13188             {
13189                 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
13190             }
13191 
13192             if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
13193             {
13194                 AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no,
13195                     ASYN_SDTR_DATA_FIX_PCI_REV_AB);
13196             }
13197         }
13198     }
13199     return;
13200 }
13201 
13202 STATIC int
AscTagQueuingSafe(ASC_SCSI_INQUIRY * inq)13203 AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
13204 {
13205     if ((inq->add_len >= 32) &&
13206         (AscCompareString((uchar *) inq->vendor_id,
13207             (uchar *) "QUANTUM XP34301", 15) == 0) &&
13208         (AscCompareString((uchar *) inq->product_rev_level,
13209             (uchar *) "1071", 4) == 0))
13210     {
13211         return 0;
13212     }
13213     return 1;
13214 }
13215 
13216 STATIC void
AscInquiryHandling(ASC_DVC_VAR * asc_dvc,uchar tid_no,ASC_SCSI_INQUIRY * inq)13217 AscInquiryHandling(ASC_DVC_VAR *asc_dvc,
13218                    uchar tid_no, ASC_SCSI_INQUIRY *inq)
13219 {
13220     ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
13221     ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
13222 
13223     orig_init_sdtr = asc_dvc->init_sdtr;
13224     orig_use_tagged_qng = asc_dvc->use_tagged_qng;
13225 
13226     asc_dvc->init_sdtr &= ~tid_bit;
13227     asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
13228     asc_dvc->use_tagged_qng &= ~tid_bit;
13229 
13230     if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) {
13231         if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) {
13232             asc_dvc->init_sdtr |= tid_bit;
13233         }
13234         if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) &&
13235              ASC_INQ_CMD_QUEUE(inq)) {
13236             if (AscTagQueuingSafe(inq)) {
13237                 asc_dvc->use_tagged_qng |= tid_bit;
13238                 asc_dvc->cfg->can_tagged_qng |= tid_bit;
13239             }
13240         }
13241     }
13242     if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
13243         AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
13244                          asc_dvc->cfg->disc_enable);
13245         AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
13246                          asc_dvc->use_tagged_qng);
13247         AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
13248                          asc_dvc->cfg->can_tagged_qng);
13249 
13250         asc_dvc->max_dvc_qng[tid_no] =
13251           asc_dvc->cfg->max_tag_qng[tid_no];
13252         AscWriteLramByte(asc_dvc->iop_base,
13253                          (ushort) (ASCV_MAX_DVC_QNG_BEG + tid_no),
13254                          asc_dvc->max_dvc_qng[tid_no]);
13255     }
13256     if (orig_init_sdtr != asc_dvc->init_sdtr) {
13257         AscAsyncFix(asc_dvc, tid_no, inq);
13258     }
13259     return;
13260 }
13261 
13262 STATIC int
AscCompareString(uchar * str1,uchar * str2,int len)13263 AscCompareString(
13264                     uchar *str1,
13265                     uchar *str2,
13266                     int len
13267 )
13268 {
13269     int                 i;
13270     int                 diff;
13271 
13272     for (i = 0; i < len; i++) {
13273         diff = (int) (str1[i] - str2[i]);
13274         if (diff != 0)
13275             return (diff);
13276     }
13277     return (0);
13278 }
13279 
13280 STATIC uchar
AscReadLramByte(PortAddr iop_base,ushort addr)13281 AscReadLramByte(
13282                    PortAddr iop_base,
13283                    ushort addr
13284 )
13285 {
13286     uchar               byte_data;
13287     ushort              word_data;
13288 
13289     if (isodd_word(addr)) {
13290         AscSetChipLramAddr(iop_base, addr - 1);
13291         word_data = AscGetChipLramData(iop_base);
13292         byte_data = (uchar) ((word_data >> 8) & 0xFF);
13293     } else {
13294         AscSetChipLramAddr(iop_base, addr);
13295         word_data = AscGetChipLramData(iop_base);
13296         byte_data = (uchar) (word_data & 0xFF);
13297     }
13298     return (byte_data);
13299 }
13300 STATIC ushort
AscReadLramWord(PortAddr iop_base,ushort addr)13301 AscReadLramWord(
13302                    PortAddr iop_base,
13303                    ushort addr
13304 )
13305 {
13306     ushort              word_data;
13307 
13308     AscSetChipLramAddr(iop_base, addr);
13309     word_data = AscGetChipLramData(iop_base);
13310     return (word_data);
13311 }
13312 
13313 #if CC_VERY_LONG_SG_LIST
13314 STATIC ASC_DCNT
AscReadLramDWord(PortAddr iop_base,ushort addr)13315 AscReadLramDWord(
13316                     PortAddr iop_base,
13317                     ushort addr
13318 )
13319 {
13320     ushort              val_low, val_high;
13321     ASC_DCNT            dword_data;
13322 
13323     AscSetChipLramAddr(iop_base, addr);
13324     val_low = AscGetChipLramData(iop_base);
13325     val_high = AscGetChipLramData(iop_base);
13326     dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
13327     return (dword_data);
13328 }
13329 #endif /* CC_VERY_LONG_SG_LIST */
13330 
13331 STATIC void
AscWriteLramWord(PortAddr iop_base,ushort addr,ushort word_val)13332 AscWriteLramWord(
13333                     PortAddr iop_base,
13334                     ushort addr,
13335                     ushort word_val
13336 )
13337 {
13338     AscSetChipLramAddr(iop_base, addr);
13339     AscSetChipLramData(iop_base, word_val);
13340     return;
13341 }
13342 
13343 STATIC void
AscWriteLramByte(PortAddr iop_base,ushort addr,uchar byte_val)13344 AscWriteLramByte(
13345                     PortAddr iop_base,
13346                     ushort addr,
13347                     uchar byte_val
13348 )
13349 {
13350     ushort              word_data;
13351 
13352     if (isodd_word(addr)) {
13353         addr--;
13354         word_data = AscReadLramWord(iop_base, addr);
13355         word_data &= 0x00FF;
13356         word_data |= (((ushort) byte_val << 8) & 0xFF00);
13357     } else {
13358         word_data = AscReadLramWord(iop_base, addr);
13359         word_data &= 0xFF00;
13360         word_data |= ((ushort) byte_val & 0x00FF);
13361     }
13362     AscWriteLramWord(iop_base, addr, word_data);
13363     return;
13364 }
13365 
13366 /*
13367  * Copy 2 bytes to LRAM.
13368  *
13369  * The source data is assumed to be in little-endian order in memory
13370  * and is maintained in little-endian order when written to LRAM.
13371  */
13372 STATIC void
AscMemWordCopyPtrToLram(PortAddr iop_base,ushort s_addr,uchar * s_buffer,int words)13373 AscMemWordCopyPtrToLram(
13374                         PortAddr iop_base,
13375                         ushort s_addr,
13376                         uchar *s_buffer,
13377                         int words
13378 )
13379 {
13380     int    i;
13381 
13382     AscSetChipLramAddr(iop_base, s_addr);
13383     for (i = 0; i < 2 * words; i += 2) {
13384         /*
13385          * On a little-endian system the second argument below
13386          * produces a little-endian ushort which is written to
13387          * LRAM in little-endian order. On a big-endian system
13388          * the second argument produces a big-endian ushort which
13389          * is "transparently" byte-swapped by outpw() and written
13390          * in little-endian order to LRAM.
13391          */
13392         outpw(iop_base + IOP_RAM_DATA,
13393             ((ushort) s_buffer[i + 1] << 8) | s_buffer[i]);
13394     }
13395     return;
13396 }
13397 
13398 /*
13399  * Copy 4 bytes to LRAM.
13400  *
13401  * The source data is assumed to be in little-endian order in memory
13402  * and is maintained in little-endian order when writen to LRAM.
13403  */
13404 STATIC void
AscMemDWordCopyPtrToLram(PortAddr iop_base,ushort s_addr,uchar * s_buffer,int dwords)13405 AscMemDWordCopyPtrToLram(
13406                          PortAddr iop_base,
13407                          ushort s_addr,
13408                          uchar *s_buffer,
13409                          int dwords
13410 )
13411 {
13412     int       i;
13413 
13414     AscSetChipLramAddr(iop_base, s_addr);
13415     for (i = 0; i < 4 * dwords; i += 4) {
13416         outpw(iop_base + IOP_RAM_DATA,
13417             ((ushort) s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
13418         outpw(iop_base + IOP_RAM_DATA,
13419             ((ushort) s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
13420     }
13421     return;
13422 }
13423 
13424 /*
13425  * Copy 2 bytes from LRAM.
13426  *
13427  * The source data is assumed to be in little-endian order in LRAM
13428  * and is maintained in little-endian order when written to memory.
13429  */
13430 STATIC void
AscMemWordCopyPtrFromLram(PortAddr iop_base,ushort s_addr,uchar * d_buffer,int words)13431 AscMemWordCopyPtrFromLram(
13432                           PortAddr iop_base,
13433                           ushort s_addr,
13434                           uchar *d_buffer,
13435                           int words
13436 )
13437 {
13438     int i;
13439     ushort word;
13440 
13441     AscSetChipLramAddr(iop_base, s_addr);
13442     for (i = 0; i < 2 * words; i += 2) {
13443         word = inpw(iop_base + IOP_RAM_DATA);
13444         d_buffer[i] = word & 0xff;
13445         d_buffer[i + 1] = (word >> 8) & 0xff;
13446     }
13447     return;
13448 }
13449 
13450 STATIC ASC_DCNT
AscMemSumLramWord(PortAddr iop_base,ushort s_addr,int words)13451 AscMemSumLramWord(
13452                      PortAddr iop_base,
13453                      ushort s_addr,
13454                      int words
13455 )
13456 {
13457     ASC_DCNT         sum;
13458     int              i;
13459 
13460     sum = 0L;
13461     for (i = 0; i < words; i++, s_addr += 2) {
13462         sum += AscReadLramWord(iop_base, s_addr);
13463     }
13464     return (sum);
13465 }
13466 
13467 STATIC void
AscMemWordSetLram(PortAddr iop_base,ushort s_addr,ushort set_wval,int words)13468 AscMemWordSetLram(
13469                      PortAddr iop_base,
13470                      ushort s_addr,
13471                      ushort set_wval,
13472                      int words
13473 )
13474 {
13475     int             i;
13476 
13477     AscSetChipLramAddr(iop_base, s_addr);
13478     for (i = 0; i < words; i++) {
13479         AscSetChipLramData(iop_base, set_wval);
13480     }
13481     return;
13482 }
13483 
13484 
13485 /*
13486  * --- Adv Library Functions
13487  */
13488 
13489 /* a_mcode.h */
13490 
13491 /* Microcode buffer is kept after initialization for error recovery. */
13492 STATIC unsigned char _adv_asc3550_buf[] = {
13493   0x00,  0x00,  0x00,  0xf2,  0x00,  0xf0,  0x00,  0x16,  0x18,  0xe4,  0x00,  0xfc,  0x01,  0x00,  0x48,  0xe4,
13494   0xbe,  0x18,  0x18,  0x80,  0x03,  0xf6,  0x02,  0x00,  0x00,  0xfa,  0xff,  0xff,  0x28,  0x0e,  0x9e,  0xe7,
13495   0xff,  0x00,  0x82,  0xe7,  0x00,  0xea,  0x00,  0xf6,  0x01,  0xe6,  0x09,  0xe7,  0x55,  0xf0,  0x01,  0xf6,
13496   0x01,  0xfa,  0x08,  0x00,  0x03,  0x00,  0x04,  0x00,  0x18,  0xf4,  0x10,  0x00,  0x00,  0xec,  0x85,  0xf0,
13497   0xbc,  0x00,  0xd5,  0xf0,  0x8e,  0x0c,  0x38,  0x54,  0x00,  0xe6,  0x1e,  0xf0,  0x86,  0xf0,  0xb4,  0x00,
13498   0x98,  0x57,  0xd0,  0x01,  0x0c,  0x1c,  0x3e,  0x1c,  0x0c,  0x00,  0xbb,  0x00,  0xaa,  0x18,  0x02,  0x80,
13499   0x32,  0xf0,  0x01,  0xfc,  0x88,  0x0c,  0xc6,  0x12,  0x02,  0x13,  0x18,  0x40,  0x00,  0x57,  0x01,  0xea,
13500   0x3c,  0x00,  0x6c,  0x01,  0x6e,  0x01,  0x04,  0x12,  0x3e,  0x57,  0x00,  0x80,  0x03,  0xe6,  0xb6,  0x00,
13501   0xc0,  0x00,  0x01,  0x01,  0x3e,  0x01,  0xda,  0x0f,  0x22,  0x10,  0x08,  0x12,  0x02,  0x4a,  0xb9,  0x54,
13502   0x03,  0x58,  0x1b,  0x80,  0x30,  0xe4,  0x4b,  0xe4,  0x20,  0x00,  0x32,  0x00,  0x3e,  0x00,  0x80,  0x00,
13503   0x24,  0x01,  0x3c,  0x01,  0x68,  0x01,  0x6a,  0x01,  0x70,  0x01,  0x72,  0x01,  0x74,  0x01,  0x76,  0x01,
13504   0x78,  0x01,  0x62,  0x0a,  0x92,  0x0c,  0x2c,  0x10,  0x2e,  0x10,  0x06,  0x13,  0x4c,  0x1c,  0xbb,  0x55,
13505   0x3c,  0x56,  0x04,  0x80,  0x4a,  0xe4,  0x02,  0xee,  0x5b,  0xf0,  0xb1,  0xf0,  0x03,  0xf7,  0x06,  0xf7,
13506   0x03,  0xfc,  0x0f,  0x00,  0x40,  0x00,  0xbe,  0x00,  0x00,  0x01,  0xb0,  0x08,  0x30,  0x13,  0x64,  0x15,
13507   0x32,  0x1c,  0x38,  0x1c,  0x4e,  0x1c,  0x10,  0x44,  0x02,  0x48,  0x00,  0x4c,  0x04,  0xea,  0x5d,  0xf0,
13508   0x04,  0xf6,  0x02,  0xfc,  0x05,  0x00,  0x34,  0x00,  0x36,  0x00,  0x98,  0x00,  0xcc,  0x00,  0x20,  0x01,
13509   0x4e,  0x01,  0x4e,  0x0b,  0x1e,  0x0e,  0x0c,  0x10,  0x0a,  0x12,  0x04,  0x13,  0x40,  0x13,  0x30,  0x1c,
13510   0x00,  0x4e,  0xbd,  0x56,  0x06,  0x83,  0x00,  0xdc,  0x05,  0xf0,  0x09,  0xf0,  0x59,  0xf0,  0xa7,  0xf0,
13511   0xb8,  0xf0,  0x0e,  0xf7,  0x06,  0x00,  0x19,  0x00,  0x33,  0x00,  0x9b,  0x00,  0xa4,  0x00,  0xb5,  0x00,
13512   0xba,  0x00,  0xd0,  0x00,  0xe1,  0x00,  0xe7,  0x00,  0xde,  0x03,  0x56,  0x0a,  0x14,  0x0e,  0x02,  0x10,
13513   0x04,  0x10,  0x0a,  0x10,  0x36,  0x10,  0x0a,  0x13,  0x12,  0x13,  0x52,  0x13,  0x10,  0x15,  0x14,  0x15,
13514   0xac,  0x16,  0x20,  0x1c,  0x34,  0x1c,  0x36,  0x1c,  0x08,  0x44,  0x38,  0x44,  0x91,  0x44,  0x0a,  0x45,
13515   0x48,  0x46,  0x01,  0x48,  0x68,  0x54,  0x83,  0x55,  0xb0,  0x57,  0x01,  0x58,  0x83,  0x59,  0x05,  0xe6,
13516   0x0b,  0xf0,  0x0c,  0xf0,  0x5c,  0xf0,  0x4b,  0xf4,  0x04,  0xf8,  0x05,  0xf8,  0x02,  0xfa,  0x03,  0xfa,
13517   0x04,  0xfc,  0x05,  0xfc,  0x07,  0x00,  0x0a,  0x00,  0x0d,  0x00,  0x1c,  0x00,  0x9e,  0x00,  0xa8,  0x00,
13518   0xaa,  0x00,  0xb9,  0x00,  0xe0,  0x00,  0x22,  0x01,  0x26,  0x01,  0x79,  0x01,  0x7a,  0x01,  0xc0,  0x01,
13519   0xc2,  0x01,  0x7c,  0x02,  0x5a,  0x03,  0xea,  0x04,  0xe8,  0x07,  0x68,  0x08,  0x69,  0x08,  0xba,  0x08,
13520   0xe9,  0x09,  0x06,  0x0b,  0x3a,  0x0e,  0x00,  0x10,  0x1a,  0x10,  0xed,  0x10,  0xf1,  0x10,  0x06,  0x12,
13521   0x0c,  0x13,  0x16,  0x13,  0x1e,  0x13,  0x82,  0x13,  0x42,  0x14,  0xd6,  0x14,  0x8a,  0x15,  0xc6,  0x17,
13522   0xd2,  0x17,  0x6b,  0x18,  0x12,  0x1c,  0x46,  0x1c,  0x9c,  0x32,  0x00,  0x40,  0x0e,  0x47,  0x48,  0x47,
13523   0x41,  0x48,  0x89,  0x48,  0x80,  0x4c,  0x00,  0x54,  0x44,  0x55,  0xe5,  0x55,  0x14,  0x56,  0x77,  0x57,
13524   0xbf,  0x57,  0x40,  0x5c,  0x06,  0x80,  0x08,  0x90,  0x03,  0xa1,  0xfe,  0x9c,  0xf0,  0x29,  0x02,  0xfe,
13525   0xb8,  0x0c,  0xff,  0x10,  0x00,  0x00,  0xd0,  0xfe,  0xcc,  0x18,  0x00,  0xcf,  0xfe,  0x80,  0x01,  0xff,
13526   0x03,  0x00,  0x00,  0xfe,  0x93,  0x15,  0xfe,  0x0f,  0x05,  0xff,  0x38,  0x00,  0x00,  0xfe,  0x57,  0x24,
13527   0x00,  0xfe,  0x48,  0x00,  0x4f,  0xff,  0x04,  0x00,  0x00,  0x10,  0xff,  0x09,  0x00,  0x00,  0xff,  0x08,
13528   0x01,  0x01,  0xff,  0x08,  0xff,  0xff,  0xff,  0x27,  0x00,  0x00,  0xff,  0x10,  0xff,  0xff,  0xff,  0x0f,
13529   0x00,  0x00,  0xfe,  0x78,  0x56,  0xfe,  0x34,  0x12,  0xff,  0x21,  0x00,  0x00,  0xfe,  0x04,  0xf7,  0xcf,
13530   0x2a,  0x67,  0x0b,  0x01,  0xfe,  0xce,  0x0e,  0xfe,  0x04,  0xf7,  0xcf,  0x67,  0x0b,  0x3c,  0x2a,  0xfe,
13531   0x3d,  0xf0,  0xfe,  0x02,  0x02,  0xfe,  0x20,  0xf0,  0x9c,  0xfe,  0x91,  0xf0,  0xfe,  0xf0,  0x01,  0xfe,
13532   0x90,  0xf0,  0xfe,  0xf0,  0x01,  0xfe,  0x8f,  0xf0,  0x9c,  0x05,  0x51,  0x3b,  0x02,  0xfe,  0xd4,  0x0c,
13533   0x01,  0xfe,  0x44,  0x0d,  0xfe,  0xdd,  0x12,  0xfe,  0xfc,  0x10,  0xfe,  0x28,  0x1c,  0x05,  0xfe,  0xa6,
13534   0x00,  0xfe,  0xd3,  0x12,  0x47,  0x18,  0xfe,  0xa6,  0x00,  0xb5,  0xfe,  0x48,  0xf0,  0xfe,  0x86,  0x02,
13535   0xfe,  0x49,  0xf0,  0xfe,  0xa0,  0x02,  0xfe,  0x4a,  0xf0,  0xfe,  0xbe,  0x02,  0xfe,  0x46,  0xf0,  0xfe,
13536   0x50,  0x02,  0xfe,  0x47,  0xf0,  0xfe,  0x56,  0x02,  0xfe,  0x43,  0xf0,  0xfe,  0x44,  0x02,  0xfe,  0x44,
13537   0xf0,  0xfe,  0x48,  0x02,  0xfe,  0x45,  0xf0,  0xfe,  0x4c,  0x02,  0x17,  0x0b,  0xa0,  0x17,  0x06,  0x18,
13538   0x96,  0x02,  0x29,  0xfe,  0x00,  0x1c,  0xde,  0xfe,  0x02,  0x1c,  0xdd,  0xfe,  0x1e,  0x1c,  0xfe,  0xe9,
13539   0x10,  0x01,  0xfe,  0x20,  0x17,  0xfe,  0xe7,  0x10,  0xfe,  0x06,  0xfc,  0xc7,  0x0a,  0x6b,  0x01,  0x9e,
13540   0x02,  0x29,  0x14,  0x4d,  0x37,  0x97,  0x01,  0xfe,  0x64,  0x0f,  0x0a,  0x6b,  0x01,  0x82,  0xfe,  0xbd,
13541   0x10,  0x0a,  0x6b,  0x01,  0x82,  0xfe,  0xad,  0x10,  0xfe,  0x16,  0x1c,  0xfe,  0x58,  0x1c,  0x17,  0x06,
13542   0x18,  0x96,  0x2a,  0x25,  0x29,  0xfe,  0x3d,  0xf0,  0xfe,  0x02,  0x02,  0x21,  0xfe,  0x94,  0x02,  0xfe,
13543   0x5a,  0x1c,  0xea,  0xfe,  0x14,  0x1c,  0x14,  0xfe,  0x30,  0x00,  0x37,  0x97,  0x01,  0xfe,  0x54,  0x0f,
13544   0x17,  0x06,  0x18,  0x96,  0x02,  0xd0,  0x1e,  0x20,  0x07,  0x10,  0x34,  0xfe,  0x69,  0x10,  0x17,  0x06,
13545   0x18,  0x96,  0xfe,  0x04,  0xec,  0x20,  0x46,  0x3d,  0x12,  0x20,  0xfe,  0x05,  0xf6,  0xc7,  0x01,  0xfe,
13546   0x52,  0x16,  0x09,  0x4a,  0x4c,  0x35,  0x11,  0x2d,  0x3c,  0x8a,  0x01,  0xe6,  0x02,  0x29,  0x0a,  0x40,
13547   0x01,  0x0e,  0x07,  0x00,  0x5d,  0x01,  0x6f,  0xfe,  0x18,  0x10,  0xfe,  0x41,  0x58,  0x0a,  0x99,  0x01,
13548   0x0e,  0xfe,  0xc8,  0x54,  0x64,  0xfe,  0x0c,  0x03,  0x01,  0xe6,  0x02,  0x29,  0x2a,  0x46,  0xfe,  0x02,
13549   0xe8,  0x27,  0xf8,  0xfe,  0x9e,  0x43,  0xf7,  0xfe,  0x27,  0xf0,  0xfe,  0xdc,  0x01,  0xfe,  0x07,  0x4b,
13550   0xfe,  0x20,  0xf0,  0x9c,  0xfe,  0x40,  0x1c,  0x25,  0xd2,  0xfe,  0x26,  0xf0,  0xfe,  0x56,  0x03,  0xfe,
13551   0xa0,  0xf0,  0xfe,  0x44,  0x03,  0xfe,  0x11,  0xf0,  0x9c,  0xfe,  0xef,  0x10,  0xfe,  0x9f,  0xf0,  0xfe,
13552   0x64,  0x03,  0xeb,  0x0f,  0xfe,  0x11,  0x00,  0x02,  0x5a,  0x2a,  0xfe,  0x48,  0x1c,  0xeb,  0x09,  0x04,
13553   0x1d,  0xfe,  0x18,  0x13,  0x23,  0x1e,  0x98,  0xac,  0x12,  0x98,  0x0a,  0x40,  0x01,  0x0e,  0xac,  0x75,
13554   0x01,  0xfe,  0xbc,  0x15,  0x11,  0xca,  0x25,  0xd2,  0xfe,  0x01,  0xf0,  0xd2,  0xfe,  0x82,  0xf0,  0xfe,
13555   0x92,  0x03,  0xec,  0x11,  0xfe,  0xe4,  0x00,  0x65,  0xfe,  0xa4,  0x03,  0x25,  0x32,  0x1f,  0xfe,  0xb4,
13556   0x03,  0x01,  0x43,  0xfe,  0x06,  0xf0,  0xfe,  0xc4,  0x03,  0x8d,  0x81,  0xfe,  0x0a,  0xf0,  0xfe,  0x7a,
13557   0x06,  0x02,  0x22,  0x05,  0x6b,  0x28,  0x16,  0xfe,  0xf6,  0x04,  0x14,  0x2c,  0x01,  0x33,  0x8f,  0xfe,
13558   0x66,  0x02,  0x02,  0xd1,  0xeb,  0x2a,  0x67,  0x1a,  0xfe,  0x67,  0x1b,  0xf8,  0xf7,  0xfe,  0x48,  0x1c,
13559   0x70,  0x01,  0x6e,  0x87,  0x0a,  0x40,  0x01,  0x0e,  0x07,  0x00,  0x16,  0xd3,  0x0a,  0xca,  0x01,  0x0e,
13560   0x74,  0x60,  0x59,  0x76,  0x27,  0x05,  0x6b,  0x28,  0xfe,  0x10,  0x12,  0x14,  0x2c,  0x01,  0x33,  0x8f,
13561   0xfe,  0x66,  0x02,  0x02,  0xd1,  0xbc,  0x7d,  0xbd,  0x7f,  0x25,  0x22,  0x65,  0xfe,  0x3c,  0x04,  0x1f,
13562   0xfe,  0x38,  0x04,  0x68,  0xfe,  0xa0,  0x00,  0xfe,  0x9b,  0x57,  0xfe,  0x4e,  0x12,  0x2b,  0xff,  0x02,
13563   0x00,  0x10,  0x01,  0x08,  0x1f,  0xfe,  0xe0,  0x04,  0x2b,  0x01,  0x08,  0x1f,  0x22,  0x30,  0x2e,  0xd5,
13564   0xfe,  0x4c,  0x44,  0xfe,  0x4c,  0x12,  0x60,  0xfe,  0x44,  0x48,  0x13,  0x2c,  0xfe,  0x4c,  0x54,  0x64,
13565   0xd3,  0x46,  0x76,  0x27,  0xfa,  0xef,  0xfe,  0x62,  0x13,  0x09,  0x04,  0x1d,  0xfe,  0x2a,  0x13,  0x2f,
13566   0x07,  0x7e,  0xa5,  0xfe,  0x20,  0x10,  0x13,  0x2c,  0xfe,  0x4c,  0x54,  0x64,  0xd3,  0xfa,  0xef,  0x86,
13567   0x09,  0x04,  0x1d,  0xfe,  0x08,  0x13,  0x2f,  0x07,  0x7e,  0x6e,  0x09,  0x04,  0x1d,  0xfe,  0x1c,  0x12,
13568   0x14,  0x92,  0x09,  0x04,  0x06,  0x3b,  0x14,  0xc4,  0x01,  0x33,  0x8f,  0xfe,  0x70,  0x0c,  0x02,  0x22,
13569   0x2b,  0x11,  0xfe,  0xe6,  0x00,  0xfe,  0x1c,  0x90,  0xf9,  0x03,  0x14,  0x92,  0x01,  0x33,  0x02,  0x29,
13570   0xfe,  0x42,  0x5b,  0x67,  0x1a,  0xfe,  0x46,  0x59,  0xf8,  0xf7,  0xfe,  0x87,  0x80,  0xfe,  0x31,  0xe4,
13571   0x4f,  0x09,  0x04,  0x0b,  0xfe,  0x78,  0x13,  0xfe,  0x20,  0x80,  0x07,  0x1a,  0xfe,  0x70,  0x12,  0x49,
13572   0x04,  0x06,  0xfe,  0x60,  0x13,  0x05,  0xfe,  0xa2,  0x00,  0x28,  0x16,  0xfe,  0x80,  0x05,  0xfe,  0x31,
13573   0xe4,  0x6a,  0x49,  0x04,  0x0b,  0xfe,  0x4a,  0x13,  0x05,  0xfe,  0xa0,  0x00,  0x28,  0xfe,  0x42,  0x12,
13574   0x5e,  0x01,  0x08,  0x25,  0x32,  0xf1,  0x01,  0x08,  0x26,  0xfe,  0x98,  0x05,  0x11,  0xfe,  0xe3,  0x00,
13575   0x23,  0x49,  0xfe,  0x4a,  0xf0,  0xfe,  0x6a,  0x05,  0xfe,  0x49,  0xf0,  0xfe,  0x64,  0x05,  0x83,  0x24,
13576   0xfe,  0x21,  0x00,  0xa1,  0x24,  0xfe,  0x22,  0x00,  0xa0,  0x24,  0x4c,  0xfe,  0x09,  0x48,  0x01,  0x08,
13577   0x26,  0xfe,  0x98,  0x05,  0xfe,  0xe2,  0x08,  0x49,  0x04,  0xc5,  0x3b,  0x01,  0x86,  0x24,  0x06,  0x12,
13578   0xcc,  0x37,  0xfe,  0x27,  0x01,  0x09,  0x04,  0x1d,  0xfe,  0x22,  0x12,  0x47,  0x01,  0xa7,  0x14,  0x92,
13579   0x09,  0x04,  0x06,  0x3b,  0x14,  0xc4,  0x01,  0x33,  0x8f,  0xfe,  0x70,  0x0c,  0x02,  0x22,  0x05,  0xfe,
13580   0x9c,  0x00,  0x28,  0xfe,  0x3e,  0x12,  0x05,  0x50,  0x28,  0xfe,  0x36,  0x13,  0x47,  0x01,  0xa7,  0x26,
13581   0xfe,  0x08,  0x06,  0x0a,  0x06,  0x49,  0x04,  0x19,  0xfe,  0x02,  0x12,  0x5f,  0x01,  0xfe,  0xaa,  0x14,
13582   0x1f,  0xfe,  0xfe,  0x05,  0x11,  0x9a,  0x01,  0x43,  0x11,  0xfe,  0xe5,  0x00,  0x05,  0x50,  0xb4,  0x0c,
13583   0x50,  0x05,  0xc6,  0x28,  0xfe,  0x62,  0x12,  0x05,  0x3f,  0x28,  0xfe,  0x5a,  0x13,  0x01,  0xfe,  0x14,
13584   0x18,  0x01,  0xfe,  0x66,  0x18,  0xfe,  0x43,  0x48,  0xb7,  0x19,  0x13,  0x6c,  0xff,  0x02,  0x00,  0x57,
13585   0x48,  0x8b,  0x1c,  0x3d,  0x85,  0xb7,  0x69,  0x47,  0x01,  0xa7,  0x26,  0xfe,  0x72,  0x06,  0x49,  0x04,
13586   0x1b,  0xdf,  0x89,  0x0a,  0x4d,  0x01,  0xfe,  0xd8,  0x14,  0x1f,  0xfe,  0x68,  0x06,  0x11,  0x9a,  0x01,
13587   0x43,  0x11,  0xfe,  0xe5,  0x00,  0x05,  0x3f,  0xb4,  0x0c,  0x3f,  0x17,  0x06,  0x01,  0xa7,  0xec,  0x72,
13588   0x70,  0x01,  0x6e,  0x87,  0x11,  0xfe,  0xe2,  0x00,  0x01,  0x08,  0x25,  0x32,  0xfe,  0x0a,  0xf0,  0xfe,
13589   0xa6,  0x06,  0x8c,  0xfe,  0x5c,  0x07,  0xfe,  0x06,  0xf0,  0xfe,  0x64,  0x07,  0x8d,  0x81,  0x02,  0x22,
13590   0x09,  0x04,  0x0b,  0xfe,  0x2e,  0x12,  0x15,  0x1a,  0x01,  0x08,  0x15,  0x00,  0x01,  0x08,  0x15,  0x00,
13591   0x01,  0x08,  0x15,  0x00,  0x01,  0x08,  0xfe,  0x99,  0xa4,  0x01,  0x08,  0x15,  0x00,  0x02,  0xfe,  0x32,
13592   0x08,  0x61,  0x04,  0x1b,  0xfe,  0x38,  0x12,  0x09,  0x04,  0x1b,  0x6e,  0x15,  0xfe,  0x1b,  0x00,  0x01,
13593   0x08,  0x15,  0x00,  0x01,  0x08,  0x15,  0x00,  0x01,  0x08,  0x15,  0x00,  0x01,  0x08,  0x15,  0x06,  0x01,
13594   0x08,  0x15,  0x00,  0x02,  0xd9,  0x66,  0x4c,  0xfe,  0x3a,  0x55,  0x5f,  0xfe,  0x9a,  0x81,  0x4b,  0x1d,
13595   0xba,  0xfe,  0x32,  0x07,  0x0a,  0x1d,  0xfe,  0x09,  0x6f,  0xaf,  0xfe,  0xca,  0x45,  0xfe,  0x32,  0x12,
13596   0x62,  0x2c,  0x85,  0x66,  0x7b,  0x01,  0x08,  0x25,  0x32,  0xfe,  0x0a,  0xf0,  0xfe,  0x32,  0x07,  0x8d,
13597   0x81,  0x8c,  0xfe,  0x5c,  0x07,  0x02,  0x22,  0x01,  0x43,  0x02,  0xfe,  0x8a,  0x06,  0x15,  0x19,  0x02,
13598   0xfe,  0x8a,  0x06,  0xfe,  0x9c,  0xf7,  0xd4,  0xfe,  0x2c,  0x90,  0xfe,  0xae,  0x90,  0x77,  0xfe,  0xca,
13599   0x07,  0x0c,  0x54,  0x18,  0x55,  0x09,  0x4a,  0x6a,  0x35,  0x1e,  0x20,  0x07,  0x10,  0xfe,  0x0e,  0x12,
13600   0x74,  0xfe,  0x80,  0x80,  0x37,  0x20,  0x63,  0x27,  0xfe,  0x06,  0x10,  0xfe,  0x83,  0xe7,  0xc4,  0xa1,
13601   0xfe,  0x03,  0x40,  0x09,  0x4a,  0x4f,  0x35,  0x01,  0xa8,  0xad,  0xfe,  0x1f,  0x40,  0x12,  0x58,  0x01,
13602   0xa5,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0xfe,  0x44,  0x51,  0xfe,  0xc6,  0x51,  0x83,  0xfb,  0xfe,
13603   0x8a,  0x90,  0x0c,  0x52,  0x18,  0x53,  0xfe,  0x0c,  0x90,  0xfe,  0x8e,  0x90,  0xfe,  0x40,  0x50,  0xfe,
13604   0xc2,  0x50,  0x0c,  0x39,  0x18,  0x3a,  0xfe,  0x4a,  0x10,  0x09,  0x04,  0x6a,  0xfe,  0x2a,  0x12,  0xfe,
13605   0x2c,  0x90,  0xfe,  0xae,  0x90,  0x0c,  0x54,  0x18,  0x55,  0x09,  0x04,  0x4f,  0x85,  0x01,  0xa8,  0xfe,
13606   0x1f,  0x80,  0x12,  0x58,  0xfe,  0x44,  0x90,  0xfe,  0xc6,  0x90,  0x0c,  0x56,  0x18,  0x57,  0xfb,  0xfe,
13607   0x8a,  0x90,  0x0c,  0x52,  0x18,  0x53,  0xfe,  0x40,  0x90,  0xfe,  0xc2,  0x90,  0x0c,  0x39,  0x18,  0x3a,
13608   0x0c,  0x38,  0x18,  0x4e,  0x09,  0x4a,  0x19,  0x35,  0x2a,  0x13,  0xfe,  0x4e,  0x11,  0x65,  0xfe,  0x48,
13609   0x08,  0xfe,  0x9e,  0xf0,  0xfe,  0x5c,  0x08,  0xb1,  0x16,  0x32,  0x2a,  0x73,  0xdd,  0xb8,  0xfe,  0x80,
13610   0x08,  0xb9,  0xfe,  0x9e,  0x08,  0x8c,  0xfe,  0x74,  0x08,  0xfe,  0x06,  0xf0,  0xfe,  0x7a,  0x08,  0x8d,
13611   0x81,  0x02,  0x22,  0x01,  0x43,  0xfe,  0xc9,  0x10,  0x15,  0x19,  0xfe,  0xc9,  0x10,  0x61,  0x04,  0x06,
13612   0xfe,  0x10,  0x12,  0x61,  0x04,  0x0b,  0x45,  0x09,  0x04,  0x0b,  0xfe,  0x68,  0x12,  0xfe,  0x2e,  0x1c,
13613   0x02,  0xfe,  0x24,  0x0a,  0x61,  0x04,  0x06,  0x45,  0x61,  0x04,  0x0b,  0xfe,  0x52,  0x12,  0xfe,  0x2c,
13614   0x1c,  0xfe,  0xaa,  0xf0,  0xfe,  0x1e,  0x09,  0xfe,  0xac,  0xf0,  0xfe,  0xbe,  0x08,  0xfe,  0x8a,  0x10,
13615   0xaa,  0xfe,  0xf3,  0x10,  0xfe,  0xad,  0xf0,  0xfe,  0xca,  0x08,  0x02,  0xfe,  0x24,  0x0a,  0xab,  0xfe,
13616   0xe7,  0x10,  0xfe,  0x2b,  0xf0,  0x9d,  0xe9,  0x1c,  0xfe,  0x00,  0xfe,  0xfe,  0x1c,  0x12,  0xb5,  0xfe,
13617   0xd2,  0xf0,  0x9d,  0xfe,  0x76,  0x18,  0x1c,  0x1a,  0x16,  0x9d,  0x05,  0xcb,  0x1c,  0x06,  0x16,  0x9d,
13618   0xb8,  0x6d,  0xb9,  0x6d,  0xaa,  0xab,  0xfe,  0xb1,  0x10,  0x70,  0x5e,  0x2b,  0x14,  0x92,  0x01,  0x33,
13619   0x0f,  0xfe,  0x35,  0x00,  0xfe,  0x01,  0xf0,  0x5a,  0x0f,  0x7c,  0x02,  0x5a,  0xfe,  0x74,  0x18,  0x1c,
13620   0xfe,  0x00,  0xf8,  0x16,  0x6d,  0x67,  0x1b,  0x01,  0xfe,  0x44,  0x0d,  0x3b,  0x01,  0xe6,  0x1e,  0x27,
13621   0x74,  0x67,  0x1a,  0x02,  0x6d,  0x09,  0x04,  0x0b,  0x21,  0xfe,  0x06,  0x0a,  0x09,  0x04,  0x6a,  0xfe,
13622   0x82,  0x12,  0x09,  0x04,  0x19,  0xfe,  0x66,  0x13,  0x1e,  0x58,  0xac,  0xfc,  0xfe,  0x83,  0x80,  0xfe,
13623   0xc8,  0x44,  0xfe,  0x2e,  0x13,  0xfe,  0x04,  0x91,  0xfe,  0x86,  0x91,  0x63,  0x27,  0xfe,  0x40,  0x59,
13624   0xfe,  0xc1,  0x59,  0x77,  0xd7,  0x05,  0x54,  0x31,  0x55,  0x0c,  0x7b,  0x18,  0x7c,  0xbe,  0x54,  0xbf,
13625   0x55,  0x01,  0xa8,  0xad,  0x63,  0x27,  0x12,  0x58,  0xc0,  0x38,  0xc1,  0x4e,  0x79,  0x56,  0x68,  0x57,
13626   0xf4,  0xf5,  0xfe,  0x04,  0xfa,  0x38,  0xfe,  0x05,  0xfa,  0x4e,  0x01,  0xa5,  0xa2,  0x23,  0x0c,  0x7b,
13627   0x0c,  0x7c,  0x79,  0x56,  0x68,  0x57,  0xfe,  0x12,  0x10,  0x09,  0x04,  0x19,  0x16,  0xd7,  0x79,  0x39,
13628   0x68,  0x3a,  0x09,  0x04,  0xfe,  0xf7,  0x00,  0x35,  0x05,  0x52,  0x31,  0x53,  0xfe,  0x10,  0x58,  0xfe,
13629   0x91,  0x58,  0xfe,  0x14,  0x59,  0xfe,  0x95,  0x59,  0x02,  0x6d,  0x09,  0x04,  0x19,  0x16,  0xd7,  0x09,
13630   0x04,  0xfe,  0xf7,  0x00,  0x35,  0xfe,  0x3a,  0x55,  0xfe,  0x19,  0x81,  0x5f,  0xfe,  0x10,  0x90,  0xfe,
13631   0x92,  0x90,  0xfe,  0xd7,  0x10,  0x2f,  0x07,  0x9b,  0x16,  0xfe,  0xc6,  0x08,  0x11,  0x9b,  0x09,  0x04,
13632   0x0b,  0xfe,  0x14,  0x13,  0x05,  0x39,  0x31,  0x3a,  0x77,  0xfe,  0xc6,  0x08,  0xfe,  0x0c,  0x58,  0xfe,
13633   0x8d,  0x58,  0x02,  0x6d,  0x23,  0x47,  0xfe,  0x19,  0x80,  0xde,  0x09,  0x04,  0x0b,  0xfe,  0x1a,  0x12,
13634   0xfe,  0x6c,  0x19,  0xfe,  0x19,  0x41,  0xe9,  0xb5,  0xfe,  0xd1,  0xf0,  0xd9,  0x14,  0x7a,  0x01,  0x33,
13635   0x0f,  0xfe,  0x44,  0x00,  0xfe,  0x8e,  0x10,  0xfe,  0x6c,  0x19,  0xbe,  0x39,  0xfe,  0xed,  0x19,  0xbf,
13636   0x3a,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0xe9,  0x1c,  0xfe,  0x00,  0xff,  0x34,  0xfe,  0x74,  0x10,
13637   0xb5,  0xfe,  0xd2,  0xf0,  0xfe,  0xb2,  0x0a,  0xfe,  0x76,  0x18,  0x1c,  0x1a,  0x84,  0x05,  0xcb,  0x1c,
13638   0x06,  0xfe,  0x08,  0x13,  0x0f,  0xfe,  0x16,  0x00,  0x02,  0x5a,  0xfe,  0xd1,  0xf0,  0xfe,  0xc4,  0x0a,
13639   0x14,  0x7a,  0x01,  0x33,  0x0f,  0xfe,  0x17,  0x00,  0xfe,  0x42,  0x10,  0xfe,  0xce,  0xf0,  0xfe,  0xca,
13640   0x0a,  0xfe,  0x3c,  0x10,  0xfe,  0xcd,  0xf0,  0xfe,  0xd6,  0x0a,  0x0f,  0xfe,  0x22,  0x00,  0x02,  0x5a,
13641   0xfe,  0xcb,  0xf0,  0xfe,  0xe2,  0x0a,  0x0f,  0xfe,  0x24,  0x00,  0x02,  0x5a,  0xfe,  0xd0,  0xf0,  0xfe,
13642   0xec,  0x0a,  0x0f,  0x93,  0xdc,  0xfe,  0xcf,  0xf0,  0xfe,  0xf6,  0x0a,  0x0f,  0x4c,  0xfe,  0x10,  0x10,
13643   0xfe,  0xcc,  0xf0,  0xd9,  0x61,  0x04,  0x19,  0x3b,  0x0f,  0xfe,  0x12,  0x00,  0x2a,  0x13,  0xfe,  0x4e,
13644   0x11,  0x65,  0xfe,  0x0c,  0x0b,  0xfe,  0x9e,  0xf0,  0xfe,  0x20,  0x0b,  0xb1,  0x16,  0x32,  0x2a,  0x73,
13645   0xdd,  0xb8,  0x22,  0xb9,  0x22,  0x2a,  0xec,  0x65,  0xfe,  0x2c,  0x0b,  0x25,  0x32,  0x8c,  0xfe,  0x48,
13646   0x0b,  0x8d,  0x81,  0xb8,  0xd4,  0xb9,  0xd4,  0x02,  0x22,  0x01,  0x43,  0xfe,  0xdb,  0x10,  0x11,  0xfe,
13647   0xe8,  0x00,  0xaa,  0xab,  0x70,  0xbc,  0x7d,  0xbd,  0x7f,  0xfe,  0x89,  0xf0,  0x22,  0x30,  0x2e,  0xd8,
13648   0xbc,  0x7d,  0xbd,  0x7f,  0x01,  0x08,  0x1f,  0x22,  0x30,  0x2e,  0xd6,  0xb1,  0x45,  0x0f,  0xfe,  0x42,
13649   0x00,  0x02,  0x5a,  0x78,  0x06,  0xfe,  0x81,  0x49,  0x16,  0xfe,  0x38,  0x0c,  0x09,  0x04,  0x0b,  0xfe,
13650   0x44,  0x13,  0x0f,  0x00,  0x4b,  0x0b,  0xfe,  0x54,  0x12,  0x4b,  0xfe,  0x28,  0x00,  0x21,  0xfe,  0xa6,
13651   0x0c,  0x0a,  0x40,  0x01,  0x0e,  0x07,  0x00,  0x5d,  0x3e,  0xfe,  0x28,  0x00,  0xfe,  0xe2,  0x10,  0x01,
13652   0xe7,  0x01,  0xe8,  0x0a,  0x99,  0x01,  0xfe,  0x32,  0x0e,  0x59,  0x11,  0x2d,  0x01,  0x6f,  0x02,  0x29,
13653   0x0f,  0xfe,  0x44,  0x00,  0x4b,  0x0b,  0xdf,  0x3e,  0x0b,  0xfe,  0xb4,  0x10,  0x01,  0x86,  0x3e,  0x0b,
13654   0xfe,  0xaa,  0x10,  0x01,  0x86,  0xfe,  0x19,  0x82,  0xfe,  0x34,  0x46,  0xa3,  0x3e,  0x0b,  0x0f,  0xfe,
13655   0x43,  0x00,  0xfe,  0x96,  0x10,  0x09,  0x4a,  0x0b,  0x35,  0x01,  0xe7,  0x01,  0xe8,  0x59,  0x11,  0x2d,
13656   0x01,  0x6f,  0x67,  0x0b,  0x59,  0x3c,  0x8a,  0x02,  0xfe,  0x2a,  0x03,  0x09,  0x04,  0x0b,  0x84,  0x3e,
13657   0x0b,  0x0f,  0x00,  0xfe,  0x5c,  0x10,  0x61,  0x04,  0x1b,  0xfe,  0x58,  0x12,  0x09,  0x04,  0x1b,  0xfe,
13658   0x50,  0x13,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x5c,  0x0c,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,
13659   0xf0,  0xfe,  0x62,  0x0c,  0x09,  0x4a,  0x1b,  0x35,  0xfe,  0xa9,  0x10,  0x0f,  0xfe,  0x15,  0x00,  0xfe,
13660   0x04,  0xe6,  0x0b,  0x5f,  0x5c,  0x0f,  0xfe,  0x13,  0x00,  0xfe,  0x10,  0x10,  0x0f,  0xfe,  0x47,  0x00,
13661   0xa1,  0x0f,  0xfe,  0x41,  0x00,  0xa0,  0x0f,  0xfe,  0x24,  0x00,  0x87,  0xaa,  0xab,  0x70,  0x05,  0x6b,
13662   0x28,  0x21,  0xd1,  0x5f,  0xfe,  0x04,  0xe6,  0x1b,  0xfe,  0x9d,  0x41,  0xfe,  0x1c,  0x42,  0x59,  0x01,
13663   0xda,  0x02,  0x29,  0xea,  0x14,  0x0b,  0x37,  0x95,  0xa9,  0x14,  0xfe,  0x31,  0x00,  0x37,  0x97,  0x01,
13664   0xfe,  0x54,  0x0f,  0x02,  0xd0,  0x3c,  0xfe,  0x06,  0xec,  0xc9,  0xee,  0x3e,  0x1d,  0xfe,  0xce,  0x45,
13665   0x34,  0x3c,  0xfe,  0x06,  0xea,  0xc9,  0xfe,  0x47,  0x4b,  0x89,  0xfe,  0x75,  0x57,  0x05,  0x51,  0xfe,
13666   0x98,  0x56,  0xfe,  0x38,  0x12,  0x0a,  0x42,  0x01,  0x0e,  0xfe,  0x44,  0x48,  0x46,  0x09,  0x04,  0x1d,
13667   0xfe,  0x1a,  0x13,  0x0a,  0x40,  0x01,  0x0e,  0x47,  0xfe,  0x41,  0x58,  0x0a,  0x99,  0x01,  0x0e,  0xfe,
13668   0x49,  0x54,  0x8e,  0xfe,  0x2a,  0x0d,  0x02,  0xfe,  0x2a,  0x03,  0x0a,  0x51,  0xfe,  0xee,  0x14,  0xee,
13669   0x3e,  0x1d,  0xfe,  0xce,  0x45,  0x34,  0x3c,  0xfe,  0xce,  0x47,  0xfe,  0xad,  0x13,  0x02,  0x29,  0x1e,
13670   0x20,  0x07,  0x10,  0xfe,  0x9e,  0x12,  0x23,  0x12,  0x4d,  0x12,  0x94,  0x12,  0xce,  0x1e,  0x2d,  0x47,
13671   0x37,  0x2d,  0xb1,  0xe0,  0xfe,  0xbc,  0xf0,  0xfe,  0xec,  0x0d,  0x13,  0x06,  0x12,  0x4d,  0x01,  0xfe,
13672   0xe2,  0x15,  0x05,  0xfe,  0x38,  0x01,  0x31,  0xfe,  0x3a,  0x01,  0x77,  0xfe,  0xf0,  0x0d,  0xfe,  0x02,
13673   0xec,  0xce,  0x62,  0x00,  0x5d,  0xfe,  0x04,  0xec,  0x20,  0x46,  0xfe,  0x05,  0xf6,  0xfe,  0x34,  0x01,
13674   0x01,  0xfe,  0x52,  0x16,  0xfb,  0xfe,  0x48,  0xf4,  0x0d,  0xfe,  0x18,  0x13,  0xaf,  0xfe,  0x02,  0xea,
13675   0xce,  0x62,  0x7a,  0xfe,  0xc5,  0x13,  0x14,  0x1b,  0x37,  0x95,  0xa9,  0x5c,  0x05,  0xfe,  0x38,  0x01,
13676   0x1c,  0xfe,  0xf0,  0xff,  0x0c,  0xfe,  0x60,  0x01,  0x05,  0xfe,  0x3a,  0x01,  0x0c,  0xfe,  0x62,  0x01,
13677   0x3d,  0x12,  0x20,  0x24,  0x06,  0x12,  0x2d,  0x11,  0x2d,  0x8a,  0x13,  0x06,  0x03,  0x23,  0x03,  0x1e,
13678   0x4d,  0xfe,  0xf7,  0x12,  0x1e,  0x94,  0xac,  0x12,  0x94,  0x07,  0x7a,  0xfe,  0x71,  0x13,  0xfe,  0x24,
13679   0x1c,  0x14,  0x1a,  0x37,  0x95,  0xa9,  0xfe,  0xd9,  0x10,  0xb6,  0xfe,  0x03,  0xdc,  0xfe,  0x73,  0x57,
13680   0xfe,  0x80,  0x5d,  0x03,  0xb6,  0xfe,  0x03,  0xdc,  0xfe,  0x5b,  0x57,  0xfe,  0x80,  0x5d,  0x03,  0xfe,
13681   0x03,  0x57,  0xb6,  0x23,  0xfe,  0x00,  0xcc,  0x03,  0xfe,  0x03,  0x57,  0xb6,  0x75,  0x03,  0x09,  0x04,
13682   0x4c,  0xfe,  0x22,  0x13,  0xfe,  0x1c,  0x80,  0x07,  0x06,  0xfe,  0x1a,  0x13,  0xfe,  0x1e,  0x80,  0xe1,
13683   0xfe,  0x1d,  0x80,  0xa4,  0xfe,  0x0c,  0x90,  0xfe,  0x0e,  0x13,  0xfe,  0x0e,  0x90,  0xa3,  0xfe,  0x3c,
13684   0x90,  0xfe,  0x30,  0xf4,  0x0b,  0xfe,  0x3c,  0x50,  0xa0,  0x01,  0xfe,  0x82,  0x16,  0x2f,  0x07,  0x2d,
13685   0xe0,  0x01,  0xfe,  0xbc,  0x15,  0x09,  0x04,  0x1d,  0x45,  0x01,  0xe7,  0x01,  0xe8,  0x11,  0xfe,  0xe9,
13686   0x00,  0x09,  0x04,  0x4c,  0xfe,  0x2c,  0x13,  0x01,  0xfe,  0x14,  0x16,  0xfe,  0x1e,  0x1c,  0xfe,  0x14,
13687   0x90,  0xfe,  0x96,  0x90,  0x0c,  0xfe,  0x64,  0x01,  0x18,  0xfe,  0x66,  0x01,  0x09,  0x04,  0x4f,  0xfe,
13688   0x12,  0x12,  0xfe,  0x03,  0x80,  0x74,  0xfe,  0x01,  0xec,  0x20,  0xfe,  0x80,  0x40,  0x12,  0x20,  0x63,
13689   0x27,  0x11,  0xc8,  0x59,  0x1e,  0x20,  0xed,  0x76,  0x20,  0x03,  0xfe,  0x08,  0x1c,  0x05,  0xfe,  0xac,
13690   0x00,  0xfe,  0x06,  0x58,  0x05,  0xfe,  0xae,  0x00,  0xfe,  0x07,  0x58,  0x05,  0xfe,  0xb0,  0x00,  0xfe,
13691   0x08,  0x58,  0x05,  0xfe,  0xb2,  0x00,  0xfe,  0x09,  0x58,  0xfe,  0x0a,  0x1c,  0x24,  0x69,  0x12,  0xc9,
13692   0x23,  0x0c,  0x50,  0x0c,  0x3f,  0x13,  0x40,  0x48,  0x5f,  0x17,  0x1d,  0xfe,  0x90,  0x4d,  0xfe,  0x91,
13693   0x54,  0x21,  0xfe,  0x08,  0x0f,  0x3e,  0x10,  0x13,  0x42,  0x48,  0x17,  0x4c,  0xfe,  0x90,  0x4d,  0xfe,
13694   0x91,  0x54,  0x21,  0xfe,  0x1e,  0x0f,  0x24,  0x10,  0x12,  0x20,  0x78,  0x2c,  0x46,  0x1e,  0x20,  0xed,
13695   0x76,  0x20,  0x11,  0xc8,  0xf6,  0xfe,  0xd6,  0xf0,  0xfe,  0x32,  0x0f,  0xea,  0x70,  0xfe,  0x14,  0x1c,
13696   0xfe,  0x10,  0x1c,  0xfe,  0x18,  0x1c,  0x03,  0x3c,  0xfe,  0x0c,  0x14,  0xee,  0xfe,  0x07,  0xe6,  0x1d,
13697   0xfe,  0xce,  0x47,  0xfe,  0xf5,  0x13,  0x03,  0x01,  0x86,  0x78,  0x2c,  0x46,  0xfa,  0xef,  0xfe,  0x42,
13698   0x13,  0x2f,  0x07,  0x2d,  0xfe,  0x34,  0x13,  0x0a,  0x42,  0x01,  0x0e,  0xb0,  0xfe,  0x36,  0x12,  0xf0,
13699   0xfe,  0x45,  0x48,  0x01,  0xe3,  0xfe,  0x00,  0xcc,  0xb0,  0xfe,  0xf3,  0x13,  0x3d,  0x75,  0x07,  0x10,
13700   0xa3,  0x0a,  0x80,  0x01,  0x0e,  0xfe,  0x80,  0x5c,  0x01,  0x6f,  0xfe,  0x0e,  0x10,  0x07,  0x7e,  0x45,
13701   0xf6,  0xfe,  0xd6,  0xf0,  0xfe,  0x6c,  0x0f,  0x03,  0xfe,  0x44,  0x58,  0x74,  0xfe,  0x01,  0xec,  0x97,
13702   0xfe,  0x9e,  0x40,  0xfe,  0x9d,  0xe7,  0x00,  0xfe,  0x9c,  0xe7,  0x1b,  0x76,  0x27,  0x01,  0xda,  0xfe,
13703   0xdd,  0x10,  0x2a,  0xbc,  0x7d,  0xbd,  0x7f,  0x30,  0x2e,  0xd5,  0x07,  0x1b,  0xfe,  0x48,  0x12,  0x07,
13704   0x0b,  0xfe,  0x56,  0x12,  0x07,  0x1a,  0xfe,  0x30,  0x12,  0x07,  0xc2,  0x16,  0xfe,  0x3e,  0x11,  0x07,
13705   0xfe,  0x23,  0x00,  0x16,  0xfe,  0x4a,  0x11,  0x07,  0x06,  0x16,  0xfe,  0xa8,  0x11,  0x07,  0x19,  0xfe,
13706   0x12,  0x12,  0x07,  0x00,  0x16,  0x22,  0x14,  0xc2,  0x01,  0x33,  0x9f,  0x2b,  0x01,  0x08,  0x8c,  0x43,
13707   0x03,  0x2b,  0xfe,  0x62,  0x08,  0x0a,  0xca,  0x01,  0xfe,  0x32,  0x0e,  0x11,  0x7e,  0x02,  0x29,  0x2b,
13708   0x2f,  0x07,  0x9b,  0xfe,  0xd9,  0x13,  0x79,  0x39,  0x68,  0x3a,  0x77,  0xfe,  0xfc,  0x10,  0x09,  0x04,
13709   0x6a,  0xfe,  0x72,  0x12,  0xc0,  0x38,  0xc1,  0x4e,  0xf4,  0xf5,  0x8e,  0xfe,  0xc6,  0x10,  0x1e,  0x58,
13710   0xfe,  0x26,  0x13,  0x05,  0x7b,  0x31,  0x7c,  0x77,  0xfe,  0x82,  0x0c,  0x0c,  0x54,  0x18,  0x55,  0x23,
13711   0x0c,  0x7b,  0x0c,  0x7c,  0x01,  0xa8,  0x24,  0x69,  0x73,  0x12,  0x58,  0x01,  0xa5,  0xc0,  0x38,  0xc1,
13712   0x4e,  0xfe,  0x04,  0x55,  0xfe,  0xa5,  0x55,  0xfe,  0x04,  0xfa,  0x38,  0xfe,  0x05,  0xfa,  0x4e,  0xfe,
13713   0x91,  0x10,  0x05,  0x56,  0x31,  0x57,  0xfe,  0x40,  0x56,  0xfe,  0xe1,  0x56,  0x0c,  0x56,  0x18,  0x57,
13714   0x83,  0xc0,  0x38,  0xc1,  0x4e,  0xf4,  0xf5,  0x05,  0x52,  0x31,  0x53,  0xfe,  0x00,  0x56,  0xfe,  0xa1,
13715   0x56,  0x0c,  0x52,  0x18,  0x53,  0x09,  0x04,  0x6a,  0xfe,  0x1e,  0x12,  0x1e,  0x58,  0xfe,  0x1f,  0x40,
13716   0x05,  0x54,  0x31,  0x55,  0xfe,  0x2c,  0x50,  0xfe,  0xae,  0x50,  0x05,  0x56,  0x31,  0x57,  0xfe,  0x44,
13717   0x50,  0xfe,  0xc6,  0x50,  0x05,  0x52,  0x31,  0x53,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0x05,  0x39,
13718   0x31,  0x3a,  0xfe,  0x40,  0x50,  0xfe,  0xc2,  0x50,  0x02,  0x5c,  0x24,  0x06,  0x12,  0xcd,  0x02,  0x5b,
13719   0x2b,  0x01,  0x08,  0x1f,  0x44,  0x30,  0x2e,  0xd5,  0x07,  0x06,  0x21,  0x44,  0x2f,  0x07,  0x9b,  0x21,
13720   0x5b,  0x01,  0x6e,  0x1c,  0x3d,  0x16,  0x44,  0x09,  0x04,  0x0b,  0xe2,  0x79,  0x39,  0x68,  0x3a,  0xfe,
13721   0x0a,  0x55,  0x34,  0xfe,  0x8b,  0x55,  0xbe,  0x39,  0xbf,  0x3a,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,
13722   0x02,  0x5b,  0xfe,  0x19,  0x81,  0xaf,  0xfe,  0x19,  0x41,  0x02,  0x5b,  0x2b,  0x01,  0x08,  0x25,  0x32,
13723   0x1f,  0xa2,  0x30,  0x2e,  0xd8,  0x4b,  0x1a,  0xfe,  0xa6,  0x12,  0x4b,  0x0b,  0x3b,  0x02,  0x44,  0x01,
13724   0x08,  0x25,  0x32,  0x1f,  0xa2,  0x30,  0x2e,  0xd6,  0x07,  0x1a,  0x21,  0x44,  0x01,  0x08,  0x1f,  0xa2,
13725   0x30,  0x2e,  0xfe,  0xe8,  0x09,  0xfe,  0xc2,  0x49,  0x60,  0x05,  0xfe,  0x9c,  0x00,  0x28,  0x84,  0x49,
13726   0x04,  0x19,  0x34,  0x9f,  0xfe,  0xbb,  0x45,  0x4b,  0x00,  0x45,  0x3e,  0x06,  0x78,  0x3d,  0xfe,  0xda,
13727   0x14,  0x01,  0x6e,  0x87,  0xfe,  0x4b,  0x45,  0xe2,  0x2f,  0x07,  0x9a,  0xe1,  0x05,  0xc6,  0x28,  0x84,
13728   0x05,  0x3f,  0x28,  0x34,  0x5e,  0x02,  0x5b,  0xfe,  0xc0,  0x5d,  0xfe,  0xf8,  0x14,  0xfe,  0x03,  0x17,
13729   0x05,  0x50,  0xb4,  0x0c,  0x50,  0x5e,  0x2b,  0x01,  0x08,  0x26,  0x5c,  0x01,  0xfe,  0xaa,  0x14,  0x02,
13730   0x5c,  0x01,  0x08,  0x25,  0x32,  0x1f,  0x44,  0x30,  0x2e,  0xd6,  0x07,  0x06,  0x21,  0x44,  0x01,  0xfe,
13731   0x8e,  0x13,  0xfe,  0x42,  0x58,  0xfe,  0x82,  0x14,  0xfe,  0xa4,  0x14,  0x87,  0xfe,  0x4a,  0xf4,  0x0b,
13732   0x16,  0x44,  0xfe,  0x4a,  0xf4,  0x06,  0xfe,  0x0c,  0x12,  0x2f,  0x07,  0x9a,  0x85,  0x02,  0x5b,  0x05,
13733   0x3f,  0xb4,  0x0c,  0x3f,  0x5e,  0x2b,  0x01,  0x08,  0x26,  0x5c,  0x01,  0xfe,  0xd8,  0x14,  0x02,  0x5c,
13734   0x13,  0x06,  0x65,  0xfe,  0xca,  0x12,  0x26,  0xfe,  0xe0,  0x12,  0x72,  0xf1,  0x01,  0x08,  0x23,  0x72,
13735   0x03,  0x8f,  0xfe,  0xdc,  0x12,  0x25,  0xfe,  0xdc,  0x12,  0x1f,  0xfe,  0xca,  0x12,  0x5e,  0x2b,  0x01,
13736   0x08,  0xfe,  0xd5,  0x10,  0x13,  0x6c,  0xff,  0x02,  0x00,  0x57,  0x48,  0x8b,  0x1c,  0xfe,  0xff,  0x7f,
13737   0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x03,  0x13,  0x6c,  0xff,  0x02,  0x00,  0x57,  0x48,  0x8b,  0x1c,
13738   0x3d,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x03,  0x13,  0x6c,  0xff,  0x02,  0x00,  0x57,  0x48,  0x8b,
13739   0x03,  0x13,  0x6c,  0xff,  0x02,  0x00,  0x57,  0x48,  0x8b,  0xfe,  0x0b,  0x58,  0x03,  0x0a,  0x50,  0x01,
13740   0x82,  0x0a,  0x3f,  0x01,  0x82,  0x03,  0xfc,  0x1c,  0x10,  0xff,  0x03,  0x00,  0x54,  0xfe,  0x00,  0xf4,
13741   0x19,  0x48,  0xfe,  0x00,  0x7d,  0xfe,  0x01,  0x7d,  0xfe,  0x02,  0x7d,  0xfe,  0x03,  0x7c,  0x63,  0x27,
13742   0x0c,  0x52,  0x18,  0x53,  0xbe,  0x56,  0xbf,  0x57,  0x03,  0xfe,  0x62,  0x08,  0xfe,  0x82,  0x4a,  0xfe,
13743   0xe1,  0x1a,  0xfe,  0x83,  0x5a,  0x74,  0x03,  0x01,  0xfe,  0x14,  0x18,  0xfe,  0x42,  0x48,  0x5f,  0x60,
13744   0x89,  0x01,  0x08,  0x1f,  0xfe,  0xa2,  0x14,  0x30,  0x2e,  0xd8,  0x01,  0x08,  0x1f,  0xfe,  0xa2,  0x14,
13745   0x30,  0x2e,  0xfe,  0xe8,  0x0a,  0xfe,  0xc1,  0x59,  0x05,  0xc6,  0x28,  0xfe,  0xcc,  0x12,  0x49,  0x04,
13746   0x1b,  0xfe,  0xc4,  0x13,  0x23,  0x62,  0x1b,  0xe2,  0x4b,  0xc3,  0x64,  0xfe,  0xe8,  0x13,  0x3b,  0x13,
13747   0x06,  0x17,  0xc3,  0x78,  0xdb,  0xfe,  0x78,  0x10,  0xff,  0x02,  0x83,  0x55,  0xa1,  0xff,  0x02,  0x83,
13748   0x55,  0x62,  0x1a,  0xa4,  0xbb,  0xfe,  0x30,  0x00,  0x8e,  0xe4,  0x17,  0x2c,  0x13,  0x06,  0xfe,  0x56,
13749   0x10,  0x62,  0x0b,  0xe1,  0xbb,  0xfe,  0x64,  0x00,  0x8e,  0xe4,  0x0a,  0xfe,  0x64,  0x00,  0x17,  0x93,
13750   0x13,  0x06,  0xfe,  0x28,  0x10,  0x62,  0x06,  0xfe,  0x60,  0x13,  0xbb,  0xfe,  0xc8,  0x00,  0x8e,  0xe4,
13751   0x0a,  0xfe,  0xc8,  0x00,  0x17,  0x4d,  0x13,  0x06,  0x83,  0xbb,  0xfe,  0x90,  0x01,  0xba,  0xfe,  0x4e,
13752   0x14,  0x89,  0xfe,  0x12,  0x10,  0xfe,  0x43,  0xf4,  0x94,  0xfe,  0x56,  0xf0,  0xfe,  0x60,  0x14,  0xfe,
13753   0x04,  0xf4,  0x6c,  0xfe,  0x43,  0xf4,  0x93,  0xfe,  0xf3,  0x10,  0xf9,  0x01,  0xfe,  0x22,  0x13,  0x1c,
13754   0x3d,  0xfe,  0x10,  0x13,  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,  0x69,  0xba,  0xfe,  0x9c,  0x14,  0xb7,
13755   0x69,  0xfe,  0x1c,  0x10,  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,  0x19,  0xba,  0xfe,  0x9c,  0x14,  0xb7,
13756   0x19,  0x83,  0x60,  0x23,  0xfe,  0x4d,  0xf4,  0x00,  0xdf,  0x89,  0x13,  0x06,  0xfe,  0xb4,  0x56,  0xfe,
13757   0xc3,  0x58,  0x03,  0x60,  0x13,  0x0b,  0x03,  0x15,  0x06,  0x01,  0x08,  0x26,  0xe5,  0x15,  0x0b,  0x01,
13758   0x08,  0x26,  0xe5,  0x15,  0x1a,  0x01,  0x08,  0x26,  0xe5,  0x72,  0xfe,  0x89,  0x49,  0x01,  0x08,  0x03,
13759   0x15,  0x06,  0x01,  0x08,  0x26,  0xa6,  0x15,  0x1a,  0x01,  0x08,  0x26,  0xa6,  0x15,  0x06,  0x01,  0x08,
13760   0x26,  0xa6,  0xfe,  0x89,  0x49,  0x01,  0x08,  0x26,  0xa6,  0x72,  0xfe,  0x89,  0x4a,  0x01,  0x08,  0x03,
13761   0x60,  0x03,  0x1e,  0xcc,  0x07,  0x06,  0xfe,  0x44,  0x13,  0xad,  0x12,  0xcc,  0xfe,  0x49,  0xf4,  0x00,
13762   0x3b,  0x72,  0x9f,  0x5e,  0xfe,  0x01,  0xec,  0xfe,  0x27,  0x01,  0xf1,  0x01,  0x08,  0x2f,  0x07,  0xfe,
13763   0xe3,  0x00,  0xfe,  0x20,  0x13,  0x1f,  0xfe,  0x5a,  0x15,  0x23,  0x12,  0xcd,  0x01,  0x43,  0x1e,  0xcd,
13764   0x07,  0x06,  0x45,  0x09,  0x4a,  0x06,  0x35,  0x03,  0x0a,  0x42,  0x01,  0x0e,  0xed,  0x88,  0x07,  0x10,
13765   0xa4,  0x0a,  0x80,  0x01,  0x0e,  0x88,  0x0a,  0x51,  0x01,  0x9e,  0x03,  0x0a,  0x80,  0x01,  0x0e,  0x88,
13766   0xfe,  0x80,  0xe7,  0x10,  0x07,  0x10,  0x84,  0xfe,  0x45,  0x58,  0x01,  0xe3,  0x88,  0x03,  0x0a,  0x42,
13767   0x01,  0x0e,  0x88,  0x0a,  0x51,  0x01,  0x9e,  0x03,  0x0a,  0x42,  0x01,  0x0e,  0xfe,  0x80,  0x80,  0xf2,
13768   0xfe,  0x49,  0xe4,  0x10,  0xa4,  0x0a,  0x80,  0x01,  0x0e,  0xf2,  0x0a,  0x51,  0x01,  0x82,  0x03,  0x17,
13769   0x10,  0x71,  0x66,  0xfe,  0x60,  0x01,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x24,  0x1c,  0xfe,
13770   0x1d,  0xf7,  0x1d,  0x90,  0xfe,  0xf6,  0x15,  0x01,  0xfe,  0xfc,  0x16,  0xe0,  0x91,  0x1d,  0x66,  0xfe,
13771   0x2c,  0x01,  0xfe,  0x2f,  0x19,  0x03,  0xae,  0x21,  0xfe,  0xe6,  0x15,  0xfe,  0xda,  0x10,  0x17,  0x10,
13772   0x71,  0x05,  0xfe,  0x64,  0x01,  0xfe,  0x00,  0xf4,  0x19,  0xfe,  0x18,  0x58,  0x05,  0xfe,  0x66,  0x01,
13773   0xfe,  0x19,  0x58,  0x91,  0x19,  0xfe,  0x3c,  0x90,  0xfe,  0x30,  0xf4,  0x06,  0xfe,  0x3c,  0x50,  0x66,
13774   0xfe,  0x38,  0x00,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0x19,  0x90,  0xfe,  0x40,  0x16,  0xfe,  0xb6,
13775   0x14,  0x34,  0x03,  0xae,  0x21,  0xfe,  0x18,  0x16,  0xfe,  0x9c,  0x10,  0x17,  0x10,  0x71,  0xfe,  0x83,
13776   0x5a,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x1d,  0xf7,  0x38,  0x90,  0xfe,  0x62,  0x16,  0xfe,
13777   0x94,  0x14,  0xfe,  0x10,  0x13,  0x91,  0x38,  0x66,  0x1b,  0xfe,  0xaf,  0x19,  0xfe,  0x98,  0xe7,  0x00,
13778   0x03,  0xae,  0x21,  0xfe,  0x56,  0x16,  0xfe,  0x6c,  0x10,  0x17,  0x10,  0x71,  0xfe,  0x30,  0xbc,  0xfe,
13779   0xb2,  0xbc,  0x91,  0xc5,  0x66,  0x1b,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0xc5,  0x90,  0xfe,  0x9a,
13780   0x16,  0xfe,  0x5c,  0x14,  0x34,  0x03,  0xae,  0x21,  0xfe,  0x86,  0x16,  0xfe,  0x42,  0x10,  0xfe,  0x02,
13781   0xf6,  0x10,  0x71,  0xfe,  0x18,  0xfe,  0x54,  0xfe,  0x19,  0xfe,  0x55,  0xfc,  0xfe,  0x1d,  0xf7,  0x4f,
13782   0x90,  0xfe,  0xc0,  0x16,  0xfe,  0x36,  0x14,  0xfe,  0x1c,  0x13,  0x91,  0x4f,  0x47,  0xfe,  0x83,  0x58,
13783   0xfe,  0xaf,  0x19,  0xfe,  0x80,  0xe7,  0x10,  0xfe,  0x81,  0xe7,  0x10,  0x11,  0xfe,  0xdd,  0x00,  0x63,
13784   0x27,  0x03,  0x63,  0x27,  0xfe,  0x12,  0x45,  0x21,  0xfe,  0xb0,  0x16,  0x14,  0x06,  0x37,  0x95,  0xa9,
13785   0x02,  0x29,  0xfe,  0x39,  0xf0,  0xfe,  0x04,  0x17,  0x23,  0x03,  0xfe,  0x7e,  0x18,  0x1c,  0x1a,  0x5d,
13786   0x13,  0x0d,  0x03,  0x71,  0x05,  0xcb,  0x1c,  0x06,  0xfe,  0xef,  0x12,  0xfe,  0xe1,  0x10,  0x78,  0x2c,
13787   0x46,  0x2f,  0x07,  0x2d,  0xfe,  0x3c,  0x13,  0xfe,  0x82,  0x14,  0xfe,  0x42,  0x13,  0x3c,  0x8a,  0x0a,
13788   0x42,  0x01,  0x0e,  0xb0,  0xfe,  0x3e,  0x12,  0xf0,  0xfe,  0x45,  0x48,  0x01,  0xe3,  0xfe,  0x00,  0xcc,
13789   0xb0,  0xfe,  0xf3,  0x13,  0x3d,  0x75,  0x07,  0x10,  0xa3,  0x0a,  0x80,  0x01,  0x0e,  0xf2,  0x01,  0x6f,
13790   0xfe,  0x16,  0x10,  0x07,  0x7e,  0x85,  0xfe,  0x40,  0x14,  0xfe,  0x24,  0x12,  0xf6,  0xfe,  0xd6,  0xf0,
13791   0xfe,  0x24,  0x17,  0x17,  0x0b,  0x03,  0xfe,  0x9c,  0xe7,  0x0b,  0x0f,  0xfe,  0x15,  0x00,  0x59,  0x76,
13792   0x27,  0x01,  0xda,  0x17,  0x06,  0x03,  0x3c,  0x8a,  0x09,  0x4a,  0x1d,  0x35,  0x11,  0x2d,  0x01,  0x6f,
13793   0x17,  0x06,  0x03,  0xfe,  0x38,  0x90,  0xfe,  0xba,  0x90,  0x79,  0xc7,  0x68,  0xc8,  0xfe,  0x48,  0x55,
13794   0x34,  0xfe,  0xc9,  0x55,  0x03,  0x1e,  0x98,  0x73,  0x12,  0x98,  0x03,  0x0a,  0x99,  0x01,  0x0e,  0xf0,
13795   0x0a,  0x40,  0x01,  0x0e,  0xfe,  0x49,  0x44,  0x16,  0xfe,  0xf0,  0x17,  0x73,  0x75,  0x03,  0x0a,  0x42,
13796   0x01,  0x0e,  0x07,  0x10,  0x45,  0x0a,  0x51,  0x01,  0x9e,  0x0a,  0x40,  0x01,  0x0e,  0x73,  0x75,  0x03,
13797   0xfe,  0x4e,  0xe4,  0x1a,  0x64,  0xfe,  0x24,  0x18,  0x05,  0xfe,  0x90,  0x00,  0xfe,  0x3a,  0x45,  0x5b,
13798   0xfe,  0x4e,  0xe4,  0xc2,  0x64,  0xfe,  0x36,  0x18,  0x05,  0xfe,  0x92,  0x00,  0xfe,  0x02,  0xe6,  0x1b,
13799   0xdc,  0xfe,  0x4e,  0xe4,  0xfe,  0x0b,  0x00,  0x64,  0xfe,  0x48,  0x18,  0x05,  0xfe,  0x94,  0x00,  0xfe,
13800   0x02,  0xe6,  0x19,  0xfe,  0x08,  0x10,  0x05,  0xfe,  0x96,  0x00,  0xfe,  0x02,  0xe6,  0x2c,  0xfe,  0x4e,
13801   0x45,  0xfe,  0x0c,  0x12,  0xaf,  0xff,  0x04,  0x68,  0x54,  0xde,  0x1c,  0x69,  0x03,  0x07,  0x7a,  0xfe,
13802   0x5a,  0xf0,  0xfe,  0x74,  0x18,  0x24,  0xfe,  0x09,  0x00,  0xfe,  0x34,  0x10,  0x07,  0x1b,  0xfe,  0x5a,
13803   0xf0,  0xfe,  0x82,  0x18,  0x24,  0xc3,  0xfe,  0x26,  0x10,  0x07,  0x1a,  0x5d,  0x24,  0x2c,  0xdc,  0x07,
13804   0x0b,  0x5d,  0x24,  0x93,  0xfe,  0x0e,  0x10,  0x07,  0x06,  0x5d,  0x24,  0x4d,  0x9f,  0xad,  0x03,  0x14,
13805   0xfe,  0x09,  0x00,  0x01,  0x33,  0xfe,  0x04,  0xfe,  0x7d,  0x05,  0x7f,  0xf9,  0x03,  0x25,  0xfe,  0xca,
13806   0x18,  0xfe,  0x14,  0xf0,  0x08,  0x65,  0xfe,  0xc6,  0x18,  0x03,  0xff,  0x1a,  0x00,  0x00,
13807 };
13808 
13809 STATIC unsigned short _adv_asc3550_size =
13810         sizeof(_adv_asc3550_buf); /* 0x13AD */
13811 STATIC ADV_DCNT _adv_asc3550_chksum =
13812         0x04D52DDDUL; /* Expanded little-endian checksum. */
13813 
13814 /* Microcode buffer is kept after initialization for error recovery. */
13815 STATIC unsigned char _adv_asc38C0800_buf[] = {
13816   0x00,  0x00,  0x00,  0xf2,  0x00,  0xf0,  0x00,  0xfc,  0x00,  0x16,  0x18,  0xe4,  0x01,  0x00,  0x48,  0xe4,
13817   0x18,  0x80,  0x03,  0xf6,  0x02,  0x00,  0xce,  0x19,  0x00,  0xfa,  0xff,  0xff,  0x1c,  0x0f,  0x00,  0xf6,
13818   0x9e,  0xe7,  0xff,  0x00,  0x82,  0xe7,  0x00,  0xea,  0x01,  0xfa,  0x01,  0xe6,  0x09,  0xe7,  0x55,  0xf0,
13819   0x01,  0xf6,  0x03,  0x00,  0x04,  0x00,  0x10,  0x00,  0x1e,  0xf0,  0x85,  0xf0,  0x18,  0xf4,  0x08,  0x00,
13820   0xbc,  0x00,  0x38,  0x54,  0x00,  0xec,  0xd5,  0xf0,  0x82,  0x0d,  0x00,  0xe6,  0x86,  0xf0,  0xb1,  0xf0,
13821   0x98,  0x57,  0x01,  0xfc,  0xb4,  0x00,  0xd4,  0x01,  0x0c,  0x1c,  0x3e,  0x1c,  0x3c,  0x00,  0xbb,  0x00,
13822   0x00,  0x10,  0xba,  0x19,  0x02,  0x80,  0x32,  0xf0,  0x7c,  0x0d,  0x02,  0x13,  0xba,  0x13,  0x18,  0x40,
13823   0x00,  0x57,  0x01,  0xea,  0x02,  0xfc,  0x03,  0xfc,  0x3e,  0x00,  0x6c,  0x01,  0x6e,  0x01,  0x74,  0x01,
13824   0x76,  0x01,  0xb9,  0x54,  0x3e,  0x57,  0x00,  0x80,  0x03,  0xe6,  0xb6,  0x00,  0xc0,  0x00,  0x01,  0x01,
13825   0x3e,  0x01,  0x7a,  0x01,  0xca,  0x08,  0xce,  0x10,  0x16,  0x11,  0x04,  0x12,  0x08,  0x12,  0x02,  0x4a,
13826   0xbb,  0x55,  0x3c,  0x56,  0x03,  0x58,  0x1b,  0x80,  0x30,  0xe4,  0x4b,  0xe4,  0x5d,  0xf0,  0x02,  0xfa,
13827   0x20,  0x00,  0x32,  0x00,  0x40,  0x00,  0x80,  0x00,  0x24,  0x01,  0x3c,  0x01,  0x68,  0x01,  0x6a,  0x01,
13828   0x70,  0x01,  0x72,  0x01,  0x78,  0x01,  0x7c,  0x01,  0x62,  0x0a,  0x86,  0x0d,  0x06,  0x13,  0x4c,  0x1c,
13829   0x04,  0x80,  0x4a,  0xe4,  0x02,  0xee,  0x5b,  0xf0,  0x03,  0xf7,  0x0c,  0x00,  0x0f,  0x00,  0x47,  0x00,
13830   0xbe,  0x00,  0x00,  0x01,  0x20,  0x11,  0x5c,  0x16,  0x32,  0x1c,  0x38,  0x1c,  0x4e,  0x1c,  0x10,  0x44,
13831   0x00,  0x4c,  0x04,  0xea,  0x5c,  0xf0,  0xa7,  0xf0,  0x04,  0xf6,  0x03,  0xfa,  0x05,  0x00,  0x34,  0x00,
13832   0x36,  0x00,  0x98,  0x00,  0xcc,  0x00,  0x20,  0x01,  0x4e,  0x01,  0x4a,  0x0b,  0x42,  0x0c,  0x12,  0x0f,
13833   0x0c,  0x10,  0x22,  0x11,  0x0a,  0x12,  0x04,  0x13,  0x30,  0x1c,  0x02,  0x48,  0x00,  0x4e,  0x42,  0x54,
13834   0x44,  0x55,  0xbd,  0x56,  0x06,  0x83,  0x00,  0xdc,  0x05,  0xf0,  0x09,  0xf0,  0x59,  0xf0,  0xb8,  0xf0,
13835   0x4b,  0xf4,  0x06,  0xf7,  0x0e,  0xf7,  0x04,  0xfc,  0x05,  0xfc,  0x06,  0x00,  0x19,  0x00,  0x33,  0x00,
13836   0x9b,  0x00,  0xa4,  0x00,  0xb5,  0x00,  0xba,  0x00,  0xd0,  0x00,  0xe1,  0x00,  0xe7,  0x00,  0xe2,  0x03,
13837   0x08,  0x0f,  0x02,  0x10,  0x04,  0x10,  0x0a,  0x10,  0x0a,  0x13,  0x0c,  0x13,  0x12,  0x13,  0x24,  0x14,
13838   0x34,  0x14,  0x04,  0x16,  0x08,  0x16,  0xa4,  0x17,  0x20,  0x1c,  0x34,  0x1c,  0x36,  0x1c,  0x08,  0x44,
13839   0x38,  0x44,  0x91,  0x44,  0x0a,  0x45,  0x48,  0x46,  0x01,  0x48,  0x68,  0x54,  0x3a,  0x55,  0x83,  0x55,
13840   0xe5,  0x55,  0xb0,  0x57,  0x01,  0x58,  0x83,  0x59,  0x05,  0xe6,  0x0b,  0xf0,  0x0c,  0xf0,  0x04,  0xf8,
13841   0x05,  0xf8,  0x07,  0x00,  0x0a,  0x00,  0x1c,  0x00,  0x1e,  0x00,  0x9e,  0x00,  0xa8,  0x00,  0xaa,  0x00,
13842   0xb9,  0x00,  0xe0,  0x00,  0x22,  0x01,  0x26,  0x01,  0x79,  0x01,  0x7e,  0x01,  0xc4,  0x01,  0xc6,  0x01,
13843   0x80,  0x02,  0x5e,  0x03,  0xee,  0x04,  0x9a,  0x06,  0xf8,  0x07,  0x62,  0x08,  0x68,  0x08,  0x69,  0x08,
13844   0xd6,  0x08,  0xe9,  0x09,  0xfa,  0x0b,  0x2e,  0x0f,  0x12,  0x10,  0x1a,  0x10,  0xed,  0x10,  0xf1,  0x10,
13845   0x2a,  0x11,  0x06,  0x12,  0x0c,  0x12,  0x3e,  0x12,  0x10,  0x13,  0x16,  0x13,  0x1e,  0x13,  0x46,  0x14,
13846   0x76,  0x14,  0x82,  0x14,  0x36,  0x15,  0xca,  0x15,  0x6b,  0x18,  0xbe,  0x18,  0xca,  0x18,  0xe6,  0x19,
13847   0x12,  0x1c,  0x46,  0x1c,  0x9c,  0x32,  0x00,  0x40,  0x0e,  0x47,  0xfe,  0x9c,  0xf0,  0x2b,  0x02,  0xfe,
13848   0xac,  0x0d,  0xff,  0x10,  0x00,  0x00,  0xd7,  0xfe,  0xe8,  0x19,  0x00,  0xd6,  0xfe,  0x84,  0x01,  0xff,
13849   0x03,  0x00,  0x00,  0xfe,  0x93,  0x15,  0xfe,  0x0f,  0x05,  0xff,  0x38,  0x00,  0x00,  0xfe,  0x57,  0x24,
13850   0x00,  0xfe,  0x4c,  0x00,  0x5b,  0xff,  0x04,  0x00,  0x00,  0x11,  0xff,  0x09,  0x00,  0x00,  0xff,  0x08,
13851   0x01,  0x01,  0xff,  0x08,  0xff,  0xff,  0xff,  0x27,  0x00,  0x00,  0xff,  0x10,  0xff,  0xff,  0xff,  0x11,
13852   0x00,  0x00,  0xfe,  0x78,  0x56,  0xfe,  0x34,  0x12,  0xff,  0x21,  0x00,  0x00,  0xfe,  0x04,  0xf7,  0xd6,
13853   0x2c,  0x99,  0x0a,  0x01,  0xfe,  0xc2,  0x0f,  0xfe,  0x04,  0xf7,  0xd6,  0x99,  0x0a,  0x42,  0x2c,  0xfe,
13854   0x3d,  0xf0,  0xfe,  0x06,  0x02,  0xfe,  0x20,  0xf0,  0xa7,  0xfe,  0x91,  0xf0,  0xfe,  0xf4,  0x01,  0xfe,
13855   0x90,  0xf0,  0xfe,  0xf4,  0x01,  0xfe,  0x8f,  0xf0,  0xa7,  0x03,  0x5d,  0x4d,  0x02,  0xfe,  0xc8,  0x0d,
13856   0x01,  0xfe,  0x38,  0x0e,  0xfe,  0xdd,  0x12,  0xfe,  0xfc,  0x10,  0xfe,  0x28,  0x1c,  0x03,  0xfe,  0xa6,
13857   0x00,  0xfe,  0xd3,  0x12,  0x41,  0x14,  0xfe,  0xa6,  0x00,  0xc2,  0xfe,  0x48,  0xf0,  0xfe,  0x8a,  0x02,
13858   0xfe,  0x49,  0xf0,  0xfe,  0xa4,  0x02,  0xfe,  0x4a,  0xf0,  0xfe,  0xc2,  0x02,  0xfe,  0x46,  0xf0,  0xfe,
13859   0x54,  0x02,  0xfe,  0x47,  0xf0,  0xfe,  0x5a,  0x02,  0xfe,  0x43,  0xf0,  0xfe,  0x48,  0x02,  0xfe,  0x44,
13860   0xf0,  0xfe,  0x4c,  0x02,  0xfe,  0x45,  0xf0,  0xfe,  0x50,  0x02,  0x18,  0x0a,  0xaa,  0x18,  0x06,  0x14,
13861   0xa1,  0x02,  0x2b,  0xfe,  0x00,  0x1c,  0xe7,  0xfe,  0x02,  0x1c,  0xe6,  0xfe,  0x1e,  0x1c,  0xfe,  0xe9,
13862   0x10,  0x01,  0xfe,  0x18,  0x18,  0xfe,  0xe7,  0x10,  0xfe,  0x06,  0xfc,  0xce,  0x09,  0x70,  0x01,  0xa8,
13863   0x02,  0x2b,  0x15,  0x59,  0x39,  0xa2,  0x01,  0xfe,  0x58,  0x10,  0x09,  0x70,  0x01,  0x87,  0xfe,  0xbd,
13864   0x10,  0x09,  0x70,  0x01,  0x87,  0xfe,  0xad,  0x10,  0xfe,  0x16,  0x1c,  0xfe,  0x58,  0x1c,  0x18,  0x06,
13865   0x14,  0xa1,  0x2c,  0x1c,  0x2b,  0xfe,  0x3d,  0xf0,  0xfe,  0x06,  0x02,  0x23,  0xfe,  0x98,  0x02,  0xfe,
13866   0x5a,  0x1c,  0xf8,  0xfe,  0x14,  0x1c,  0x15,  0xfe,  0x30,  0x00,  0x39,  0xa2,  0x01,  0xfe,  0x48,  0x10,
13867   0x18,  0x06,  0x14,  0xa1,  0x02,  0xd7,  0x22,  0x20,  0x07,  0x11,  0x35,  0xfe,  0x69,  0x10,  0x18,  0x06,
13868   0x14,  0xa1,  0xfe,  0x04,  0xec,  0x20,  0x4f,  0x43,  0x13,  0x20,  0xfe,  0x05,  0xf6,  0xce,  0x01,  0xfe,
13869   0x4a,  0x17,  0x08,  0x54,  0x58,  0x37,  0x12,  0x2f,  0x42,  0x92,  0x01,  0xfe,  0x82,  0x16,  0x02,  0x2b,
13870   0x09,  0x46,  0x01,  0x0e,  0x07,  0x00,  0x66,  0x01,  0x73,  0xfe,  0x18,  0x10,  0xfe,  0x41,  0x58,  0x09,
13871   0xa4,  0x01,  0x0e,  0xfe,  0xc8,  0x54,  0x6b,  0xfe,  0x10,  0x03,  0x01,  0xfe,  0x82,  0x16,  0x02,  0x2b,
13872   0x2c,  0x4f,  0xfe,  0x02,  0xe8,  0x2a,  0xfe,  0xbf,  0x57,  0xfe,  0x9e,  0x43,  0xfe,  0x77,  0x57,  0xfe,
13873   0x27,  0xf0,  0xfe,  0xe0,  0x01,  0xfe,  0x07,  0x4b,  0xfe,  0x20,  0xf0,  0xa7,  0xfe,  0x40,  0x1c,  0x1c,
13874   0xd9,  0xfe,  0x26,  0xf0,  0xfe,  0x5a,  0x03,  0xfe,  0xa0,  0xf0,  0xfe,  0x48,  0x03,  0xfe,  0x11,  0xf0,
13875   0xa7,  0xfe,  0xef,  0x10,  0xfe,  0x9f,  0xf0,  0xfe,  0x68,  0x03,  0xf9,  0x10,  0xfe,  0x11,  0x00,  0x02,
13876   0x65,  0x2c,  0xfe,  0x48,  0x1c,  0xf9,  0x08,  0x05,  0x1b,  0xfe,  0x18,  0x13,  0x21,  0x22,  0xa3,  0xb7,
13877   0x13,  0xa3,  0x09,  0x46,  0x01,  0x0e,  0xb7,  0x78,  0x01,  0xfe,  0xb4,  0x16,  0x12,  0xd1,  0x1c,  0xd9,
13878   0xfe,  0x01,  0xf0,  0xd9,  0xfe,  0x82,  0xf0,  0xfe,  0x96,  0x03,  0xfa,  0x12,  0xfe,  0xe4,  0x00,  0x27,
13879   0xfe,  0xa8,  0x03,  0x1c,  0x34,  0x1d,  0xfe,  0xb8,  0x03,  0x01,  0x4b,  0xfe,  0x06,  0xf0,  0xfe,  0xc8,
13880   0x03,  0x95,  0x86,  0xfe,  0x0a,  0xf0,  0xfe,  0x8a,  0x06,  0x02,  0x24,  0x03,  0x70,  0x28,  0x17,  0xfe,
13881   0xfa,  0x04,  0x15,  0x6d,  0x01,  0x36,  0x7b,  0xfe,  0x6a,  0x02,  0x02,  0xd8,  0xf9,  0x2c,  0x99,  0x19,
13882   0xfe,  0x67,  0x1b,  0xfe,  0xbf,  0x57,  0xfe,  0x77,  0x57,  0xfe,  0x48,  0x1c,  0x74,  0x01,  0xaf,  0x8c,
13883   0x09,  0x46,  0x01,  0x0e,  0x07,  0x00,  0x17,  0xda,  0x09,  0xd1,  0x01,  0x0e,  0x8d,  0x51,  0x64,  0x79,
13884   0x2a,  0x03,  0x70,  0x28,  0xfe,  0x10,  0x12,  0x15,  0x6d,  0x01,  0x36,  0x7b,  0xfe,  0x6a,  0x02,  0x02,
13885   0xd8,  0xc7,  0x81,  0xc8,  0x83,  0x1c,  0x24,  0x27,  0xfe,  0x40,  0x04,  0x1d,  0xfe,  0x3c,  0x04,  0x3b,
13886   0xfe,  0xa0,  0x00,  0xfe,  0x9b,  0x57,  0xfe,  0x4e,  0x12,  0x2d,  0xff,  0x02,  0x00,  0x10,  0x01,  0x0b,
13887   0x1d,  0xfe,  0xe4,  0x04,  0x2d,  0x01,  0x0b,  0x1d,  0x24,  0x33,  0x31,  0xde,  0xfe,  0x4c,  0x44,  0xfe,
13888   0x4c,  0x12,  0x51,  0xfe,  0x44,  0x48,  0x0f,  0x6f,  0xfe,  0x4c,  0x54,  0x6b,  0xda,  0x4f,  0x79,  0x2a,
13889   0xfe,  0x06,  0x80,  0xfe,  0x48,  0x47,  0xfe,  0x62,  0x13,  0x08,  0x05,  0x1b,  0xfe,  0x2a,  0x13,  0x32,
13890   0x07,  0x82,  0xfe,  0x52,  0x13,  0xfe,  0x20,  0x10,  0x0f,  0x6f,  0xfe,  0x4c,  0x54,  0x6b,  0xda,  0xfe,
13891   0x06,  0x80,  0xfe,  0x48,  0x47,  0xfe,  0x40,  0x13,  0x08,  0x05,  0x1b,  0xfe,  0x08,  0x13,  0x32,  0x07,
13892   0x82,  0xfe,  0x30,  0x13,  0x08,  0x05,  0x1b,  0xfe,  0x1c,  0x12,  0x15,  0x9d,  0x08,  0x05,  0x06,  0x4d,
13893   0x15,  0xfe,  0x0d,  0x00,  0x01,  0x36,  0x7b,  0xfe,  0x64,  0x0d,  0x02,  0x24,  0x2d,  0x12,  0xfe,  0xe6,
13894   0x00,  0xfe,  0x1c,  0x90,  0xfe,  0x40,  0x5c,  0x04,  0x15,  0x9d,  0x01,  0x36,  0x02,  0x2b,  0xfe,  0x42,
13895   0x5b,  0x99,  0x19,  0xfe,  0x46,  0x59,  0xfe,  0xbf,  0x57,  0xfe,  0x77,  0x57,  0xfe,  0x87,  0x80,  0xfe,
13896   0x31,  0xe4,  0x5b,  0x08,  0x05,  0x0a,  0xfe,  0x84,  0x13,  0xfe,  0x20,  0x80,  0x07,  0x19,  0xfe,  0x7c,
13897   0x12,  0x53,  0x05,  0x06,  0xfe,  0x6c,  0x13,  0x03,  0xfe,  0xa2,  0x00,  0x28,  0x17,  0xfe,  0x90,  0x05,
13898   0xfe,  0x31,  0xe4,  0x5a,  0x53,  0x05,  0x0a,  0xfe,  0x56,  0x13,  0x03,  0xfe,  0xa0,  0x00,  0x28,  0xfe,
13899   0x4e,  0x12,  0x67,  0xff,  0x02,  0x00,  0x10,  0x27,  0xfe,  0x48,  0x05,  0x1c,  0x34,  0xfe,  0x89,  0x48,
13900   0xff,  0x02,  0x00,  0x10,  0x27,  0xfe,  0x56,  0x05,  0x26,  0xfe,  0xa8,  0x05,  0x12,  0xfe,  0xe3,  0x00,
13901   0x21,  0x53,  0xfe,  0x4a,  0xf0,  0xfe,  0x76,  0x05,  0xfe,  0x49,  0xf0,  0xfe,  0x70,  0x05,  0x88,  0x25,
13902   0xfe,  0x21,  0x00,  0xab,  0x25,  0xfe,  0x22,  0x00,  0xaa,  0x25,  0x58,  0xfe,  0x09,  0x48,  0xff,  0x02,
13903   0x00,  0x10,  0x27,  0xfe,  0x86,  0x05,  0x26,  0xfe,  0xa8,  0x05,  0xfe,  0xe2,  0x08,  0x53,  0x05,  0xcb,
13904   0x4d,  0x01,  0xb0,  0x25,  0x06,  0x13,  0xd3,  0x39,  0xfe,  0x27,  0x01,  0x08,  0x05,  0x1b,  0xfe,  0x22,
13905   0x12,  0x41,  0x01,  0xb2,  0x15,  0x9d,  0x08,  0x05,  0x06,  0x4d,  0x15,  0xfe,  0x0d,  0x00,  0x01,  0x36,
13906   0x7b,  0xfe,  0x64,  0x0d,  0x02,  0x24,  0x03,  0xfe,  0x9c,  0x00,  0x28,  0xeb,  0x03,  0x5c,  0x28,  0xfe,
13907   0x36,  0x13,  0x41,  0x01,  0xb2,  0x26,  0xfe,  0x18,  0x06,  0x09,  0x06,  0x53,  0x05,  0x1f,  0xfe,  0x02,
13908   0x12,  0x50,  0x01,  0xfe,  0x9e,  0x15,  0x1d,  0xfe,  0x0e,  0x06,  0x12,  0xa5,  0x01,  0x4b,  0x12,  0xfe,
13909   0xe5,  0x00,  0x03,  0x5c,  0xc1,  0x0c,  0x5c,  0x03,  0xcd,  0x28,  0xfe,  0x62,  0x12,  0x03,  0x45,  0x28,
13910   0xfe,  0x5a,  0x13,  0x01,  0xfe,  0x0c,  0x19,  0x01,  0xfe,  0x76,  0x19,  0xfe,  0x43,  0x48,  0xc4,  0xcc,
13911   0x0f,  0x71,  0xff,  0x02,  0x00,  0x57,  0x52,  0x93,  0x1e,  0x43,  0x8b,  0xc4,  0x6e,  0x41,  0x01,  0xb2,
13912   0x26,  0xfe,  0x82,  0x06,  0x53,  0x05,  0x1a,  0xe9,  0x91,  0x09,  0x59,  0x01,  0xfe,  0xcc,  0x15,  0x1d,
13913   0xfe,  0x78,  0x06,  0x12,  0xa5,  0x01,  0x4b,  0x12,  0xfe,  0xe5,  0x00,  0x03,  0x45,  0xc1,  0x0c,  0x45,
13914   0x18,  0x06,  0x01,  0xb2,  0xfa,  0x76,  0x74,  0x01,  0xaf,  0x8c,  0x12,  0xfe,  0xe2,  0x00,  0x27,  0xdb,
13915   0x1c,  0x34,  0xfe,  0x0a,  0xf0,  0xfe,  0xb6,  0x06,  0x94,  0xfe,  0x6c,  0x07,  0xfe,  0x06,  0xf0,  0xfe,
13916   0x74,  0x07,  0x95,  0x86,  0x02,  0x24,  0x08,  0x05,  0x0a,  0xfe,  0x2e,  0x12,  0x16,  0x19,  0x01,  0x0b,
13917   0x16,  0x00,  0x01,  0x0b,  0x16,  0x00,  0x01,  0x0b,  0x16,  0x00,  0x01,  0x0b,  0xfe,  0x99,  0xa4,  0x01,
13918   0x0b,  0x16,  0x00,  0x02,  0xfe,  0x42,  0x08,  0x68,  0x05,  0x1a,  0xfe,  0x38,  0x12,  0x08,  0x05,  0x1a,
13919   0xfe,  0x30,  0x13,  0x16,  0xfe,  0x1b,  0x00,  0x01,  0x0b,  0x16,  0x00,  0x01,  0x0b,  0x16,  0x00,  0x01,
13920   0x0b,  0x16,  0x00,  0x01,  0x0b,  0x16,  0x06,  0x01,  0x0b,  0x16,  0x00,  0x02,  0xe2,  0x6c,  0x58,  0xbe,
13921   0x50,  0xfe,  0x9a,  0x81,  0x55,  0x1b,  0x7a,  0xfe,  0x42,  0x07,  0x09,  0x1b,  0xfe,  0x09,  0x6f,  0xba,
13922   0xfe,  0xca,  0x45,  0xfe,  0x32,  0x12,  0x69,  0x6d,  0x8b,  0x6c,  0x7f,  0x27,  0xfe,  0x54,  0x07,  0x1c,
13923   0x34,  0xfe,  0x0a,  0xf0,  0xfe,  0x42,  0x07,  0x95,  0x86,  0x94,  0xfe,  0x6c,  0x07,  0x02,  0x24,  0x01,
13924   0x4b,  0x02,  0xdb,  0x16,  0x1f,  0x02,  0xdb,  0xfe,  0x9c,  0xf7,  0xdc,  0xfe,  0x2c,  0x90,  0xfe,  0xae,
13925   0x90,  0x56,  0xfe,  0xda,  0x07,  0x0c,  0x60,  0x14,  0x61,  0x08,  0x54,  0x5a,  0x37,  0x22,  0x20,  0x07,
13926   0x11,  0xfe,  0x0e,  0x12,  0x8d,  0xfe,  0x80,  0x80,  0x39,  0x20,  0x6a,  0x2a,  0xfe,  0x06,  0x10,  0xfe,
13927   0x83,  0xe7,  0xfe,  0x48,  0x00,  0xab,  0xfe,  0x03,  0x40,  0x08,  0x54,  0x5b,  0x37,  0x01,  0xb3,  0xb8,
13928   0xfe,  0x1f,  0x40,  0x13,  0x62,  0x01,  0xef,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0xfe,  0x44,  0x51,
13929   0xfe,  0xc6,  0x51,  0x88,  0xfe,  0x08,  0x90,  0xfe,  0x8a,  0x90,  0x0c,  0x5e,  0x14,  0x5f,  0xfe,  0x0c,
13930   0x90,  0xfe,  0x8e,  0x90,  0xfe,  0x40,  0x50,  0xfe,  0xc2,  0x50,  0x0c,  0x3d,  0x14,  0x3e,  0xfe,  0x4a,
13931   0x10,  0x08,  0x05,  0x5a,  0xfe,  0x2a,  0x12,  0xfe,  0x2c,  0x90,  0xfe,  0xae,  0x90,  0x0c,  0x60,  0x14,
13932   0x61,  0x08,  0x05,  0x5b,  0x8b,  0x01,  0xb3,  0xfe,  0x1f,  0x80,  0x13,  0x62,  0xfe,  0x44,  0x90,  0xfe,
13933   0xc6,  0x90,  0x0c,  0x3f,  0x14,  0x40,  0xfe,  0x08,  0x90,  0xfe,  0x8a,  0x90,  0x0c,  0x5e,  0x14,  0x5f,
13934   0xfe,  0x40,  0x90,  0xfe,  0xc2,  0x90,  0x0c,  0x3d,  0x14,  0x3e,  0x0c,  0x2e,  0x14,  0x3c,  0x21,  0x0c,
13935   0x49,  0x0c,  0x63,  0x08,  0x54,  0x1f,  0x37,  0x2c,  0x0f,  0xfe,  0x4e,  0x11,  0x27,  0xdd,  0xfe,  0x9e,
13936   0xf0,  0xfe,  0x76,  0x08,  0xbc,  0x17,  0x34,  0x2c,  0x77,  0xe6,  0xc5,  0xfe,  0x9a,  0x08,  0xc6,  0xfe,
13937   0xb8,  0x08,  0x94,  0xfe,  0x8e,  0x08,  0xfe,  0x06,  0xf0,  0xfe,  0x94,  0x08,  0x95,  0x86,  0x02,  0x24,
13938   0x01,  0x4b,  0xfe,  0xc9,  0x10,  0x16,  0x1f,  0xfe,  0xc9,  0x10,  0x68,  0x05,  0x06,  0xfe,  0x10,  0x12,
13939   0x68,  0x05,  0x0a,  0x4e,  0x08,  0x05,  0x0a,  0xfe,  0x90,  0x12,  0xfe,  0x2e,  0x1c,  0x02,  0xfe,  0x18,
13940   0x0b,  0x68,  0x05,  0x06,  0x4e,  0x68,  0x05,  0x0a,  0xfe,  0x7a,  0x12,  0xfe,  0x2c,  0x1c,  0xfe,  0xaa,
13941   0xf0,  0xfe,  0xd2,  0x09,  0xfe,  0xac,  0xf0,  0xfe,  0x00,  0x09,  0x02,  0xfe,  0xde,  0x09,  0xfe,  0xb7,
13942   0xf0,  0xfe,  0xfc,  0x08,  0xfe,  0x02,  0xf6,  0x1a,  0x50,  0xfe,  0x70,  0x18,  0xfe,  0xf1,  0x18,  0xfe,
13943   0x40,  0x55,  0xfe,  0xe1,  0x55,  0xfe,  0x10,  0x58,  0xfe,  0x91,  0x58,  0xfe,  0x14,  0x59,  0xfe,  0x95,
13944   0x59,  0x1c,  0x85,  0xfe,  0x8c,  0xf0,  0xfe,  0xfc,  0x08,  0xfe,  0xac,  0xf0,  0xfe,  0xf0,  0x08,  0xb5,
13945   0xfe,  0xcb,  0x10,  0xfe,  0xad,  0xf0,  0xfe,  0x0c,  0x09,  0x02,  0xfe,  0x18,  0x0b,  0xb6,  0xfe,  0xbf,
13946   0x10,  0xfe,  0x2b,  0xf0,  0x85,  0xf4,  0x1e,  0xfe,  0x00,  0xfe,  0xfe,  0x1c,  0x12,  0xc2,  0xfe,  0xd2,
13947   0xf0,  0x85,  0xfe,  0x76,  0x18,  0x1e,  0x19,  0x17,  0x85,  0x03,  0xd2,  0x1e,  0x06,  0x17,  0x85,  0xc5,
13948   0x4a,  0xc6,  0x4a,  0xb5,  0xb6,  0xfe,  0x89,  0x10,  0x74,  0x67,  0x2d,  0x15,  0x9d,  0x01,  0x36,  0x10,
13949   0xfe,  0x35,  0x00,  0xfe,  0x01,  0xf0,  0x65,  0x10,  0x80,  0x02,  0x65,  0xfe,  0x98,  0x80,  0xfe,  0x19,
13950   0xe4,  0x0a,  0xfe,  0x1a,  0x12,  0x51,  0xfe,  0x19,  0x82,  0xfe,  0x6c,  0x18,  0xfe,  0x44,  0x54,  0xbe,
13951   0xfe,  0x19,  0x81,  0xfe,  0x74,  0x18,  0x8f,  0x90,  0x17,  0xfe,  0xce,  0x08,  0x02,  0x4a,  0x08,  0x05,
13952   0x5a,  0xec,  0x03,  0x2e,  0x29,  0x3c,  0x0c,  0x3f,  0x14,  0x40,  0x9b,  0x2e,  0x9c,  0x3c,  0xfe,  0x6c,
13953   0x18,  0xfe,  0xed,  0x18,  0xfe,  0x44,  0x54,  0xfe,  0xe5,  0x54,  0x3a,  0x3f,  0x3b,  0x40,  0x03,  0x49,
13954   0x29,  0x63,  0x8f,  0xfe,  0xe3,  0x54,  0xfe,  0x74,  0x18,  0xfe,  0xf5,  0x18,  0x8f,  0xfe,  0xe3,  0x54,
13955   0x90,  0xc0,  0x56,  0xfe,  0xce,  0x08,  0x02,  0x4a,  0xfe,  0x37,  0xf0,  0xfe,  0xda,  0x09,  0xfe,  0x8b,
13956   0xf0,  0xfe,  0x60,  0x09,  0x02,  0x4a,  0x08,  0x05,  0x0a,  0x23,  0xfe,  0xfa,  0x0a,  0x3a,  0x49,  0x3b,
13957   0x63,  0x56,  0xfe,  0x3e,  0x0a,  0x0f,  0xfe,  0xc0,  0x07,  0x41,  0x98,  0x00,  0xad,  0xfe,  0x01,  0x59,
13958   0xfe,  0x52,  0xf0,  0xfe,  0x0c,  0x0a,  0x8f,  0x7a,  0xfe,  0x24,  0x0a,  0x3a,  0x49,  0x8f,  0xfe,  0xe3,
13959   0x54,  0x57,  0x49,  0x7d,  0x63,  0xfe,  0x14,  0x58,  0xfe,  0x95,  0x58,  0x02,  0x4a,  0x3a,  0x49,  0x3b,
13960   0x63,  0xfe,  0x14,  0x59,  0xfe,  0x95,  0x59,  0xbe,  0x57,  0x49,  0x57,  0x63,  0x02,  0x4a,  0x08,  0x05,
13961   0x5a,  0xfe,  0x82,  0x12,  0x08,  0x05,  0x1f,  0xfe,  0x66,  0x13,  0x22,  0x62,  0xb7,  0xfe,  0x03,  0xa1,
13962   0xfe,  0x83,  0x80,  0xfe,  0xc8,  0x44,  0xfe,  0x2e,  0x13,  0xfe,  0x04,  0x91,  0xfe,  0x86,  0x91,  0x6a,
13963   0x2a,  0xfe,  0x40,  0x59,  0xfe,  0xc1,  0x59,  0x56,  0xe0,  0x03,  0x60,  0x29,  0x61,  0x0c,  0x7f,  0x14,
13964   0x80,  0x57,  0x60,  0x7d,  0x61,  0x01,  0xb3,  0xb8,  0x6a,  0x2a,  0x13,  0x62,  0x9b,  0x2e,  0x9c,  0x3c,
13965   0x3a,  0x3f,  0x3b,  0x40,  0x90,  0xc0,  0xfe,  0x04,  0xfa,  0x2e,  0xfe,  0x05,  0xfa,  0x3c,  0x01,  0xef,
13966   0xfe,  0x36,  0x10,  0x21,  0x0c,  0x7f,  0x0c,  0x80,  0x3a,  0x3f,  0x3b,  0x40,  0xe4,  0x08,  0x05,  0x1f,
13967   0x17,  0xe0,  0x3a,  0x3d,  0x3b,  0x3e,  0x08,  0x05,  0xfe,  0xf7,  0x00,  0x37,  0x03,  0x5e,  0x29,  0x5f,
13968   0xfe,  0x10,  0x58,  0xfe,  0x91,  0x58,  0x57,  0x49,  0x7d,  0x63,  0x02,  0xfe,  0xf4,  0x09,  0x08,  0x05,
13969   0x1f,  0x17,  0xe0,  0x08,  0x05,  0xfe,  0xf7,  0x00,  0x37,  0xbe,  0xfe,  0x19,  0x81,  0x50,  0xfe,  0x10,
13970   0x90,  0xfe,  0x92,  0x90,  0xfe,  0xd3,  0x10,  0x32,  0x07,  0xa6,  0x17,  0xfe,  0x08,  0x09,  0x12,  0xa6,
13971   0x08,  0x05,  0x0a,  0xfe,  0x14,  0x13,  0x03,  0x3d,  0x29,  0x3e,  0x56,  0xfe,  0x08,  0x09,  0xfe,  0x0c,
13972   0x58,  0xfe,  0x8d,  0x58,  0x02,  0x4a,  0x21,  0x41,  0xfe,  0x19,  0x80,  0xe7,  0x08,  0x05,  0x0a,  0xfe,
13973   0x1a,  0x12,  0xfe,  0x6c,  0x19,  0xfe,  0x19,  0x41,  0xf4,  0xc2,  0xfe,  0xd1,  0xf0,  0xe2,  0x15,  0x7e,
13974   0x01,  0x36,  0x10,  0xfe,  0x44,  0x00,  0xfe,  0x8e,  0x10,  0xfe,  0x6c,  0x19,  0x57,  0x3d,  0xfe,  0xed,
13975   0x19,  0x7d,  0x3e,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0xf4,  0x1e,  0xfe,  0x00,  0xff,  0x35,  0xfe,
13976   0x74,  0x10,  0xc2,  0xfe,  0xd2,  0xf0,  0xfe,  0xa6,  0x0b,  0xfe,  0x76,  0x18,  0x1e,  0x19,  0x8a,  0x03,
13977   0xd2,  0x1e,  0x06,  0xfe,  0x08,  0x13,  0x10,  0xfe,  0x16,  0x00,  0x02,  0x65,  0xfe,  0xd1,  0xf0,  0xfe,
13978   0xb8,  0x0b,  0x15,  0x7e,  0x01,  0x36,  0x10,  0xfe,  0x17,  0x00,  0xfe,  0x42,  0x10,  0xfe,  0xce,  0xf0,
13979   0xfe,  0xbe,  0x0b,  0xfe,  0x3c,  0x10,  0xfe,  0xcd,  0xf0,  0xfe,  0xca,  0x0b,  0x10,  0xfe,  0x22,  0x00,
13980   0x02,  0x65,  0xfe,  0xcb,  0xf0,  0xfe,  0xd6,  0x0b,  0x10,  0xfe,  0x24,  0x00,  0x02,  0x65,  0xfe,  0xd0,
13981   0xf0,  0xfe,  0xe0,  0x0b,  0x10,  0x9e,  0xe5,  0xfe,  0xcf,  0xf0,  0xfe,  0xea,  0x0b,  0x10,  0x58,  0xfe,
13982   0x10,  0x10,  0xfe,  0xcc,  0xf0,  0xe2,  0x68,  0x05,  0x1f,  0x4d,  0x10,  0xfe,  0x12,  0x00,  0x2c,  0x0f,
13983   0xfe,  0x4e,  0x11,  0x27,  0xfe,  0x00,  0x0c,  0xfe,  0x9e,  0xf0,  0xfe,  0x14,  0x0c,  0xbc,  0x17,  0x34,
13984   0x2c,  0x77,  0xe6,  0xc5,  0x24,  0xc6,  0x24,  0x2c,  0xfa,  0x27,  0xfe,  0x20,  0x0c,  0x1c,  0x34,  0x94,
13985   0xfe,  0x3c,  0x0c,  0x95,  0x86,  0xc5,  0xdc,  0xc6,  0xdc,  0x02,  0x24,  0x01,  0x4b,  0xfe,  0xdb,  0x10,
13986   0x12,  0xfe,  0xe8,  0x00,  0xb5,  0xb6,  0x74,  0xc7,  0x81,  0xc8,  0x83,  0xfe,  0x89,  0xf0,  0x24,  0x33,
13987   0x31,  0xe1,  0xc7,  0x81,  0xc8,  0x83,  0x27,  0xfe,  0x66,  0x0c,  0x1d,  0x24,  0x33,  0x31,  0xdf,  0xbc,
13988   0x4e,  0x10,  0xfe,  0x42,  0x00,  0x02,  0x65,  0x7c,  0x06,  0xfe,  0x81,  0x49,  0x17,  0xfe,  0x2c,  0x0d,
13989   0x08,  0x05,  0x0a,  0xfe,  0x44,  0x13,  0x10,  0x00,  0x55,  0x0a,  0xfe,  0x54,  0x12,  0x55,  0xfe,  0x28,
13990   0x00,  0x23,  0xfe,  0x9a,  0x0d,  0x09,  0x46,  0x01,  0x0e,  0x07,  0x00,  0x66,  0x44,  0xfe,  0x28,  0x00,
13991   0xfe,  0xe2,  0x10,  0x01,  0xf5,  0x01,  0xf6,  0x09,  0xa4,  0x01,  0xfe,  0x26,  0x0f,  0x64,  0x12,  0x2f,
13992   0x01,  0x73,  0x02,  0x2b,  0x10,  0xfe,  0x44,  0x00,  0x55,  0x0a,  0xe9,  0x44,  0x0a,  0xfe,  0xb4,  0x10,
13993   0x01,  0xb0,  0x44,  0x0a,  0xfe,  0xaa,  0x10,  0x01,  0xb0,  0xfe,  0x19,  0x82,  0xfe,  0x34,  0x46,  0xac,
13994   0x44,  0x0a,  0x10,  0xfe,  0x43,  0x00,  0xfe,  0x96,  0x10,  0x08,  0x54,  0x0a,  0x37,  0x01,  0xf5,  0x01,
13995   0xf6,  0x64,  0x12,  0x2f,  0x01,  0x73,  0x99,  0x0a,  0x64,  0x42,  0x92,  0x02,  0xfe,  0x2e,  0x03,  0x08,
13996   0x05,  0x0a,  0x8a,  0x44,  0x0a,  0x10,  0x00,  0xfe,  0x5c,  0x10,  0x68,  0x05,  0x1a,  0xfe,  0x58,  0x12,
13997   0x08,  0x05,  0x1a,  0xfe,  0x50,  0x13,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x50,  0x0d,  0xfe,
13998   0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x56,  0x0d,  0x08,  0x54,  0x1a,  0x37,  0xfe,  0xa9,  0x10,  0x10,
13999   0xfe,  0x15,  0x00,  0xfe,  0x04,  0xe6,  0x0a,  0x50,  0xfe,  0x2e,  0x10,  0x10,  0xfe,  0x13,  0x00,  0xfe,
14000   0x10,  0x10,  0x10,  0x6f,  0xab,  0x10,  0xfe,  0x41,  0x00,  0xaa,  0x10,  0xfe,  0x24,  0x00,  0x8c,  0xb5,
14001   0xb6,  0x74,  0x03,  0x70,  0x28,  0x23,  0xd8,  0x50,  0xfe,  0x04,  0xe6,  0x1a,  0xfe,  0x9d,  0x41,  0xfe,
14002   0x1c,  0x42,  0x64,  0x01,  0xe3,  0x02,  0x2b,  0xf8,  0x15,  0x0a,  0x39,  0xa0,  0xb4,  0x15,  0xfe,  0x31,
14003   0x00,  0x39,  0xa2,  0x01,  0xfe,  0x48,  0x10,  0x02,  0xd7,  0x42,  0xfe,  0x06,  0xec,  0xd0,  0xfc,  0x44,
14004   0x1b,  0xfe,  0xce,  0x45,  0x35,  0x42,  0xfe,  0x06,  0xea,  0xd0,  0xfe,  0x47,  0x4b,  0x91,  0xfe,  0x75,
14005   0x57,  0x03,  0x5d,  0xfe,  0x98,  0x56,  0xfe,  0x38,  0x12,  0x09,  0x48,  0x01,  0x0e,  0xfe,  0x44,  0x48,
14006   0x4f,  0x08,  0x05,  0x1b,  0xfe,  0x1a,  0x13,  0x09,  0x46,  0x01,  0x0e,  0x41,  0xfe,  0x41,  0x58,  0x09,
14007   0xa4,  0x01,  0x0e,  0xfe,  0x49,  0x54,  0x96,  0xfe,  0x1e,  0x0e,  0x02,  0xfe,  0x2e,  0x03,  0x09,  0x5d,
14008   0xfe,  0xee,  0x14,  0xfc,  0x44,  0x1b,  0xfe,  0xce,  0x45,  0x35,  0x42,  0xfe,  0xce,  0x47,  0xfe,  0xad,
14009   0x13,  0x02,  0x2b,  0x22,  0x20,  0x07,  0x11,  0xfe,  0x9e,  0x12,  0x21,  0x13,  0x59,  0x13,  0x9f,  0x13,
14010   0xd5,  0x22,  0x2f,  0x41,  0x39,  0x2f,  0xbc,  0xad,  0xfe,  0xbc,  0xf0,  0xfe,  0xe0,  0x0e,  0x0f,  0x06,
14011   0x13,  0x59,  0x01,  0xfe,  0xda,  0x16,  0x03,  0xfe,  0x38,  0x01,  0x29,  0xfe,  0x3a,  0x01,  0x56,  0xfe,
14012   0xe4,  0x0e,  0xfe,  0x02,  0xec,  0xd5,  0x69,  0x00,  0x66,  0xfe,  0x04,  0xec,  0x20,  0x4f,  0xfe,  0x05,
14013   0xf6,  0xfe,  0x34,  0x01,  0x01,  0xfe,  0x4a,  0x17,  0xfe,  0x08,  0x90,  0xfe,  0x48,  0xf4,  0x0d,  0xfe,
14014   0x18,  0x13,  0xba,  0xfe,  0x02,  0xea,  0xd5,  0x69,  0x7e,  0xfe,  0xc5,  0x13,  0x15,  0x1a,  0x39,  0xa0,
14015   0xb4,  0xfe,  0x2e,  0x10,  0x03,  0xfe,  0x38,  0x01,  0x1e,  0xfe,  0xf0,  0xff,  0x0c,  0xfe,  0x60,  0x01,
14016   0x03,  0xfe,  0x3a,  0x01,  0x0c,  0xfe,  0x62,  0x01,  0x43,  0x13,  0x20,  0x25,  0x06,  0x13,  0x2f,  0x12,
14017   0x2f,  0x92,  0x0f,  0x06,  0x04,  0x21,  0x04,  0x22,  0x59,  0xfe,  0xf7,  0x12,  0x22,  0x9f,  0xb7,  0x13,
14018   0x9f,  0x07,  0x7e,  0xfe,  0x71,  0x13,  0xfe,  0x24,  0x1c,  0x15,  0x19,  0x39,  0xa0,  0xb4,  0xfe,  0xd9,
14019   0x10,  0xc3,  0xfe,  0x03,  0xdc,  0xfe,  0x73,  0x57,  0xfe,  0x80,  0x5d,  0x04,  0xc3,  0xfe,  0x03,  0xdc,
14020   0xfe,  0x5b,  0x57,  0xfe,  0x80,  0x5d,  0x04,  0xfe,  0x03,  0x57,  0xc3,  0x21,  0xfe,  0x00,  0xcc,  0x04,
14021   0xfe,  0x03,  0x57,  0xc3,  0x78,  0x04,  0x08,  0x05,  0x58,  0xfe,  0x22,  0x13,  0xfe,  0x1c,  0x80,  0x07,
14022   0x06,  0xfe,  0x1a,  0x13,  0xfe,  0x1e,  0x80,  0xed,  0xfe,  0x1d,  0x80,  0xae,  0xfe,  0x0c,  0x90,  0xfe,
14023   0x0e,  0x13,  0xfe,  0x0e,  0x90,  0xac,  0xfe,  0x3c,  0x90,  0xfe,  0x30,  0xf4,  0x0a,  0xfe,  0x3c,  0x50,
14024   0xaa,  0x01,  0xfe,  0x7a,  0x17,  0x32,  0x07,  0x2f,  0xad,  0x01,  0xfe,  0xb4,  0x16,  0x08,  0x05,  0x1b,
14025   0x4e,  0x01,  0xf5,  0x01,  0xf6,  0x12,  0xfe,  0xe9,  0x00,  0x08,  0x05,  0x58,  0xfe,  0x2c,  0x13,  0x01,
14026   0xfe,  0x0c,  0x17,  0xfe,  0x1e,  0x1c,  0xfe,  0x14,  0x90,  0xfe,  0x96,  0x90,  0x0c,  0xfe,  0x64,  0x01,
14027   0x14,  0xfe,  0x66,  0x01,  0x08,  0x05,  0x5b,  0xfe,  0x12,  0x12,  0xfe,  0x03,  0x80,  0x8d,  0xfe,  0x01,
14028   0xec,  0x20,  0xfe,  0x80,  0x40,  0x13,  0x20,  0x6a,  0x2a,  0x12,  0xcf,  0x64,  0x22,  0x20,  0xfb,  0x79,
14029   0x20,  0x04,  0xfe,  0x08,  0x1c,  0x03,  0xfe,  0xac,  0x00,  0xfe,  0x06,  0x58,  0x03,  0xfe,  0xae,  0x00,
14030 
14031   0xfe,  0x07,  0x58,  0x03,  0xfe,  0xb0,  0x00,  0xfe,  0x08,  0x58,  0x03,  0xfe,  0xb2,  0x00,  0xfe,  0x09,
14032   0x58,  0xfe,  0x0a,  0x1c,  0x25,  0x6e,  0x13,  0xd0,  0x21,  0x0c,  0x5c,  0x0c,  0x45,  0x0f,  0x46,  0x52,
14033   0x50,  0x18,  0x1b,  0xfe,  0x90,  0x4d,  0xfe,  0x91,  0x54,  0x23,  0xfe,  0xfc,  0x0f,  0x44,  0x11,  0x0f,
14034   0x48,  0x52,  0x18,  0x58,  0xfe,  0x90,  0x4d,  0xfe,  0x91,  0x54,  0x23,  0xe4,  0x25,  0x11,  0x13,  0x20,
14035   0x7c,  0x6f,  0x4f,  0x22,  0x20,  0xfb,  0x79,  0x20,  0x12,  0xcf,  0xfe,  0x14,  0x56,  0xfe,  0xd6,  0xf0,
14036   0xfe,  0x26,  0x10,  0xf8,  0x74,  0xfe,  0x14,  0x1c,  0xfe,  0x10,  0x1c,  0xfe,  0x18,  0x1c,  0x04,  0x42,
14037   0xfe,  0x0c,  0x14,  0xfc,  0xfe,  0x07,  0xe6,  0x1b,  0xfe,  0xce,  0x47,  0xfe,  0xf5,  0x13,  0x04,  0x01,
14038   0xb0,  0x7c,  0x6f,  0x4f,  0xfe,  0x06,  0x80,  0xfe,  0x48,  0x47,  0xfe,  0x42,  0x13,  0x32,  0x07,  0x2f,
14039   0xfe,  0x34,  0x13,  0x09,  0x48,  0x01,  0x0e,  0xbb,  0xfe,  0x36,  0x12,  0xfe,  0x41,  0x48,  0xfe,  0x45,
14040   0x48,  0x01,  0xf0,  0xfe,  0x00,  0xcc,  0xbb,  0xfe,  0xf3,  0x13,  0x43,  0x78,  0x07,  0x11,  0xac,  0x09,
14041   0x84,  0x01,  0x0e,  0xfe,  0x80,  0x5c,  0x01,  0x73,  0xfe,  0x0e,  0x10,  0x07,  0x82,  0x4e,  0xfe,  0x14,
14042   0x56,  0xfe,  0xd6,  0xf0,  0xfe,  0x60,  0x10,  0x04,  0xfe,  0x44,  0x58,  0x8d,  0xfe,  0x01,  0xec,  0xa2,
14043   0xfe,  0x9e,  0x40,  0xfe,  0x9d,  0xe7,  0x00,  0xfe,  0x9c,  0xe7,  0x1a,  0x79,  0x2a,  0x01,  0xe3,  0xfe,
14044   0xdd,  0x10,  0x2c,  0xc7,  0x81,  0xc8,  0x83,  0x33,  0x31,  0xde,  0x07,  0x1a,  0xfe,  0x48,  0x12,  0x07,
14045   0x0a,  0xfe,  0x56,  0x12,  0x07,  0x19,  0xfe,  0x30,  0x12,  0x07,  0xc9,  0x17,  0xfe,  0x32,  0x12,  0x07,
14046   0xfe,  0x23,  0x00,  0x17,  0xeb,  0x07,  0x06,  0x17,  0xfe,  0x9c,  0x12,  0x07,  0x1f,  0xfe,  0x12,  0x12,
14047   0x07,  0x00,  0x17,  0x24,  0x15,  0xc9,  0x01,  0x36,  0xa9,  0x2d,  0x01,  0x0b,  0x94,  0x4b,  0x04,  0x2d,
14048   0xdd,  0x09,  0xd1,  0x01,  0xfe,  0x26,  0x0f,  0x12,  0x82,  0x02,  0x2b,  0x2d,  0x32,  0x07,  0xa6,  0xfe,
14049   0xd9,  0x13,  0x3a,  0x3d,  0x3b,  0x3e,  0x56,  0xfe,  0xf0,  0x11,  0x08,  0x05,  0x5a,  0xfe,  0x72,  0x12,
14050   0x9b,  0x2e,  0x9c,  0x3c,  0x90,  0xc0,  0x96,  0xfe,  0xba,  0x11,  0x22,  0x62,  0xfe,  0x26,  0x13,  0x03,
14051   0x7f,  0x29,  0x80,  0x56,  0xfe,  0x76,  0x0d,  0x0c,  0x60,  0x14,  0x61,  0x21,  0x0c,  0x7f,  0x0c,  0x80,
14052   0x01,  0xb3,  0x25,  0x6e,  0x77,  0x13,  0x62,  0x01,  0xef,  0x9b,  0x2e,  0x9c,  0x3c,  0xfe,  0x04,  0x55,
14053   0xfe,  0xa5,  0x55,  0xfe,  0x04,  0xfa,  0x2e,  0xfe,  0x05,  0xfa,  0x3c,  0xfe,  0x91,  0x10,  0x03,  0x3f,
14054   0x29,  0x40,  0xfe,  0x40,  0x56,  0xfe,  0xe1,  0x56,  0x0c,  0x3f,  0x14,  0x40,  0x88,  0x9b,  0x2e,  0x9c,
14055   0x3c,  0x90,  0xc0,  0x03,  0x5e,  0x29,  0x5f,  0xfe,  0x00,  0x56,  0xfe,  0xa1,  0x56,  0x0c,  0x5e,  0x14,
14056   0x5f,  0x08,  0x05,  0x5a,  0xfe,  0x1e,  0x12,  0x22,  0x62,  0xfe,  0x1f,  0x40,  0x03,  0x60,  0x29,  0x61,
14057   0xfe,  0x2c,  0x50,  0xfe,  0xae,  0x50,  0x03,  0x3f,  0x29,  0x40,  0xfe,  0x44,  0x50,  0xfe,  0xc6,  0x50,
14058   0x03,  0x5e,  0x29,  0x5f,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0x03,  0x3d,  0x29,  0x3e,  0xfe,  0x40,
14059   0x50,  0xfe,  0xc2,  0x50,  0x02,  0x89,  0x25,  0x06,  0x13,  0xd4,  0x02,  0x72,  0x2d,  0x01,  0x0b,  0x1d,
14060   0x4c,  0x33,  0x31,  0xde,  0x07,  0x06,  0x23,  0x4c,  0x32,  0x07,  0xa6,  0x23,  0x72,  0x01,  0xaf,  0x1e,
14061   0x43,  0x17,  0x4c,  0x08,  0x05,  0x0a,  0xee,  0x3a,  0x3d,  0x3b,  0x3e,  0xfe,  0x0a,  0x55,  0x35,  0xfe,
14062   0x8b,  0x55,  0x57,  0x3d,  0x7d,  0x3e,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0x02,  0x72,  0xfe,  0x19,
14063   0x81,  0xba,  0xfe,  0x19,  0x41,  0x02,  0x72,  0x2d,  0x01,  0x0b,  0x1c,  0x34,  0x1d,  0xe8,  0x33,  0x31,
14064   0xe1,  0x55,  0x19,  0xfe,  0xa6,  0x12,  0x55,  0x0a,  0x4d,  0x02,  0x4c,  0x01,  0x0b,  0x1c,  0x34,  0x1d,
14065   0xe8,  0x33,  0x31,  0xdf,  0x07,  0x19,  0x23,  0x4c,  0x01,  0x0b,  0x1d,  0xe8,  0x33,  0x31,  0xfe,  0xe8,
14066   0x09,  0xfe,  0xc2,  0x49,  0x51,  0x03,  0xfe,  0x9c,  0x00,  0x28,  0x8a,  0x53,  0x05,  0x1f,  0x35,  0xa9,
14067   0xfe,  0xbb,  0x45,  0x55,  0x00,  0x4e,  0x44,  0x06,  0x7c,  0x43,  0xfe,  0xda,  0x14,  0x01,  0xaf,  0x8c,
14068   0xfe,  0x4b,  0x45,  0xee,  0x32,  0x07,  0xa5,  0xed,  0x03,  0xcd,  0x28,  0x8a,  0x03,  0x45,  0x28,  0x35,
14069   0x67,  0x02,  0x72,  0xfe,  0xc0,  0x5d,  0xfe,  0xf8,  0x14,  0xfe,  0x03,  0x17,  0x03,  0x5c,  0xc1,  0x0c,
14070   0x5c,  0x67,  0x2d,  0x01,  0x0b,  0x26,  0x89,  0x01,  0xfe,  0x9e,  0x15,  0x02,  0x89,  0x01,  0x0b,  0x1c,
14071   0x34,  0x1d,  0x4c,  0x33,  0x31,  0xdf,  0x07,  0x06,  0x23,  0x4c,  0x01,  0xf1,  0xfe,  0x42,  0x58,  0xf1,
14072   0xfe,  0xa4,  0x14,  0x8c,  0xfe,  0x4a,  0xf4,  0x0a,  0x17,  0x4c,  0xfe,  0x4a,  0xf4,  0x06,  0xea,  0x32,
14073   0x07,  0xa5,  0x8b,  0x02,  0x72,  0x03,  0x45,  0xc1,  0x0c,  0x45,  0x67,  0x2d,  0x01,  0x0b,  0x26,  0x89,
14074   0x01,  0xfe,  0xcc,  0x15,  0x02,  0x89,  0x0f,  0x06,  0x27,  0xfe,  0xbe,  0x13,  0x26,  0xfe,  0xd4,  0x13,
14075   0x76,  0xfe,  0x89,  0x48,  0x01,  0x0b,  0x21,  0x76,  0x04,  0x7b,  0xfe,  0xd0,  0x13,  0x1c,  0xfe,  0xd0,
14076   0x13,  0x1d,  0xfe,  0xbe,  0x13,  0x67,  0x2d,  0x01,  0x0b,  0xfe,  0xd5,  0x10,  0x0f,  0x71,  0xff,  0x02,
14077   0x00,  0x57,  0x52,  0x93,  0x1e,  0xfe,  0xff,  0x7f,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x04,  0x0f,
14078   0x71,  0xff,  0x02,  0x00,  0x57,  0x52,  0x93,  0x1e,  0x43,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x04,
14079   0x0f,  0x71,  0xff,  0x02,  0x00,  0x57,  0x52,  0x93,  0x04,  0x0f,  0x71,  0xff,  0x02,  0x00,  0x57,  0x52,
14080   0x93,  0xfe,  0x0b,  0x58,  0x04,  0x09,  0x5c,  0x01,  0x87,  0x09,  0x45,  0x01,  0x87,  0x04,  0xfe,  0x03,
14081   0xa1,  0x1e,  0x11,  0xff,  0x03,  0x00,  0x54,  0xfe,  0x00,  0xf4,  0x1f,  0x52,  0xfe,  0x00,  0x7d,  0xfe,
14082   0x01,  0x7d,  0xfe,  0x02,  0x7d,  0xfe,  0x03,  0x7c,  0x6a,  0x2a,  0x0c,  0x5e,  0x14,  0x5f,  0x57,  0x3f,
14083   0x7d,  0x40,  0x04,  0xdd,  0xfe,  0x82,  0x4a,  0xfe,  0xe1,  0x1a,  0xfe,  0x83,  0x5a,  0x8d,  0x04,  0x01,
14084   0xfe,  0x0c,  0x19,  0xfe,  0x42,  0x48,  0x50,  0x51,  0x91,  0x01,  0x0b,  0x1d,  0xfe,  0x96,  0x15,  0x33,
14085   0x31,  0xe1,  0x01,  0x0b,  0x1d,  0xfe,  0x96,  0x15,  0x33,  0x31,  0xfe,  0xe8,  0x0a,  0xfe,  0xc1,  0x59,
14086   0x03,  0xcd,  0x28,  0xfe,  0xcc,  0x12,  0x53,  0x05,  0x1a,  0xfe,  0xc4,  0x13,  0x21,  0x69,  0x1a,  0xee,
14087   0x55,  0xca,  0x6b,  0xfe,  0xdc,  0x14,  0x4d,  0x0f,  0x06,  0x18,  0xca,  0x7c,  0x30,  0xfe,  0x78,  0x10,
14088   0xff,  0x02,  0x83,  0x55,  0xab,  0xff,  0x02,  0x83,  0x55,  0x69,  0x19,  0xae,  0x98,  0xfe,  0x30,  0x00,
14089   0x96,  0xf2,  0x18,  0x6d,  0x0f,  0x06,  0xfe,  0x56,  0x10,  0x69,  0x0a,  0xed,  0x98,  0xfe,  0x64,  0x00,
14090   0x96,  0xf2,  0x09,  0xfe,  0x64,  0x00,  0x18,  0x9e,  0x0f,  0x06,  0xfe,  0x28,  0x10,  0x69,  0x06,  0xfe,
14091   0x60,  0x13,  0x98,  0xfe,  0xc8,  0x00,  0x96,  0xf2,  0x09,  0xfe,  0xc8,  0x00,  0x18,  0x59,  0x0f,  0x06,
14092   0x88,  0x98,  0xfe,  0x90,  0x01,  0x7a,  0xfe,  0x42,  0x15,  0x91,  0xe4,  0xfe,  0x43,  0xf4,  0x9f,  0xfe,
14093   0x56,  0xf0,  0xfe,  0x54,  0x15,  0xfe,  0x04,  0xf4,  0x71,  0xfe,  0x43,  0xf4,  0x9e,  0xfe,  0xf3,  0x10,
14094   0xfe,  0x40,  0x5c,  0x01,  0xfe,  0x16,  0x14,  0x1e,  0x43,  0xec,  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,
14095   0x6e,  0x7a,  0xfe,  0x90,  0x15,  0xc4,  0x6e,  0xfe,  0x1c,  0x10,  0xfe,  0x00,  0x17,  0xfe,  0x4d,  0xe4,
14096   0xcc,  0x7a,  0xfe,  0x90,  0x15,  0xc4,  0xcc,  0x88,  0x51,  0x21,  0xfe,  0x4d,  0xf4,  0x00,  0xe9,  0x91,
14097   0x0f,  0x06,  0xfe,  0xb4,  0x56,  0xfe,  0xc3,  0x58,  0x04,  0x51,  0x0f,  0x0a,  0x04,  0x16,  0x06,  0x01,
14098   0x0b,  0x26,  0xf3,  0x16,  0x0a,  0x01,  0x0b,  0x26,  0xf3,  0x16,  0x19,  0x01,  0x0b,  0x26,  0xf3,  0x76,
14099   0xfe,  0x89,  0x49,  0x01,  0x0b,  0x04,  0x16,  0x06,  0x01,  0x0b,  0x26,  0xb1,  0x16,  0x19,  0x01,  0x0b,
14100   0x26,  0xb1,  0x16,  0x06,  0x01,  0x0b,  0x26,  0xb1,  0xfe,  0x89,  0x49,  0x01,  0x0b,  0x26,  0xb1,  0x76,
14101   0xfe,  0x89,  0x4a,  0x01,  0x0b,  0x04,  0x51,  0x04,  0x22,  0xd3,  0x07,  0x06,  0xfe,  0x48,  0x13,  0xb8,
14102   0x13,  0xd3,  0xfe,  0x49,  0xf4,  0x00,  0x4d,  0x76,  0xa9,  0x67,  0xfe,  0x01,  0xec,  0xfe,  0x27,  0x01,
14103   0xfe,  0x89,  0x48,  0xff,  0x02,  0x00,  0x10,  0x27,  0xfe,  0x2e,  0x16,  0x32,  0x07,  0xfe,  0xe3,  0x00,
14104   0xfe,  0x20,  0x13,  0x1d,  0xfe,  0x52,  0x16,  0x21,  0x13,  0xd4,  0x01,  0x4b,  0x22,  0xd4,  0x07,  0x06,
14105   0x4e,  0x08,  0x54,  0x06,  0x37,  0x04,  0x09,  0x48,  0x01,  0x0e,  0xfb,  0x8e,  0x07,  0x11,  0xae,  0x09,
14106   0x84,  0x01,  0x0e,  0x8e,  0x09,  0x5d,  0x01,  0xa8,  0x04,  0x09,  0x84,  0x01,  0x0e,  0x8e,  0xfe,  0x80,
14107   0xe7,  0x11,  0x07,  0x11,  0x8a,  0xfe,  0x45,  0x58,  0x01,  0xf0,  0x8e,  0x04,  0x09,  0x48,  0x01,  0x0e,
14108   0x8e,  0x09,  0x5d,  0x01,  0xa8,  0x04,  0x09,  0x48,  0x01,  0x0e,  0xfe,  0x80,  0x80,  0xfe,  0x80,  0x4c,
14109   0xfe,  0x49,  0xe4,  0x11,  0xae,  0x09,  0x84,  0x01,  0x0e,  0xfe,  0x80,  0x4c,  0x09,  0x5d,  0x01,  0x87,
14110   0x04,  0x18,  0x11,  0x75,  0x6c,  0xfe,  0x60,  0x01,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x24,
14111   0x1c,  0xfe,  0x1d,  0xf7,  0x1b,  0x97,  0xfe,  0xee,  0x16,  0x01,  0xfe,  0xf4,  0x17,  0xad,  0x9a,  0x1b,
14112   0x6c,  0xfe,  0x2c,  0x01,  0xfe,  0x2f,  0x19,  0x04,  0xb9,  0x23,  0xfe,  0xde,  0x16,  0xfe,  0xda,  0x10,
14113   0x18,  0x11,  0x75,  0x03,  0xfe,  0x64,  0x01,  0xfe,  0x00,  0xf4,  0x1f,  0xfe,  0x18,  0x58,  0x03,  0xfe,
14114   0x66,  0x01,  0xfe,  0x19,  0x58,  0x9a,  0x1f,  0xfe,  0x3c,  0x90,  0xfe,  0x30,  0xf4,  0x06,  0xfe,  0x3c,
14115   0x50,  0x6c,  0xfe,  0x38,  0x00,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0x1f,  0x97,  0xfe,  0x38,  0x17,
14116   0xfe,  0xb6,  0x14,  0x35,  0x04,  0xb9,  0x23,  0xfe,  0x10,  0x17,  0xfe,  0x9c,  0x10,  0x18,  0x11,  0x75,
14117   0xfe,  0x83,  0x5a,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x1d,  0xf7,  0x2e,  0x97,  0xfe,  0x5a,
14118   0x17,  0xfe,  0x94,  0x14,  0xec,  0x9a,  0x2e,  0x6c,  0x1a,  0xfe,  0xaf,  0x19,  0xfe,  0x98,  0xe7,  0x00,
14119   0x04,  0xb9,  0x23,  0xfe,  0x4e,  0x17,  0xfe,  0x6c,  0x10,  0x18,  0x11,  0x75,  0xfe,  0x30,  0xbc,  0xfe,
14120   0xb2,  0xbc,  0x9a,  0xcb,  0x6c,  0x1a,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0xcb,  0x97,  0xfe,  0x92,
14121   0x17,  0xfe,  0x5c,  0x14,  0x35,  0x04,  0xb9,  0x23,  0xfe,  0x7e,  0x17,  0xfe,  0x42,  0x10,  0xfe,  0x02,
14122   0xf6,  0x11,  0x75,  0xfe,  0x18,  0xfe,  0x60,  0xfe,  0x19,  0xfe,  0x61,  0xfe,  0x03,  0xa1,  0xfe,  0x1d,
14123   0xf7,  0x5b,  0x97,  0xfe,  0xb8,  0x17,  0xfe,  0x36,  0x14,  0xfe,  0x1c,  0x13,  0x9a,  0x5b,  0x41,  0xfe,
14124   0x83,  0x58,  0xfe,  0xaf,  0x19,  0xfe,  0x80,  0xe7,  0x11,  0xfe,  0x81,  0xe7,  0x11,  0x12,  0xfe,  0xdd,
14125   0x00,  0x6a,  0x2a,  0x04,  0x6a,  0x2a,  0xfe,  0x12,  0x45,  0x23,  0xfe,  0xa8,  0x17,  0x15,  0x06,  0x39,
14126   0xa0,  0xb4,  0x02,  0x2b,  0xfe,  0x39,  0xf0,  0xfe,  0xfc,  0x17,  0x21,  0x04,  0xfe,  0x7e,  0x18,  0x1e,
14127   0x19,  0x66,  0x0f,  0x0d,  0x04,  0x75,  0x03,  0xd2,  0x1e,  0x06,  0xfe,  0xef,  0x12,  0xfe,  0xe1,  0x10,
14128   0x7c,  0x6f,  0x4f,  0x32,  0x07,  0x2f,  0xfe,  0x3c,  0x13,  0xf1,  0xfe,  0x42,  0x13,  0x42,  0x92,  0x09,
14129   0x48,  0x01,  0x0e,  0xbb,  0xeb,  0xfe,  0x41,  0x48,  0xfe,  0x45,  0x48,  0x01,  0xf0,  0xfe,  0x00,  0xcc,
14130   0xbb,  0xfe,  0xf3,  0x13,  0x43,  0x78,  0x07,  0x11,  0xac,  0x09,  0x84,  0x01,  0x0e,  0xfe,  0x80,  0x4c,
14131   0x01,  0x73,  0xfe,  0x16,  0x10,  0x07,  0x82,  0x8b,  0xfe,  0x40,  0x14,  0xfe,  0x24,  0x12,  0xfe,  0x14,
14132   0x56,  0xfe,  0xd6,  0xf0,  0xfe,  0x1c,  0x18,  0x18,  0x0a,  0x04,  0xfe,  0x9c,  0xe7,  0x0a,  0x10,  0xfe,
14133   0x15,  0x00,  0x64,  0x79,  0x2a,  0x01,  0xe3,  0x18,  0x06,  0x04,  0x42,  0x92,  0x08,  0x54,  0x1b,  0x37,
14134   0x12,  0x2f,  0x01,  0x73,  0x18,  0x06,  0x04,  0xfe,  0x38,  0x90,  0xfe,  0xba,  0x90,  0x3a,  0xce,  0x3b,
14135   0xcf,  0xfe,  0x48,  0x55,  0x35,  0xfe,  0xc9,  0x55,  0x04,  0x22,  0xa3,  0x77,  0x13,  0xa3,  0x04,  0x09,
14136   0xa4,  0x01,  0x0e,  0xfe,  0x41,  0x48,  0x09,  0x46,  0x01,  0x0e,  0xfe,  0x49,  0x44,  0x17,  0xfe,  0xe8,
14137   0x18,  0x77,  0x78,  0x04,  0x09,  0x48,  0x01,  0x0e,  0x07,  0x11,  0x4e,  0x09,  0x5d,  0x01,  0xa8,  0x09,
14138   0x46,  0x01,  0x0e,  0x77,  0x78,  0x04,  0xfe,  0x4e,  0xe4,  0x19,  0x6b,  0xfe,  0x1c,  0x19,  0x03,  0xfe,
14139   0x90,  0x00,  0xfe,  0x3a,  0x45,  0xfe,  0x2c,  0x10,  0xfe,  0x4e,  0xe4,  0xc9,  0x6b,  0xfe,  0x2e,  0x19,
14140   0x03,  0xfe,  0x92,  0x00,  0xfe,  0x02,  0xe6,  0x1a,  0xe5,  0xfe,  0x4e,  0xe4,  0xfe,  0x0b,  0x00,  0x6b,
14141   0xfe,  0x40,  0x19,  0x03,  0xfe,  0x94,  0x00,  0xfe,  0x02,  0xe6,  0x1f,  0xfe,  0x08,  0x10,  0x03,  0xfe,
14142   0x96,  0x00,  0xfe,  0x02,  0xe6,  0x6d,  0xfe,  0x4e,  0x45,  0xea,  0xba,  0xff,  0x04,  0x68,  0x54,  0xe7,
14143   0x1e,  0x6e,  0xfe,  0x08,  0x1c,  0xfe,  0x67,  0x19,  0xfe,  0x0a,  0x1c,  0xfe,  0x1a,  0xf4,  0xfe,  0x00,
14144   0x04,  0xea,  0xfe,  0x48,  0xf4,  0x19,  0x7a,  0xfe,  0x74,  0x19,  0x0f,  0x19,  0x04,  0x07,  0x7e,  0xfe,
14145   0x5a,  0xf0,  0xfe,  0x84,  0x19,  0x25,  0xfe,  0x09,  0x00,  0xfe,  0x34,  0x10,  0x07,  0x1a,  0xfe,  0x5a,
14146   0xf0,  0xfe,  0x92,  0x19,  0x25,  0xca,  0xfe,  0x26,  0x10,  0x07,  0x19,  0x66,  0x25,  0x6d,  0xe5,  0x07,
14147   0x0a,  0x66,  0x25,  0x9e,  0xfe,  0x0e,  0x10,  0x07,  0x06,  0x66,  0x25,  0x59,  0xa9,  0xb8,  0x04,  0x15,
14148   0xfe,  0x09,  0x00,  0x01,  0x36,  0xfe,  0x04,  0xfe,  0x81,  0x03,  0x83,  0xfe,  0x40,  0x5c,  0x04,  0x1c,
14149   0xf7,  0xfe,  0x14,  0xf0,  0x0b,  0x27,  0xfe,  0xd6,  0x19,  0x1c,  0xf7,  0x7b,  0xf7,  0xfe,  0x82,  0xf0,
14150   0xfe,  0xda,  0x19,  0x04,  0xff,  0xcc,  0x00,  0x00,
14151 };
14152 
14153 STATIC unsigned short _adv_asc38C0800_size =
14154         sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
14155 STATIC ADV_DCNT _adv_asc38C0800_chksum =
14156         0x050D3FD8UL; /* Expanded little-endian checksum. */
14157 
14158 /* Microcode buffer is kept after initialization for error recovery. */
14159 STATIC unsigned char _adv_asc38C1600_buf[] = {
14160   0x00,  0x00,  0x00,  0xf2,  0x00,  0x16,  0x00,  0xfc,  0x00,  0x10,  0x00,  0xf0,  0x18,  0xe4,  0x01,  0x00,
14161   0x04,  0x1e,  0x48,  0xe4,  0x03,  0xf6,  0xf7,  0x13,  0x2e,  0x1e,  0x02,  0x00,  0x07,  0x17,  0xc0,  0x5f,
14162   0x00,  0xfa,  0xff,  0xff,  0x04,  0x00,  0x00,  0xf6,  0x09,  0xe7,  0x82,  0xe7,  0x85,  0xf0,  0x86,  0xf0,
14163   0x4e,  0x10,  0x9e,  0xe7,  0xff,  0x00,  0x55,  0xf0,  0x01,  0xf6,  0x03,  0x00,  0x98,  0x57,  0x01,  0xe6,
14164   0x00,  0xea,  0x00,  0xec,  0x01,  0xfa,  0x18,  0xf4,  0x08,  0x00,  0xf0,  0x1d,  0x38,  0x54,  0x32,  0xf0,
14165   0x10,  0x00,  0xc2,  0x0e,  0x1e,  0xf0,  0xd5,  0xf0,  0xbc,  0x00,  0x4b,  0xe4,  0x00,  0xe6,  0xb1,  0xf0,
14166   0xb4,  0x00,  0x02,  0x13,  0x3e,  0x1c,  0xc8,  0x47,  0x3e,  0x00,  0xd8,  0x01,  0x06,  0x13,  0x0c,  0x1c,
14167   0x5e,  0x1e,  0x00,  0x57,  0xc8,  0x57,  0x01,  0xfc,  0xbc,  0x0e,  0xa2,  0x12,  0xb9,  0x54,  0x00,  0x80,
14168   0x62,  0x0a,  0x5a,  0x12,  0xc8,  0x15,  0x3e,  0x1e,  0x18,  0x40,  0xbd,  0x56,  0x03,  0xe6,  0x01,  0xea,
14169   0x5c,  0xf0,  0x0f,  0x00,  0x20,  0x00,  0x6c,  0x01,  0x6e,  0x01,  0x04,  0x12,  0x04,  0x13,  0xbb,  0x55,
14170   0x3c,  0x56,  0x3e,  0x57,  0x03,  0x58,  0x4a,  0xe4,  0x40,  0x00,  0xb6,  0x00,  0xbb,  0x00,  0xc0,  0x00,
14171   0x00,  0x01,  0x01,  0x01,  0x3e,  0x01,  0x58,  0x0a,  0x44,  0x10,  0x0a,  0x12,  0x4c,  0x1c,  0x4e,  0x1c,
14172   0x02,  0x4a,  0x30,  0xe4,  0x05,  0xe6,  0x0c,  0x00,  0x3c,  0x00,  0x80,  0x00,  0x24,  0x01,  0x3c,  0x01,
14173   0x68,  0x01,  0x6a,  0x01,  0x70,  0x01,  0x72,  0x01,  0x74,  0x01,  0x76,  0x01,  0x78,  0x01,  0x7c,  0x01,
14174   0xc6,  0x0e,  0x0c,  0x10,  0xac,  0x12,  0xae,  0x12,  0x16,  0x1a,  0x32,  0x1c,  0x6e,  0x1e,  0x02,  0x48,
14175   0x3a,  0x55,  0xc9,  0x57,  0x02,  0xee,  0x5b,  0xf0,  0x03,  0xf7,  0x06,  0xf7,  0x03,  0xfc,  0x06,  0x00,
14176   0x1e,  0x00,  0xbe,  0x00,  0xe1,  0x00,  0x0c,  0x12,  0x18,  0x1a,  0x70,  0x1a,  0x30,  0x1c,  0x38,  0x1c,
14177   0x10,  0x44,  0x00,  0x4c,  0xb0,  0x57,  0x40,  0x5c,  0x4d,  0xe4,  0x04,  0xea,  0x5d,  0xf0,  0xa7,  0xf0,
14178   0x04,  0xf6,  0x02,  0xfc,  0x05,  0x00,  0x09,  0x00,  0x19,  0x00,  0x32,  0x00,  0x33,  0x00,  0x34,  0x00,
14179   0x36,  0x00,  0x98,  0x00,  0x9e,  0x00,  0xcc,  0x00,  0x20,  0x01,  0x4e,  0x01,  0x79,  0x01,  0x3c,  0x09,
14180   0x68,  0x0d,  0x02,  0x10,  0x04,  0x10,  0x3a,  0x10,  0x08,  0x12,  0x0a,  0x13,  0x40,  0x16,  0x50,  0x16,
14181   0x00,  0x17,  0x4a,  0x19,  0x00,  0x4e,  0x00,  0x54,  0x01,  0x58,  0x00,  0xdc,  0x05,  0xf0,  0x09,  0xf0,
14182   0x59,  0xf0,  0xb8,  0xf0,  0x48,  0xf4,  0x0e,  0xf7,  0x0a,  0x00,  0x9b,  0x00,  0x9c,  0x00,  0xa4,  0x00,
14183   0xb5,  0x00,  0xba,  0x00,  0xd0,  0x00,  0xe7,  0x00,  0xf0,  0x03,  0x69,  0x08,  0xe9,  0x09,  0x5c,  0x0c,
14184   0xb6,  0x12,  0xbc,  0x19,  0xd8,  0x1b,  0x20,  0x1c,  0x34,  0x1c,  0x36,  0x1c,  0x42,  0x1d,  0x08,  0x44,
14185   0x38,  0x44,  0x91,  0x44,  0x0a,  0x45,  0x48,  0x46,  0x89,  0x48,  0x68,  0x54,  0x83,  0x55,  0x83,  0x59,
14186   0x31,  0xe4,  0x02,  0xe6,  0x07,  0xf0,  0x08,  0xf0,  0x0b,  0xf0,  0x0c,  0xf0,  0x4b,  0xf4,  0x04,  0xf8,
14187   0x05,  0xf8,  0x02,  0xfa,  0x03,  0xfa,  0x04,  0xfc,  0x05,  0xfc,  0x07,  0x00,  0xa8,  0x00,  0xaa,  0x00,
14188   0xb9,  0x00,  0xe0,  0x00,  0xe5,  0x00,  0x22,  0x01,  0x26,  0x01,  0x60,  0x01,  0x7a,  0x01,  0x82,  0x01,
14189   0xc8,  0x01,  0xca,  0x01,  0x86,  0x02,  0x6a,  0x03,  0x18,  0x05,  0xb2,  0x07,  0x68,  0x08,  0x10,  0x0d,
14190   0x06,  0x10,  0x0a,  0x10,  0x0e,  0x10,  0x12,  0x10,  0x60,  0x10,  0xed,  0x10,  0xf3,  0x10,  0x06,  0x12,
14191   0x10,  0x12,  0x1e,  0x12,  0x0c,  0x13,  0x0e,  0x13,  0x10,  0x13,  0xfe,  0x9c,  0xf0,  0x35,  0x05,  0xfe,
14192   0xec,  0x0e,  0xff,  0x10,  0x00,  0x00,  0xe9,  0xfe,  0x34,  0x1f,  0x00,  0xe8,  0xfe,  0x88,  0x01,  0xff,
14193   0x03,  0x00,  0x00,  0xfe,  0x93,  0x15,  0xfe,  0x0f,  0x05,  0xff,  0x38,  0x00,  0x00,  0xfe,  0x57,  0x24,
14194   0x00,  0xfe,  0x4c,  0x00,  0x65,  0xff,  0x04,  0x00,  0x00,  0x1a,  0xff,  0x09,  0x00,  0x00,  0xff,  0x08,
14195   0x01,  0x01,  0xff,  0x08,  0xff,  0xff,  0xff,  0x27,  0x00,  0x00,  0xff,  0x10,  0xff,  0xff,  0xff,  0x13,
14196   0x00,  0x00,  0xfe,  0x78,  0x56,  0xfe,  0x34,  0x12,  0xff,  0x21,  0x00,  0x00,  0xfe,  0x04,  0xf7,  0xe8,
14197   0x37,  0x7d,  0x0d,  0x01,  0xfe,  0x4a,  0x11,  0xfe,  0x04,  0xf7,  0xe8,  0x7d,  0x0d,  0x51,  0x37,  0xfe,
14198   0x3d,  0xf0,  0xfe,  0x0c,  0x02,  0xfe,  0x20,  0xf0,  0xbc,  0xfe,  0x91,  0xf0,  0xfe,  0xf8,  0x01,  0xfe,
14199   0x90,  0xf0,  0xfe,  0xf8,  0x01,  0xfe,  0x8f,  0xf0,  0xbc,  0x03,  0x67,  0x4d,  0x05,  0xfe,  0x08,  0x0f,
14200   0x01,  0xfe,  0x78,  0x0f,  0xfe,  0xdd,  0x12,  0x05,  0xfe,  0x0e,  0x03,  0xfe,  0x28,  0x1c,  0x03,  0xfe,
14201   0xa6,  0x00,  0xfe,  0xd1,  0x12,  0x3e,  0x22,  0xfe,  0xa6,  0x00,  0xac,  0xfe,  0x48,  0xf0,  0xfe,  0x90,
14202   0x02,  0xfe,  0x49,  0xf0,  0xfe,  0xaa,  0x02,  0xfe,  0x4a,  0xf0,  0xfe,  0xc8,  0x02,  0xfe,  0x46,  0xf0,
14203   0xfe,  0x5a,  0x02,  0xfe,  0x47,  0xf0,  0xfe,  0x60,  0x02,  0xfe,  0x43,  0xf0,  0xfe,  0x4e,  0x02,  0xfe,
14204   0x44,  0xf0,  0xfe,  0x52,  0x02,  0xfe,  0x45,  0xf0,  0xfe,  0x56,  0x02,  0x1c,  0x0d,  0xa2,  0x1c,  0x07,
14205   0x22,  0xb7,  0x05,  0x35,  0xfe,  0x00,  0x1c,  0xfe,  0xf1,  0x10,  0xfe,  0x02,  0x1c,  0xf5,  0xfe,  0x1e,
14206   0x1c,  0xfe,  0xe9,  0x10,  0x01,  0x5f,  0xfe,  0xe7,  0x10,  0xfe,  0x06,  0xfc,  0xde,  0x0a,  0x81,  0x01,
14207   0xa3,  0x05,  0x35,  0x1f,  0x95,  0x47,  0xb8,  0x01,  0xfe,  0xe4,  0x11,  0x0a,  0x81,  0x01,  0x5c,  0xfe,
14208   0xbd,  0x10,  0x0a,  0x81,  0x01,  0x5c,  0xfe,  0xad,  0x10,  0xfe,  0x16,  0x1c,  0xfe,  0x58,  0x1c,  0x1c,
14209   0x07,  0x22,  0xb7,  0x37,  0x2a,  0x35,  0xfe,  0x3d,  0xf0,  0xfe,  0x0c,  0x02,  0x2b,  0xfe,  0x9e,  0x02,
14210   0xfe,  0x5a,  0x1c,  0xfe,  0x12,  0x1c,  0xfe,  0x14,  0x1c,  0x1f,  0xfe,  0x30,  0x00,  0x47,  0xb8,  0x01,
14211   0xfe,  0xd4,  0x11,  0x1c,  0x07,  0x22,  0xb7,  0x05,  0xe9,  0x21,  0x2c,  0x09,  0x1a,  0x31,  0xfe,  0x69,
14212   0x10,  0x1c,  0x07,  0x22,  0xb7,  0xfe,  0x04,  0xec,  0x2c,  0x60,  0x01,  0xfe,  0x1e,  0x1e,  0x20,  0x2c,
14213   0xfe,  0x05,  0xf6,  0xde,  0x01,  0xfe,  0x62,  0x1b,  0x01,  0x0c,  0x61,  0x4a,  0x44,  0x15,  0x56,  0x51,
14214   0x01,  0xfe,  0x9e,  0x1e,  0x01,  0xfe,  0x96,  0x1a,  0x05,  0x35,  0x0a,  0x57,  0x01,  0x18,  0x09,  0x00,
14215   0x36,  0x01,  0x85,  0xfe,  0x18,  0x10,  0xfe,  0x41,  0x58,  0x0a,  0xba,  0x01,  0x18,  0xfe,  0xc8,  0x54,
14216   0x7b,  0xfe,  0x1c,  0x03,  0x01,  0xfe,  0x96,  0x1a,  0x05,  0x35,  0x37,  0x60,  0xfe,  0x02,  0xe8,  0x30,
14217   0xfe,  0xbf,  0x57,  0xfe,  0x9e,  0x43,  0xfe,  0x77,  0x57,  0xfe,  0x27,  0xf0,  0xfe,  0xe4,  0x01,  0xfe,
14218   0x07,  0x4b,  0xfe,  0x20,  0xf0,  0xbc,  0xfe,  0x40,  0x1c,  0x2a,  0xeb,  0xfe,  0x26,  0xf0,  0xfe,  0x66,
14219   0x03,  0xfe,  0xa0,  0xf0,  0xfe,  0x54,  0x03,  0xfe,  0x11,  0xf0,  0xbc,  0xfe,  0xef,  0x10,  0xfe,  0x9f,
14220   0xf0,  0xfe,  0x74,  0x03,  0xfe,  0x46,  0x1c,  0x19,  0xfe,  0x11,  0x00,  0x05,  0x70,  0x37,  0xfe,  0x48,
14221   0x1c,  0xfe,  0x46,  0x1c,  0x01,  0x0c,  0x06,  0x28,  0xfe,  0x18,  0x13,  0x26,  0x21,  0xb9,  0xc7,  0x20,
14222   0xb9,  0x0a,  0x57,  0x01,  0x18,  0xc7,  0x89,  0x01,  0xfe,  0xc8,  0x1a,  0x15,  0xe1,  0x2a,  0xeb,  0xfe,
14223   0x01,  0xf0,  0xeb,  0xfe,  0x82,  0xf0,  0xfe,  0xa4,  0x03,  0xfe,  0x9c,  0x32,  0x15,  0xfe,  0xe4,  0x00,
14224   0x2f,  0xfe,  0xb6,  0x03,  0x2a,  0x3c,  0x16,  0xfe,  0xc6,  0x03,  0x01,  0x41,  0xfe,  0x06,  0xf0,  0xfe,
14225   0xd6,  0x03,  0xaf,  0xa0,  0xfe,  0x0a,  0xf0,  0xfe,  0xa2,  0x07,  0x05,  0x29,  0x03,  0x81,  0x1e,  0x1b,
14226   0xfe,  0x24,  0x05,  0x1f,  0x63,  0x01,  0x42,  0x8f,  0xfe,  0x70,  0x02,  0x05,  0xea,  0xfe,  0x46,  0x1c,
14227   0x37,  0x7d,  0x1d,  0xfe,  0x67,  0x1b,  0xfe,  0xbf,  0x57,  0xfe,  0x77,  0x57,  0xfe,  0x48,  0x1c,  0x75,
14228   0x01,  0xa6,  0x86,  0x0a,  0x57,  0x01,  0x18,  0x09,  0x00,  0x1b,  0xec,  0x0a,  0xe1,  0x01,  0x18,  0x77,
14229   0x50,  0x40,  0x8d,  0x30,  0x03,  0x81,  0x1e,  0xf8,  0x1f,  0x63,  0x01,  0x42,  0x8f,  0xfe,  0x70,  0x02,
14230   0x05,  0xea,  0xd7,  0x99,  0xd8,  0x9c,  0x2a,  0x29,  0x2f,  0xfe,  0x4e,  0x04,  0x16,  0xfe,  0x4a,  0x04,
14231   0x7e,  0xfe,  0xa0,  0x00,  0xfe,  0x9b,  0x57,  0xfe,  0x54,  0x12,  0x32,  0xff,  0x02,  0x00,  0x10,  0x01,
14232   0x08,  0x16,  0xfe,  0x02,  0x05,  0x32,  0x01,  0x08,  0x16,  0x29,  0x27,  0x25,  0xee,  0xfe,  0x4c,  0x44,
14233   0xfe,  0x58,  0x12,  0x50,  0xfe,  0x44,  0x48,  0x13,  0x34,  0xfe,  0x4c,  0x54,  0x7b,  0xec,  0x60,  0x8d,
14234   0x30,  0x01,  0xfe,  0x4e,  0x1e,  0xfe,  0x48,  0x47,  0xfe,  0x7c,  0x13,  0x01,  0x0c,  0x06,  0x28,  0xfe,
14235   0x32,  0x13,  0x01,  0x43,  0x09,  0x9b,  0xfe,  0x68,  0x13,  0xfe,  0x26,  0x10,  0x13,  0x34,  0xfe,  0x4c,
14236   0x54,  0x7b,  0xec,  0x01,  0xfe,  0x4e,  0x1e,  0xfe,  0x48,  0x47,  0xfe,  0x54,  0x13,  0x01,  0x0c,  0x06,
14237   0x28,  0xa5,  0x01,  0x43,  0x09,  0x9b,  0xfe,  0x40,  0x13,  0x01,  0x0c,  0x06,  0x28,  0xf9,  0x1f,  0x7f,
14238   0x01,  0x0c,  0x06,  0x07,  0x4d,  0x1f,  0xfe,  0x0d,  0x00,  0x01,  0x42,  0x8f,  0xfe,  0xa4,  0x0e,  0x05,
14239   0x29,  0x32,  0x15,  0xfe,  0xe6,  0x00,  0x0f,  0xfe,  0x1c,  0x90,  0x04,  0xfe,  0x9c,  0x93,  0x3a,  0x0b,
14240   0x0e,  0x8b,  0x02,  0x1f,  0x7f,  0x01,  0x42,  0x05,  0x35,  0xfe,  0x42,  0x5b,  0x7d,  0x1d,  0xfe,  0x46,
14241   0x59,  0xfe,  0xbf,  0x57,  0xfe,  0x77,  0x57,  0x0f,  0xfe,  0x87,  0x80,  0x04,  0xfe,  0x87,  0x83,  0xfe,
14242   0xc9,  0x47,  0x0b,  0x0e,  0xd0,  0x65,  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x98,  0x13,  0x0f,  0xfe,  0x20,
14243   0x80,  0x04,  0xfe,  0xa0,  0x83,  0x33,  0x0b,  0x0e,  0x09,  0x1d,  0xfe,  0x84,  0x12,  0x01,  0x38,  0x06,
14244   0x07,  0xfe,  0x70,  0x13,  0x03,  0xfe,  0xa2,  0x00,  0x1e,  0x1b,  0xfe,  0xda,  0x05,  0xd0,  0x54,  0x01,
14245   0x38,  0x06,  0x0d,  0xfe,  0x58,  0x13,  0x03,  0xfe,  0xa0,  0x00,  0x1e,  0xfe,  0x50,  0x12,  0x5e,  0xff,
14246   0x02,  0x00,  0x10,  0x2f,  0xfe,  0x90,  0x05,  0x2a,  0x3c,  0xcc,  0xff,  0x02,  0x00,  0x10,  0x2f,  0xfe,
14247   0x9e,  0x05,  0x17,  0xfe,  0xf4,  0x05,  0x15,  0xfe,  0xe3,  0x00,  0x26,  0x01,  0x38,  0xfe,  0x4a,  0xf0,
14248   0xfe,  0xc0,  0x05,  0xfe,  0x49,  0xf0,  0xfe,  0xba,  0x05,  0x71,  0x2e,  0xfe,  0x21,  0x00,  0xf1,  0x2e,
14249   0xfe,  0x22,  0x00,  0xa2,  0x2e,  0x4a,  0xfe,  0x09,  0x48,  0xff,  0x02,  0x00,  0x10,  0x2f,  0xfe,  0xd0,
14250   0x05,  0x17,  0xfe,  0xf4,  0x05,  0xfe,  0xe2,  0x08,  0x01,  0x38,  0x06,  0xfe,  0x1c,  0x00,  0x4d,  0x01,
14251   0xa7,  0x2e,  0x07,  0x20,  0xe4,  0x47,  0xfe,  0x27,  0x01,  0x01,  0x0c,  0x06,  0x28,  0xfe,  0x24,  0x12,
14252   0x3e,  0x01,  0x84,  0x1f,  0x7f,  0x01,  0x0c,  0x06,  0x07,  0x4d,  0x1f,  0xfe,  0x0d,  0x00,  0x01,  0x42,
14253   0x8f,  0xfe,  0xa4,  0x0e,  0x05,  0x29,  0x03,  0xe6,  0x1e,  0xfe,  0xca,  0x13,  0x03,  0xb6,  0x1e,  0xfe,
14254   0x40,  0x12,  0x03,  0x66,  0x1e,  0xfe,  0x38,  0x13,  0x3e,  0x01,  0x84,  0x17,  0xfe,  0x72,  0x06,  0x0a,
14255   0x07,  0x01,  0x38,  0x06,  0x24,  0xfe,  0x02,  0x12,  0x4f,  0x01,  0xfe,  0x56,  0x19,  0x16,  0xfe,  0x68,
14256   0x06,  0x15,  0x82,  0x01,  0x41,  0x15,  0xe2,  0x03,  0x66,  0x8a,  0x10,  0x66,  0x03,  0x9a,  0x1e,  0xfe,
14257   0x70,  0x12,  0x03,  0x55,  0x1e,  0xfe,  0x68,  0x13,  0x01,  0xc6,  0x09,  0x12,  0x48,  0xfe,  0x92,  0x06,
14258   0x2e,  0x12,  0x01,  0xfe,  0xac,  0x1d,  0xfe,  0x43,  0x48,  0x62,  0x80,  0x13,  0x58,  0xff,  0x02,  0x00,
14259   0x57,  0x52,  0xad,  0x23,  0x3f,  0x4e,  0x62,  0x49,  0x3e,  0x01,  0x84,  0x17,  0xfe,  0xea,  0x06,  0x01,
14260   0x38,  0x06,  0x12,  0xf7,  0x45,  0x0a,  0x95,  0x01,  0xfe,  0x84,  0x19,  0x16,  0xfe,  0xe0,  0x06,  0x15,
14261   0x82,  0x01,  0x41,  0x15,  0xe2,  0x03,  0x55,  0x8a,  0x10,  0x55,  0x1c,  0x07,  0x01,  0x84,  0xfe,  0xae,
14262   0x10,  0x03,  0x6f,  0x1e,  0xfe,  0x9e,  0x13,  0x3e,  0x01,  0x84,  0x03,  0x9a,  0x1e,  0xfe,  0x1a,  0x12,
14263   0x01,  0x38,  0x06,  0x12,  0xfc,  0x01,  0xc6,  0x01,  0xfe,  0xac,  0x1d,  0xfe,  0x43,  0x48,  0x62,  0x80,
14264   0xf0,  0x45,  0x0a,  0x95,  0x03,  0xb6,  0x1e,  0xf8,  0x01,  0x38,  0x06,  0x24,  0x36,  0xfe,  0x02,  0xf6,
14265   0x07,  0x71,  0x78,  0x8c,  0x00,  0x4d,  0x62,  0x49,  0x3e,  0x2d,  0x93,  0x4e,  0xd0,  0x0d,  0x17,  0xfe,
14266   0x9a,  0x07,  0x01,  0xfe,  0xc0,  0x19,  0x16,  0xfe,  0x90,  0x07,  0x26,  0x20,  0x9e,  0x15,  0x82,  0x01,
14267   0x41,  0x15,  0xe2,  0x21,  0x9e,  0x09,  0x07,  0xfb,  0x03,  0xe6,  0xfe,  0x58,  0x57,  0x10,  0xe6,  0x05,
14268   0xfe,  0x2a,  0x06,  0x03,  0x6f,  0x8a,  0x10,  0x6f,  0x1c,  0x07,  0x01,  0x84,  0xfe,  0x9c,  0x32,  0x5f,
14269   0x75,  0x01,  0xa6,  0x86,  0x15,  0xfe,  0xe2,  0x00,  0x2f,  0xed,  0x2a,  0x3c,  0xfe,  0x0a,  0xf0,  0xfe,
14270   0xce,  0x07,  0xae,  0xfe,  0x96,  0x08,  0xfe,  0x06,  0xf0,  0xfe,  0x9e,  0x08,  0xaf,  0xa0,  0x05,  0x29,
14271   0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x2e,  0x12,  0x14,  0x1d,  0x01,  0x08,  0x14,  0x00,  0x01,  0x08,  0x14,
14272   0x00,  0x01,  0x08,  0x14,  0x00,  0x01,  0x08,  0xfe,  0x99,  0xa4,  0x01,  0x08,  0x14,  0x00,  0x05,  0xfe,
14273   0xc6,  0x09,  0x01,  0x76,  0x06,  0x12,  0xfe,  0x3a,  0x12,  0x01,  0x0c,  0x06,  0x12,  0xfe,  0x30,  0x13,
14274   0x14,  0xfe,  0x1b,  0x00,  0x01,  0x08,  0x14,  0x00,  0x01,  0x08,  0x14,  0x00,  0x01,  0x08,  0x14,  0x00,
14275   0x01,  0x08,  0x14,  0x07,  0x01,  0x08,  0x14,  0x00,  0x05,  0xef,  0x7c,  0x4a,  0x78,  0x4f,  0x0f,  0xfe,
14276   0x9a,  0x81,  0x04,  0xfe,  0x9a,  0x83,  0xfe,  0xcb,  0x47,  0x0b,  0x0e,  0x2d,  0x28,  0x48,  0xfe,  0x6c,
14277   0x08,  0x0a,  0x28,  0xfe,  0x09,  0x6f,  0xca,  0xfe,  0xca,  0x45,  0xfe,  0x32,  0x12,  0x53,  0x63,  0x4e,
14278   0x7c,  0x97,  0x2f,  0xfe,  0x7e,  0x08,  0x2a,  0x3c,  0xfe,  0x0a,  0xf0,  0xfe,  0x6c,  0x08,  0xaf,  0xa0,
14279   0xae,  0xfe,  0x96,  0x08,  0x05,  0x29,  0x01,  0x41,  0x05,  0xed,  0x14,  0x24,  0x05,  0xed,  0xfe,  0x9c,
14280   0xf7,  0x9f,  0x01,  0xfe,  0xae,  0x1e,  0xfe,  0x18,  0x58,  0x01,  0xfe,  0xbe,  0x1e,  0xfe,  0x99,  0x58,
14281   0xfe,  0x78,  0x18,  0xfe,  0xf9,  0x18,  0x8e,  0xfe,  0x16,  0x09,  0x10,  0x6a,  0x22,  0x6b,  0x01,  0x0c,
14282   0x61,  0x54,  0x44,  0x21,  0x2c,  0x09,  0x1a,  0xf8,  0x77,  0x01,  0xfe,  0x7e,  0x1e,  0x47,  0x2c,  0x7a,
14283   0x30,  0xf0,  0xfe,  0x83,  0xe7,  0xfe,  0x3f,  0x00,  0x71,  0xfe,  0x03,  0x40,  0x01,  0x0c,  0x61,  0x65,
14284   0x44,  0x01,  0xc2,  0xc8,  0xfe,  0x1f,  0x40,  0x20,  0x6e,  0x01,  0xfe,  0x6a,  0x16,  0xfe,  0x08,  0x50,
14285   0xfe,  0x8a,  0x50,  0xfe,  0x44,  0x51,  0xfe,  0xc6,  0x51,  0xfe,  0x10,  0x10,  0x01,  0xfe,  0xce,  0x1e,
14286   0x01,  0xfe,  0xde,  0x1e,  0x10,  0x68,  0x22,  0x69,  0x01,  0xfe,  0xee,  0x1e,  0x01,  0xfe,  0xfe,  0x1e,
14287   0xfe,  0x40,  0x50,  0xfe,  0xc2,  0x50,  0x10,  0x4b,  0x22,  0x4c,  0xfe,  0x8a,  0x10,  0x01,  0x0c,  0x06,
14288   0x54,  0xfe,  0x50,  0x12,  0x01,  0xfe,  0xae,  0x1e,  0x01,  0xfe,  0xbe,  0x1e,  0x10,  0x6a,  0x22,  0x6b,
14289   0x01,  0x0c,  0x06,  0x65,  0x4e,  0x01,  0xc2,  0x0f,  0xfe,  0x1f,  0x80,  0x04,  0xfe,  0x9f,  0x83,  0x33,
14290   0x0b,  0x0e,  0x20,  0x6e,  0x0f,  0xfe,  0x44,  0x90,  0x04,  0xfe,  0xc4,  0x93,  0x3a,  0x0b,  0xfe,  0xc6,
14291   0x90,  0x04,  0xfe,  0xc6,  0x93,  0x79,  0x0b,  0x0e,  0x10,  0x6c,  0x22,  0x6d,  0x01,  0xfe,  0xce,  0x1e,
14292   0x01,  0xfe,  0xde,  0x1e,  0x10,  0x68,  0x22,  0x69,  0x0f,  0xfe,  0x40,  0x90,  0x04,  0xfe,  0xc0,  0x93,
14293   0x3a,  0x0b,  0xfe,  0xc2,  0x90,  0x04,  0xfe,  0xc2,  0x93,  0x79,  0x0b,  0x0e,  0x10,  0x4b,  0x22,  0x4c,
14294   0x10,  0x64,  0x22,  0x34,  0x01,  0x0c,  0x61,  0x24,  0x44,  0x37,  0x13,  0xfe,  0x4e,  0x11,  0x2f,  0xfe,
14295   0xde,  0x09,  0xfe,  0x9e,  0xf0,  0xfe,  0xf2,  0x09,  0xfe,  0x01,  0x48,  0x1b,  0x3c,  0x37,  0x88,  0xf5,
14296   0xd4,  0xfe,  0x1e,  0x0a,  0xd5,  0xfe,  0x42,  0x0a,  0xd2,  0xfe,  0x1e,  0x0a,  0xd3,  0xfe,  0x42,  0x0a,
14297   0xae,  0xfe,  0x12,  0x0a,  0xfe,  0x06,  0xf0,  0xfe,  0x18,  0x0a,  0xaf,  0xa0,  0x05,  0x29,  0x01,  0x41,
14298   0xfe,  0xc1,  0x10,  0x14,  0x24,  0xfe,  0xc1,  0x10,  0x01,  0x76,  0x06,  0x07,  0xfe,  0x14,  0x12,  0x01,
14299   0x76,  0x06,  0x0d,  0x5d,  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x74,  0x12,  0xfe,  0x2e,  0x1c,  0x05,  0xfe,
14300   0x1a,  0x0c,  0x01,  0x76,  0x06,  0x07,  0x5d,  0x01,  0x76,  0x06,  0x0d,  0x41,  0xfe,  0x2c,  0x1c,  0xfe,
14301   0xaa,  0xf0,  0xfe,  0xce,  0x0a,  0xfe,  0xac,  0xf0,  0xfe,  0x66,  0x0a,  0xfe,  0x92,  0x10,  0xc4,  0xf6,
14302   0xfe,  0xad,  0xf0,  0xfe,  0x72,  0x0a,  0x05,  0xfe,  0x1a,  0x0c,  0xc5,  0xfe,  0xe7,  0x10,  0xfe,  0x2b,
14303   0xf0,  0xbf,  0xfe,  0x6b,  0x18,  0x23,  0xfe,  0x00,  0xfe,  0xfe,  0x1c,  0x12,  0xac,  0xfe,  0xd2,  0xf0,
14304   0xbf,  0xfe,  0x76,  0x18,  0x23,  0x1d,  0x1b,  0xbf,  0x03,  0xe3,  0x23,  0x07,  0x1b,  0xbf,  0xd4,  0x5b,
14305   0xd5,  0x5b,  0xd2,  0x5b,  0xd3,  0x5b,  0xc4,  0xc5,  0xfe,  0xa9,  0x10,  0x75,  0x5e,  0x32,  0x1f,  0x7f,
14306   0x01,  0x42,  0x19,  0xfe,  0x35,  0x00,  0xfe,  0x01,  0xf0,  0x70,  0x19,  0x98,  0x05,  0x70,  0xfe,  0x74,
14307   0x18,  0x23,  0xfe,  0x00,  0xf8,  0x1b,  0x5b,  0x7d,  0x12,  0x01,  0xfe,  0x78,  0x0f,  0x4d,  0x01,  0xfe,
14308   0x96,  0x1a,  0x21,  0x30,  0x77,  0x7d,  0x1d,  0x05,  0x5b,  0x01,  0x0c,  0x06,  0x0d,  0x2b,  0xfe,  0xe2,
14309   0x0b,  0x01,  0x0c,  0x06,  0x54,  0xfe,  0xa6,  0x12,  0x01,  0x0c,  0x06,  0x24,  0xfe,  0x88,  0x13,  0x21,
14310   0x6e,  0xc7,  0x01,  0xfe,  0x1e,  0x1f,  0x0f,  0xfe,  0x83,  0x80,  0x04,  0xfe,  0x83,  0x83,  0xfe,  0xc9,
14311   0x47,  0x0b,  0x0e,  0xfe,  0xc8,  0x44,  0xfe,  0x42,  0x13,  0x0f,  0xfe,  0x04,  0x91,  0x04,  0xfe,  0x84,
14312   0x93,  0xfe,  0xca,  0x57,  0x0b,  0xfe,  0x86,  0x91,  0x04,  0xfe,  0x86,  0x93,  0xfe,  0xcb,  0x57,  0x0b,
14313   0x0e,  0x7a,  0x30,  0xfe,  0x40,  0x59,  0xfe,  0xc1,  0x59,  0x8e,  0x40,  0x03,  0x6a,  0x3b,  0x6b,  0x10,
14314   0x97,  0x22,  0x98,  0xd9,  0x6a,  0xda,  0x6b,  0x01,  0xc2,  0xc8,  0x7a,  0x30,  0x20,  0x6e,  0xdb,  0x64,
14315   0xdc,  0x34,  0x91,  0x6c,  0x7e,  0x6d,  0xfe,  0x44,  0x55,  0xfe,  0xe5,  0x55,  0xfe,  0x04,  0xfa,  0x64,
14316   0xfe,  0x05,  0xfa,  0x34,  0x01,  0xfe,  0x6a,  0x16,  0xa3,  0x26,  0x10,  0x97,  0x10,  0x98,  0x91,  0x6c,
14317   0x7e,  0x6d,  0xfe,  0x14,  0x10,  0x01,  0x0c,  0x06,  0x24,  0x1b,  0x40,  0x91,  0x4b,  0x7e,  0x4c,  0x01,
14318   0x0c,  0x06,  0xfe,  0xf7,  0x00,  0x44,  0x03,  0x68,  0x3b,  0x69,  0xfe,  0x10,  0x58,  0xfe,  0x91,  0x58,
14319   0xfe,  0x14,  0x59,  0xfe,  0x95,  0x59,  0x05,  0x5b,  0x01,  0x0c,  0x06,  0x24,  0x1b,  0x40,  0x01,  0x0c,
14320   0x06,  0xfe,  0xf7,  0x00,  0x44,  0x78,  0x01,  0xfe,  0x8e,  0x1e,  0x4f,  0x0f,  0xfe,  0x10,  0x90,  0x04,
14321   0xfe,  0x90,  0x93,  0x3a,  0x0b,  0xfe,  0x92,  0x90,  0x04,  0xfe,  0x92,  0x93,  0x79,  0x0b,  0x0e,  0xfe,
14322   0xbd,  0x10,  0x01,  0x43,  0x09,  0xbb,  0x1b,  0xfe,  0x6e,  0x0a,  0x15,  0xbb,  0x01,  0x0c,  0x06,  0x0d,
14323   0xfe,  0x14,  0x13,  0x03,  0x4b,  0x3b,  0x4c,  0x8e,  0xfe,  0x6e,  0x0a,  0xfe,  0x0c,  0x58,  0xfe,  0x8d,
14324   0x58,  0x05,  0x5b,  0x26,  0x3e,  0x0f,  0xfe,  0x19,  0x80,  0x04,  0xfe,  0x99,  0x83,  0x33,  0x0b,  0x0e,
14325   0xfe,  0xe5,  0x10,  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x1a,  0x12,  0xfe,  0x6c,  0x19,  0xfe,  0x19,  0x41,
14326   0xfe,  0x6b,  0x18,  0xac,  0xfe,  0xd1,  0xf0,  0xef,  0x1f,  0x92,  0x01,  0x42,  0x19,  0xfe,  0x44,  0x00,
14327   0xfe,  0x90,  0x10,  0xfe,  0x6c,  0x19,  0xd9,  0x4b,  0xfe,  0xed,  0x19,  0xda,  0x4c,  0xfe,  0x0c,  0x51,
14328   0xfe,  0x8e,  0x51,  0xfe,  0x6b,  0x18,  0x23,  0xfe,  0x00,  0xff,  0x31,  0xfe,  0x76,  0x10,  0xac,  0xfe,
14329   0xd2,  0xf0,  0xfe,  0xba,  0x0c,  0xfe,  0x76,  0x18,  0x23,  0x1d,  0x5d,  0x03,  0xe3,  0x23,  0x07,  0xfe,
14330   0x08,  0x13,  0x19,  0xfe,  0x16,  0x00,  0x05,  0x70,  0xfe,  0xd1,  0xf0,  0xfe,  0xcc,  0x0c,  0x1f,  0x92,
14331   0x01,  0x42,  0x19,  0xfe,  0x17,  0x00,  0x5c,  0xfe,  0xce,  0xf0,  0xfe,  0xd2,  0x0c,  0xfe,  0x3e,  0x10,
14332   0xfe,  0xcd,  0xf0,  0xfe,  0xde,  0x0c,  0x19,  0xfe,  0x22,  0x00,  0x05,  0x70,  0xfe,  0xcb,  0xf0,  0xfe,
14333   0xea,  0x0c,  0x19,  0xfe,  0x24,  0x00,  0x05,  0x70,  0xfe,  0xd0,  0xf0,  0xfe,  0xf4,  0x0c,  0x19,  0x94,
14334   0xfe,  0x1c,  0x10,  0xfe,  0xcf,  0xf0,  0xfe,  0xfe,  0x0c,  0x19,  0x4a,  0xf3,  0xfe,  0xcc,  0xf0,  0xef,
14335   0x01,  0x76,  0x06,  0x24,  0x4d,  0x19,  0xfe,  0x12,  0x00,  0x37,  0x13,  0xfe,  0x4e,  0x11,  0x2f,  0xfe,
14336   0x16,  0x0d,  0xfe,  0x9e,  0xf0,  0xfe,  0x2a,  0x0d,  0xfe,  0x01,  0x48,  0x1b,  0x3c,  0x37,  0x88,  0xf5,
14337   0xd4,  0x29,  0xd5,  0x29,  0xd2,  0x29,  0xd3,  0x29,  0x37,  0xfe,  0x9c,  0x32,  0x2f,  0xfe,  0x3e,  0x0d,
14338   0x2a,  0x3c,  0xae,  0xfe,  0x62,  0x0d,  0xaf,  0xa0,  0xd4,  0x9f,  0xd5,  0x9f,  0xd2,  0x9f,  0xd3,  0x9f,
14339   0x05,  0x29,  0x01,  0x41,  0xfe,  0xd3,  0x10,  0x15,  0xfe,  0xe8,  0x00,  0xc4,  0xc5,  0x75,  0xd7,  0x99,
14340   0xd8,  0x9c,  0xfe,  0x89,  0xf0,  0x29,  0x27,  0x25,  0xbe,  0xd7,  0x99,  0xd8,  0x9c,  0x2f,  0xfe,  0x8c,
14341   0x0d,  0x16,  0x29,  0x27,  0x25,  0xbd,  0xfe,  0x01,  0x48,  0xa4,  0x19,  0xfe,  0x42,  0x00,  0x05,  0x70,
14342   0x90,  0x07,  0xfe,  0x81,  0x49,  0x1b,  0xfe,  0x64,  0x0e,  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x44,  0x13,
14343   0x19,  0x00,  0x2d,  0x0d,  0xfe,  0x54,  0x12,  0x2d,  0xfe,  0x28,  0x00,  0x2b,  0xfe,  0xda,  0x0e,  0x0a,
14344   0x57,  0x01,  0x18,  0x09,  0x00,  0x36,  0x46,  0xfe,  0x28,  0x00,  0xfe,  0xfa,  0x10,  0x01,  0xfe,  0xf4,
14345   0x1c,  0x01,  0xfe,  0x00,  0x1d,  0x0a,  0xba,  0x01,  0xfe,  0x58,  0x10,  0x40,  0x15,  0x56,  0x01,  0x85,
14346   0x05,  0x35,  0x19,  0xfe,  0x44,  0x00,  0x2d,  0x0d,  0xf7,  0x46,  0x0d,  0xfe,  0xcc,  0x10,  0x01,  0xa7,
14347   0x46,  0x0d,  0xfe,  0xc2,  0x10,  0x01,  0xa7,  0x0f,  0xfe,  0x19,  0x82,  0x04,  0xfe,  0x99,  0x83,  0xfe,
14348   0xcc,  0x47,  0x0b,  0x0e,  0xfe,  0x34,  0x46,  0xa5,  0x46,  0x0d,  0x19,  0xfe,  0x43,  0x00,  0xfe,  0xa2,
14349   0x10,  0x01,  0x0c,  0x61,  0x0d,  0x44,  0x01,  0xfe,  0xf4,  0x1c,  0x01,  0xfe,  0x00,  0x1d,  0x40,  0x15,
14350   0x56,  0x01,  0x85,  0x7d,  0x0d,  0x40,  0x51,  0x01,  0xfe,  0x9e,  0x1e,  0x05,  0xfe,  0x3a,  0x03,  0x01,
14351   0x0c,  0x06,  0x0d,  0x5d,  0x46,  0x0d,  0x19,  0x00,  0xfe,  0x62,  0x10,  0x01,  0x76,  0x06,  0x12,  0xfe,
14352   0x5c,  0x12,  0x01,  0x0c,  0x06,  0x12,  0xfe,  0x52,  0x13,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,
14353   0x8e,  0x0e,  0xfe,  0x1c,  0x1c,  0xfe,  0x9d,  0xf0,  0xfe,  0x94,  0x0e,  0x01,  0x0c,  0x61,  0x12,  0x44,
14354   0xfe,  0x9f,  0x10,  0x19,  0xfe,  0x15,  0x00,  0xfe,  0x04,  0xe6,  0x0d,  0x4f,  0xfe,  0x2e,  0x10,  0x19,
14355   0xfe,  0x13,  0x00,  0xfe,  0x10,  0x10,  0x19,  0xfe,  0x47,  0x00,  0xf1,  0x19,  0xfe,  0x41,  0x00,  0xa2,
14356   0x19,  0xfe,  0x24,  0x00,  0x86,  0xc4,  0xc5,  0x75,  0x03,  0x81,  0x1e,  0x2b,  0xea,  0x4f,  0xfe,  0x04,
14357   0xe6,  0x12,  0xfe,  0x9d,  0x41,  0xfe,  0x1c,  0x42,  0x40,  0x01,  0xf4,  0x05,  0x35,  0xfe,  0x12,  0x1c,
14358   0x1f,  0x0d,  0x47,  0xb5,  0xc3,  0x1f,  0xfe,  0x31,  0x00,  0x47,  0xb8,  0x01,  0xfe,  0xd4,  0x11,  0x05,
14359   0xe9,  0x51,  0xfe,  0x06,  0xec,  0xe0,  0xfe,  0x0e,  0x47,  0x46,  0x28,  0xfe,  0xce,  0x45,  0x31,  0x51,
14360   0xfe,  0x06,  0xea,  0xe0,  0xfe,  0x47,  0x4b,  0x45,  0xfe,  0x75,  0x57,  0x03,  0x67,  0xfe,  0x98,  0x56,
14361   0xfe,  0x38,  0x12,  0x0a,  0x5a,  0x01,  0x18,  0xfe,  0x44,  0x48,  0x60,  0x01,  0x0c,  0x06,  0x28,  0xfe,
14362   0x18,  0x13,  0x0a,  0x57,  0x01,  0x18,  0x3e,  0xfe,  0x41,  0x58,  0x0a,  0xba,  0xfe,  0xfa,  0x14,  0xfe,
14363   0x49,  0x54,  0xb0,  0xfe,  0x5e,  0x0f,  0x05,  0xfe,  0x3a,  0x03,  0x0a,  0x67,  0xfe,  0xe0,  0x14,  0xfe,
14364   0x0e,  0x47,  0x46,  0x28,  0xfe,  0xce,  0x45,  0x31,  0x51,  0xfe,  0xce,  0x47,  0xfe,  0xad,  0x13,  0x05,
14365   0x35,  0x21,  0x2c,  0x09,  0x1a,  0xfe,  0x98,  0x12,  0x26,  0x20,  0x96,  0x20,  0xe7,  0xfe,  0x08,  0x1c,
14366   0xfe,  0x7c,  0x19,  0xfe,  0xfd,  0x19,  0xfe,  0x0a,  0x1c,  0x03,  0xe5,  0xfe,  0x48,  0x55,  0xa5,  0x3b,
14367   0xfe,  0x62,  0x01,  0xfe,  0xc9,  0x55,  0x31,  0xfe,  0x74,  0x10,  0x01,  0xfe,  0xf0,  0x1a,  0x03,  0xfe,
14368   0x38,  0x01,  0x3b,  0xfe,  0x3a,  0x01,  0x8e,  0xfe,  0x1e,  0x10,  0xfe,  0x02,  0xec,  0xe7,  0x53,  0x00,
14369   0x36,  0xfe,  0x04,  0xec,  0x2c,  0x60,  0xfe,  0x05,  0xf6,  0xfe,  0x34,  0x01,  0x01,  0xfe,  0x62,  0x1b,
14370   0x01,  0xfe,  0xce,  0x1e,  0xb2,  0x11,  0xfe,  0x18,  0x13,  0xca,  0xfe,  0x02,  0xea,  0xe7,  0x53,  0x92,
14371   0xfe,  0xc3,  0x13,  0x1f,  0x12,  0x47,  0xb5,  0xc3,  0xfe,  0x2a,  0x10,  0x03,  0xfe,  0x38,  0x01,  0x23,
14372   0xfe,  0xf0,  0xff,  0x10,  0xe5,  0x03,  0xfe,  0x3a,  0x01,  0x10,  0xfe,  0x62,  0x01,  0x01,  0xfe,  0x1e,
14373   0x1e,  0x20,  0x2c,  0x15,  0x56,  0x01,  0xfe,  0x9e,  0x1e,  0x13,  0x07,  0x02,  0x26,  0x02,  0x21,  0x96,
14374   0xc7,  0x20,  0x96,  0x09,  0x92,  0xfe,  0x79,  0x13,  0x1f,  0x1d,  0x47,  0xb5,  0xc3,  0xfe,  0xe1,  0x10,
14375   0xcf,  0xfe,  0x03,  0xdc,  0xfe,  0x73,  0x57,  0xfe,  0x80,  0x5d,  0x02,  0xcf,  0xfe,  0x03,  0xdc,  0xfe,
14376   0x5b,  0x57,  0xfe,  0x80,  0x5d,  0x02,  0xfe,  0x03,  0x57,  0xcf,  0x26,  0xfe,  0x00,  0xcc,  0x02,  0xfe,
14377   0x03,  0x57,  0xcf,  0x89,  0x02,  0x01,  0x0c,  0x06,  0x4a,  0xfe,  0x4e,  0x13,  0x0f,  0xfe,  0x1c,  0x80,
14378   0x04,  0xfe,  0x9c,  0x83,  0x33,  0x0b,  0x0e,  0x09,  0x07,  0xfe,  0x3a,  0x13,  0x0f,  0xfe,  0x1e,  0x80,
14379   0x04,  0xfe,  0x9e,  0x83,  0x33,  0x0b,  0x0e,  0xfe,  0x2a,  0x13,  0x0f,  0xfe,  0x1d,  0x80,  0x04,  0xfe,
14380   0x9d,  0x83,  0xfe,  0xf9,  0x13,  0x0e,  0xfe,  0x1c,  0x13,  0x01,  0xfe,  0xee,  0x1e,  0xac,  0xfe,  0x14,
14381   0x13,  0x01,  0xfe,  0xfe,  0x1e,  0xfe,  0x81,  0x58,  0xfa,  0x01,  0xfe,  0x0e,  0x1f,  0xfe,  0x30,  0xf4,
14382   0x0d,  0xfe,  0x3c,  0x50,  0xa2,  0x01,  0xfe,  0x92,  0x1b,  0x01,  0x43,  0x09,  0x56,  0xfb,  0x01,  0xfe,
14383   0xc8,  0x1a,  0x01,  0x0c,  0x06,  0x28,  0xa4,  0x01,  0xfe,  0xf4,  0x1c,  0x01,  0xfe,  0x00,  0x1d,  0x15,
14384   0xfe,  0xe9,  0x00,  0x01,  0x0c,  0x06,  0x4a,  0xfe,  0x4e,  0x13,  0x01,  0xfe,  0x22,  0x1b,  0xfe,  0x1e,
14385   0x1c,  0x0f,  0xfe,  0x14,  0x90,  0x04,  0xfe,  0x94,  0x93,  0x3a,  0x0b,  0xfe,  0x96,  0x90,  0x04,  0xfe,
14386   0x96,  0x93,  0x79,  0x0b,  0x0e,  0x10,  0xfe,  0x64,  0x01,  0x22,  0xfe,  0x66,  0x01,  0x01,  0x0c,  0x06,
14387   0x65,  0xf9,  0x0f,  0xfe,  0x03,  0x80,  0x04,  0xfe,  0x83,  0x83,  0x33,  0x0b,  0x0e,  0x77,  0xfe,  0x01,
14388   0xec,  0x2c,  0xfe,  0x80,  0x40,  0x20,  0x2c,  0x7a,  0x30,  0x15,  0xdf,  0x40,  0x21,  0x2c,  0xfe,  0x00,
14389   0x40,  0x8d,  0x2c,  0x02,  0xfe,  0x08,  0x1c,  0x03,  0xfe,  0xac,  0x00,  0xfe,  0x06,  0x58,  0x03,  0xfe,
14390   0xae,  0x00,  0xfe,  0x07,  0x58,  0x03,  0xfe,  0xb0,  0x00,  0xfe,  0x08,  0x58,  0x03,  0xfe,  0xb2,  0x00,
14391   0xfe,  0x09,  0x58,  0xfe,  0x0a,  0x1c,  0x2e,  0x49,  0x20,  0xe0,  0x26,  0x10,  0x66,  0x10,  0x55,  0x10,
14392   0x6f,  0x13,  0x57,  0x52,  0x4f,  0x1c,  0x28,  0xfe,  0x90,  0x4d,  0xfe,  0x91,  0x54,  0x2b,  0xfe,  0x88,
14393   0x11,  0x46,  0x1a,  0x13,  0x5a,  0x52,  0x1c,  0x4a,  0xfe,  0x90,  0x4d,  0xfe,  0x91,  0x54,  0x2b,  0xfe,
14394   0x9e,  0x11,  0x2e,  0x1a,  0x20,  0x2c,  0x90,  0x34,  0x60,  0x21,  0x2c,  0xfe,  0x00,  0x40,  0x8d,  0x2c,
14395   0x15,  0xdf,  0xfe,  0x14,  0x56,  0xfe,  0xd6,  0xf0,  0xfe,  0xb2,  0x11,  0xfe,  0x12,  0x1c,  0x75,  0xfe,
14396   0x14,  0x1c,  0xfe,  0x10,  0x1c,  0xfe,  0x18,  0x1c,  0x02,  0x51,  0xfe,  0x0c,  0x14,  0xfe,  0x0e,  0x47,
14397   0xfe,  0x07,  0xe6,  0x28,  0xfe,  0xce,  0x47,  0xfe,  0xf5,  0x13,  0x02,  0x01,  0xa7,  0x90,  0x34,  0x60,
14398   0xfe,  0x06,  0x80,  0xfe,  0x48,  0x47,  0xfe,  0x42,  0x13,  0xfe,  0x02,  0x80,  0x09,  0x56,  0xfe,  0x34,
14399   0x13,  0x0a,  0x5a,  0x01,  0x18,  0xcb,  0xfe,  0x36,  0x12,  0xfe,  0x41,  0x48,  0xfe,  0x45,  0x48,  0x01,
14400   0xfe,  0xb2,  0x16,  0xfe,  0x00,  0xcc,  0xcb,  0xfe,  0xf3,  0x13,  0x3f,  0x89,  0x09,  0x1a,  0xa5,  0x0a,
14401   0x9d,  0x01,  0x18,  0xfe,  0x80,  0x5c,  0x01,  0x85,  0xf2,  0x09,  0x9b,  0xa4,  0xfe,  0x14,  0x56,  0xfe,
14402   0xd6,  0xf0,  0xfe,  0xec,  0x11,  0x02,  0xfe,  0x44,  0x58,  0x77,  0xfe,  0x01,  0xec,  0xb8,  0xfe,  0x9e,
14403   0x40,  0xfe,  0x9d,  0xe7,  0x00,  0xfe,  0x9c,  0xe7,  0x12,  0x8d,  0x30,  0x01,  0xf4,  0xfe,  0xdd,  0x10,
14404   0x37,  0xd7,  0x99,  0xd8,  0x9c,  0x27,  0x25,  0xee,  0x09,  0x12,  0xfe,  0x48,  0x12,  0x09,  0x0d,  0xfe,
14405   0x56,  0x12,  0x09,  0x1d,  0xfe,  0x30,  0x12,  0x09,  0xdd,  0x1b,  0xfe,  0xc4,  0x13,  0x09,  0xfe,  0x23,
14406   0x00,  0x1b,  0xfe,  0xd0,  0x13,  0x09,  0x07,  0x1b,  0xfe,  0x34,  0x14,  0x09,  0x24,  0xfe,  0x12,  0x12,
14407   0x09,  0x00,  0x1b,  0x29,  0x1f,  0xdd,  0x01,  0x42,  0xa1,  0x32,  0x01,  0x08,  0xae,  0x41,  0x02,  0x32,
14408   0xfe,  0x62,  0x08,  0x0a,  0xe1,  0x01,  0xfe,  0x58,  0x10,  0x15,  0x9b,  0x05,  0x35,  0x32,  0x01,  0x43,
14409   0x09,  0xbb,  0xfe,  0xd7,  0x13,  0x91,  0x4b,  0x7e,  0x4c,  0x8e,  0xfe,  0x80,  0x13,  0x01,  0x0c,  0x06,
14410   0x54,  0xfe,  0x72,  0x12,  0xdb,  0x64,  0xdc,  0x34,  0xfe,  0x44,  0x55,  0xfe,  0xe5,  0x55,  0xb0,  0xfe,
14411   0x4a,  0x13,  0x21,  0x6e,  0xfe,  0x26,  0x13,  0x03,  0x97,  0x3b,  0x98,  0x8e,  0xfe,  0xb6,  0x0e,  0x10,
14412   0x6a,  0x22,  0x6b,  0x26,  0x10,  0x97,  0x10,  0x98,  0x01,  0xc2,  0x2e,  0x49,  0x88,  0x20,  0x6e,  0x01,
14413   0xfe,  0x6a,  0x16,  0xdb,  0x64,  0xdc,  0x34,  0xfe,  0x04,  0x55,  0xfe,  0xa5,  0x55,  0xfe,  0x04,  0xfa,
14414   0x64,  0xfe,  0x05,  0xfa,  0x34,  0xfe,  0x8f,  0x10,  0x03,  0x6c,  0x3b,  0x6d,  0xfe,  0x40,  0x56,  0xfe,
14415   0xe1,  0x56,  0x10,  0x6c,  0x22,  0x6d,  0x71,  0xdb,  0x64,  0xdc,  0x34,  0xfe,  0x44,  0x55,  0xfe,  0xe5,
14416   0x55,  0x03,  0x68,  0x3b,  0x69,  0xfe,  0x00,  0x56,  0xfe,  0xa1,  0x56,  0x10,  0x68,  0x22,  0x69,  0x01,
14417   0x0c,  0x06,  0x54,  0xf9,  0x21,  0x6e,  0xfe,  0x1f,  0x40,  0x03,  0x6a,  0x3b,  0x6b,  0xfe,  0x2c,  0x50,
14418   0xfe,  0xae,  0x50,  0x03,  0x6c,  0x3b,  0x6d,  0xfe,  0x44,  0x50,  0xfe,  0xc6,  0x50,  0x03,  0x68,  0x3b,
14419   0x69,  0xfe,  0x08,  0x50,  0xfe,  0x8a,  0x50,  0x03,  0x4b,  0x3b,  0x4c,  0xfe,  0x40,  0x50,  0xfe,  0xc2,
14420   0x50,  0x05,  0x73,  0x2e,  0x07,  0x20,  0x9e,  0x05,  0x72,  0x32,  0x01,  0x08,  0x16,  0x3d,  0x27,  0x25,
14421   0xee,  0x09,  0x07,  0x2b,  0x3d,  0x01,  0x43,  0x09,  0xbb,  0x2b,  0x72,  0x01,  0xa6,  0x23,  0x3f,  0x1b,
14422   0x3d,  0x01,  0x0c,  0x06,  0x0d,  0xfe,  0x1e,  0x13,  0x91,  0x4b,  0x7e,  0x4c,  0xfe,  0x0a,  0x55,  0x31,
14423   0xfe,  0x8b,  0x55,  0xd9,  0x4b,  0xda,  0x4c,  0xfe,  0x0c,  0x51,  0xfe,  0x8e,  0x51,  0x05,  0x72,  0x01,
14424   0xfe,  0x8e,  0x1e,  0xca,  0xfe,  0x19,  0x41,  0x05,  0x72,  0x32,  0x01,  0x08,  0x2a,  0x3c,  0x16,  0xc0,
14425   0x27,  0x25,  0xbe,  0x2d,  0x1d,  0xc0,  0x2d,  0x0d,  0x83,  0x2d,  0x7f,  0x1b,  0xfe,  0x66,  0x15,  0x05,
14426   0x3d,  0x01,  0x08,  0x2a,  0x3c,  0x16,  0xc0,  0x27,  0x25,  0xbd,  0x09,  0x1d,  0x2b,  0x3d,  0x01,  0x08,
14427   0x16,  0xc0,  0x27,  0x25,  0xfe,  0xe8,  0x09,  0xfe,  0xc2,  0x49,  0x50,  0x03,  0xb6,  0x1e,  0x83,  0x01,
14428   0x38,  0x06,  0x24,  0x31,  0xa1,  0xfe,  0xbb,  0x45,  0x2d,  0x00,  0xa4,  0x46,  0x07,  0x90,  0x3f,  0x01,
14429   0xfe,  0xf8,  0x15,  0x01,  0xa6,  0x86,  0xfe,  0x4b,  0x45,  0xfe,  0x20,  0x13,  0x01,  0x43,  0x09,  0x82,
14430   0xfe,  0x16,  0x13,  0x03,  0x9a,  0x1e,  0x5d,  0x03,  0x55,  0x1e,  0x31,  0x5e,  0x05,  0x72,  0xfe,  0xc0,
14431   0x5d,  0x01,  0xa7,  0xfe,  0x03,  0x17,  0x03,  0x66,  0x8a,  0x10,  0x66,  0x5e,  0x32,  0x01,  0x08,  0x17,
14432   0x73,  0x01,  0xfe,  0x56,  0x19,  0x05,  0x73,  0x01,  0x08,  0x2a,  0x3c,  0x16,  0x3d,  0x27,  0x25,  0xbd,
14433   0x09,  0x07,  0x2b,  0x3d,  0x01,  0xfe,  0xbe,  0x16,  0xfe,  0x42,  0x58,  0xfe,  0xe8,  0x14,  0x01,  0xa6,
14434   0x86,  0xfe,  0x4a,  0xf4,  0x0d,  0x1b,  0x3d,  0xfe,  0x4a,  0xf4,  0x07,  0xfe,  0x0e,  0x12,  0x01,  0x43,
14435   0x09,  0x82,  0x4e,  0x05,  0x72,  0x03,  0x55,  0x8a,  0x10,  0x55,  0x5e,  0x32,  0x01,  0x08,  0x17,  0x73,
14436   0x01,  0xfe,  0x84,  0x19,  0x05,  0x73,  0x01,  0x08,  0x2a,  0x3c,  0x16,  0x3d,  0x27,  0x25,  0xbd,  0x09,
14437   0x12,  0x2b,  0x3d,  0x01,  0xfe,  0xe8,  0x17,  0x8b,  0xfe,  0xaa,  0x14,  0xfe,  0xb6,  0x14,  0x86,  0xa8,
14438   0xb2,  0x0d,  0x1b,  0x3d,  0xb2,  0x07,  0xfe,  0x0e,  0x12,  0x01,  0x43,  0x09,  0x82,  0x4e,  0x05,  0x72,
14439   0x03,  0x6f,  0x8a,  0x10,  0x6f,  0x5e,  0x32,  0x01,  0x08,  0x17,  0x73,  0x01,  0xfe,  0xc0,  0x19,  0x05,
14440   0x73,  0x13,  0x07,  0x2f,  0xfe,  0xcc,  0x15,  0x17,  0xfe,  0xe2,  0x15,  0x5f,  0xcc,  0x01,  0x08,  0x26,
14441   0x5f,  0x02,  0x8f,  0xfe,  0xde,  0x15,  0x2a,  0xfe,  0xde,  0x15,  0x16,  0xfe,  0xcc,  0x15,  0x5e,  0x32,
14442   0x01,  0x08,  0xfe,  0xd5,  0x10,  0x13,  0x58,  0xff,  0x02,  0x00,  0x57,  0x52,  0xad,  0x23,  0xfe,  0xff,
14443   0x7f,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x02,  0x13,  0x58,  0xff,  0x02,  0x00,  0x57,  0x52,  0xad,
14444   0x23,  0x3f,  0xfe,  0x30,  0x56,  0xfe,  0x00,  0x5c,  0x02,  0x13,  0x58,  0xff,  0x02,  0x00,  0x57,  0x52,
14445   0xad,  0x02,  0x13,  0x58,  0xff,  0x02,  0x00,  0x57,  0x52,  0xfe,  0x00,  0x5e,  0x02,  0x13,  0x58,  0xff,
14446   0x02,  0x00,  0x57,  0x52,  0xad,  0xfe,  0x0b,  0x58,  0x02,  0x0a,  0x66,  0x01,  0x5c,  0x0a,  0x55,  0x01,
14447   0x5c,  0x0a,  0x6f,  0x01,  0x5c,  0x02,  0x01,  0xfe,  0x1e,  0x1f,  0x23,  0x1a,  0xff,  0x03,  0x00,  0x54,
14448   0xfe,  0x00,  0xf4,  0x24,  0x52,  0x0f,  0xfe,  0x00,  0x7c,  0x04,  0xfe,  0x07,  0x7c,  0x3a,  0x0b,  0x0e,
14449   0xfe,  0x00,  0x71,  0xfe,  0xf9,  0x18,  0xfe,  0x7a,  0x19,  0xfe,  0xfb,  0x19,  0xfe,  0x1a,  0xf7,  0x00,
14450   0xfe,  0x1b,  0xf7,  0x00,  0x7a,  0x30,  0x10,  0x68,  0x22,  0x69,  0xd9,  0x6c,  0xda,  0x6d,  0x02,  0xfe,
14451   0x62,  0x08,  0xfe,  0x82,  0x4a,  0xfe,  0xe1,  0x1a,  0xfe,  0x83,  0x5a,  0x77,  0x02,  0x01,  0xc6,  0xfe,
14452   0x42,  0x48,  0x4f,  0x50,  0x45,  0x01,  0x08,  0x16,  0xfe,  0xe0,  0x17,  0x27,  0x25,  0xbe,  0x01,  0x08,
14453   0x16,  0xfe,  0xe0,  0x17,  0x27,  0x25,  0xfe,  0xe8,  0x0a,  0xfe,  0xc1,  0x59,  0x03,  0x9a,  0x1e,  0xfe,
14454   0xda,  0x12,  0x01,  0x38,  0x06,  0x12,  0xfe,  0xd0,  0x13,  0x26,  0x53,  0x12,  0x48,  0xfe,  0x08,  0x17,
14455   0xd1,  0x12,  0x53,  0x12,  0xfe,  0x1e,  0x13,  0x2d,  0xb4,  0x7b,  0xfe,  0x26,  0x17,  0x4d,  0x13,  0x07,
14456   0x1c,  0xb4,  0x90,  0x04,  0xfe,  0x78,  0x10,  0xff,  0x02,  0x83,  0x55,  0xf1,  0xff,  0x02,  0x83,  0x55,
14457   0x53,  0x1d,  0xfe,  0x12,  0x13,  0xd6,  0xfe,  0x30,  0x00,  0xb0,  0xfe,  0x80,  0x17,  0x1c,  0x63,  0x13,
14458   0x07,  0xfe,  0x56,  0x10,  0x53,  0x0d,  0xfe,  0x16,  0x13,  0xd6,  0xfe,  0x64,  0x00,  0xb0,  0xfe,  0x80,
14459   0x17,  0x0a,  0xfe,  0x64,  0x00,  0x1c,  0x94,  0x13,  0x07,  0xfe,  0x28,  0x10,  0x53,  0x07,  0xfe,  0x60,
14460   0x13,  0xd6,  0xfe,  0xc8,  0x00,  0xb0,  0xfe,  0x80,  0x17,  0x0a,  0xfe,  0xc8,  0x00,  0x1c,  0x95,  0x13,
14461   0x07,  0x71,  0xd6,  0xfe,  0x90,  0x01,  0x48,  0xfe,  0x8c,  0x17,  0x45,  0xf3,  0xfe,  0x43,  0xf4,  0x96,
14462   0xfe,  0x56,  0xf0,  0xfe,  0x9e,  0x17,  0xfe,  0x04,  0xf4,  0x58,  0xfe,  0x43,  0xf4,  0x94,  0xf6,  0x8b,
14463   0x01,  0xfe,  0x24,  0x16,  0x23,  0x3f,  0xfc,  0xa8,  0x8c,  0x49,  0x48,  0xfe,  0xda,  0x17,  0x62,  0x49,
14464   0xfe,  0x1c,  0x10,  0xa8,  0x8c,  0x80,  0x48,  0xfe,  0xda,  0x17,  0x62,  0x80,  0x71,  0x50,  0x26,  0xfe,
14465   0x4d,  0xf4,  0x00,  0xf7,  0x45,  0x13,  0x07,  0xfe,  0xb4,  0x56,  0xfe,  0xc3,  0x58,  0x02,  0x50,  0x13,
14466   0x0d,  0x02,  0x50,  0x3e,  0x78,  0x4f,  0x45,  0x01,  0x08,  0x16,  0xa9,  0x27,  0x25,  0xbe,  0xfe,  0x03,
14467   0xea,  0xfe,  0x7e,  0x01,  0x01,  0x08,  0x16,  0xa9,  0x27,  0x25,  0xfe,  0xe9,  0x0a,  0x01,  0x08,  0x16,
14468   0xa9,  0x27,  0x25,  0xfe,  0xe9,  0x0a,  0xfe,  0x05,  0xea,  0xfe,  0x7f,  0x01,  0x01,  0x08,  0x16,  0xa9,
14469   0x27,  0x25,  0xfe,  0x69,  0x09,  0xfe,  0x02,  0xea,  0xfe,  0x80,  0x01,  0x01,  0x08,  0x16,  0xa9,  0x27,
14470   0x25,  0xfe,  0xe8,  0x08,  0x47,  0xfe,  0x81,  0x01,  0x03,  0xb6,  0x1e,  0x83,  0x01,  0x38,  0x06,  0x24,
14471   0x31,  0xa2,  0x78,  0xf2,  0x53,  0x07,  0x36,  0xfe,  0x34,  0xf4,  0x3f,  0xa1,  0x78,  0x03,  0x9a,  0x1e,
14472   0x83,  0x01,  0x38,  0x06,  0x12,  0x31,  0xf0,  0x4f,  0x45,  0xfe,  0x90,  0x10,  0xfe,  0x40,  0x5a,  0x23,
14473   0x3f,  0xfb,  0x8c,  0x49,  0x48,  0xfe,  0xaa,  0x18,  0x62,  0x49,  0x71,  0x8c,  0x80,  0x48,  0xfe,  0xaa,
14474   0x18,  0x62,  0x80,  0xfe,  0xb4,  0x56,  0xfe,  0x40,  0x5d,  0x01,  0xc6,  0x01,  0xfe,  0xac,  0x1d,  0xfe,
14475   0x02,  0x17,  0xfe,  0xc8,  0x45,  0xfe,  0x5a,  0xf0,  0xfe,  0xc0,  0x18,  0xfe,  0x43,  0x48,  0x2d,  0x93,
14476   0x36,  0xfe,  0x34,  0xf4,  0xfe,  0x00,  0x11,  0xfe,  0x40,  0x10,  0x2d,  0xb4,  0x36,  0xfe,  0x34,  0xf4,
14477   0x04,  0xfe,  0x34,  0x10,  0x2d,  0xfe,  0x0b,  0x00,  0x36,  0x46,  0x63,  0xfe,  0x28,  0x10,  0xfe,  0xc0,
14478   0x49,  0xff,  0x02,  0x00,  0x54,  0xb2,  0xfe,  0x90,  0x01,  0x48,  0xfe,  0xfa,  0x18,  0x45,  0xfe,  0x1c,
14479   0xf4,  0x3f,  0xf3,  0xfe,  0x40,  0xf4,  0x96,  0xfe,  0x56,  0xf0,  0xfe,  0x0c,  0x19,  0xfe,  0x04,  0xf4,
14480   0x58,  0xfe,  0x40,  0xf4,  0x94,  0xf6,  0x3e,  0x2d,  0x93,  0x4e,  0xd0,  0x0d,  0x21,  0xfe,  0x7f,  0x01,
14481   0xfe,  0xc8,  0x46,  0xfe,  0x24,  0x13,  0x8c,  0x00,  0x5d,  0x26,  0x21,  0xfe,  0x7e,  0x01,  0xfe,  0xc8,
14482   0x45,  0xfe,  0x14,  0x13,  0x21,  0xfe,  0x80,  0x01,  0xfe,  0x48,  0x45,  0xfa,  0x21,  0xfe,  0x81,  0x01,
14483   0xfe,  0xc8,  0x44,  0x4e,  0x26,  0x02,  0x13,  0x07,  0x02,  0x78,  0x45,  0x50,  0x13,  0x0d,  0x02,  0x14,
14484   0x07,  0x01,  0x08,  0x17,  0xfe,  0x82,  0x19,  0x14,  0x0d,  0x01,  0x08,  0x17,  0xfe,  0x82,  0x19,  0x14,
14485   0x1d,  0x01,  0x08,  0x17,  0xfe,  0x82,  0x19,  0x5f,  0xfe,  0x89,  0x49,  0x01,  0x08,  0x02,  0x14,  0x07,
14486   0x01,  0x08,  0x17,  0xc1,  0x14,  0x1d,  0x01,  0x08,  0x17,  0xc1,  0x14,  0x07,  0x01,  0x08,  0x17,  0xc1,
14487   0xfe,  0x89,  0x49,  0x01,  0x08,  0x17,  0xc1,  0x5f,  0xfe,  0x89,  0x4a,  0x01,  0x08,  0x02,  0x50,  0x02,
14488   0x14,  0x07,  0x01,  0x08,  0x17,  0x74,  0x14,  0x7f,  0x01,  0x08,  0x17,  0x74,  0x14,  0x12,  0x01,  0x08,
14489   0x17,  0x74,  0xfe,  0x89,  0x49,  0x01,  0x08,  0x17,  0x74,  0x14,  0x00,  0x01,  0x08,  0x17,  0x74,  0xfe,
14490   0x89,  0x4a,  0x01,  0x08,  0x17,  0x74,  0xfe,  0x09,  0x49,  0x01,  0x08,  0x17,  0x74,  0x5f,  0xcc,  0x01,
14491   0x08,  0x02,  0x21,  0xe4,  0x09,  0x07,  0xfe,  0x4c,  0x13,  0xc8,  0x20,  0xe4,  0xfe,  0x49,  0xf4,  0x00,
14492   0x4d,  0x5f,  0xa1,  0x5e,  0xfe,  0x01,  0xec,  0xfe,  0x27,  0x01,  0xcc,  0xff,  0x02,  0x00,  0x10,  0x2f,
14493   0xfe,  0x3e,  0x1a,  0x01,  0x43,  0x09,  0xfe,  0xe3,  0x00,  0xfe,  0x22,  0x13,  0x16,  0xfe,  0x64,  0x1a,
14494   0x26,  0x20,  0x9e,  0x01,  0x41,  0x21,  0x9e,  0x09,  0x07,  0x5d,  0x01,  0x0c,  0x61,  0x07,  0x44,  0x02,
14495   0x0a,  0x5a,  0x01,  0x18,  0xfe,  0x00,  0x40,  0xaa,  0x09,  0x1a,  0xfe,  0x12,  0x13,  0x0a,  0x9d,  0x01,
14496   0x18,  0xaa,  0x0a,  0x67,  0x01,  0xa3,  0x02,  0x0a,  0x9d,  0x01,  0x18,  0xaa,  0xfe,  0x80,  0xe7,  0x1a,
14497   0x09,  0x1a,  0x5d,  0xfe,  0x45,  0x58,  0x01,  0xfe,  0xb2,  0x16,  0xaa,  0x02,  0x0a,  0x5a,  0x01,  0x18,
14498   0xaa,  0x0a,  0x67,  0x01,  0xa3,  0x02,  0x0a,  0x5a,  0x01,  0x18,  0x01,  0xfe,  0x7e,  0x1e,  0xfe,  0x80,
14499   0x4c,  0xfe,  0x49,  0xe4,  0x1a,  0xfe,  0x12,  0x13,  0x0a,  0x9d,  0x01,  0x18,  0xfe,  0x80,  0x4c,  0x0a,
14500   0x67,  0x01,  0x5c,  0x02,  0x1c,  0x1a,  0x87,  0x7c,  0xe5,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,
14501   0x24,  0x1c,  0xfe,  0x1d,  0xf7,  0x28,  0xb1,  0xfe,  0x04,  0x1b,  0x01,  0xfe,  0x2a,  0x1c,  0xfa,  0xb3,
14502   0x28,  0x7c,  0xfe,  0x2c,  0x01,  0xfe,  0x2f,  0x19,  0x02,  0xc9,  0x2b,  0xfe,  0xf4,  0x1a,  0xfe,  0xfa,
14503   0x10,  0x1c,  0x1a,  0x87,  0x03,  0xfe,  0x64,  0x01,  0xfe,  0x00,  0xf4,  0x24,  0xfe,  0x18,  0x58,  0x03,
14504   0xfe,  0x66,  0x01,  0xfe,  0x19,  0x58,  0xb3,  0x24,  0x01,  0xfe,  0x0e,  0x1f,  0xfe,  0x30,  0xf4,  0x07,
14505   0xfe,  0x3c,  0x50,  0x7c,  0xfe,  0x38,  0x00,  0xfe,  0x0f,  0x79,  0xfe,  0x1c,  0xf7,  0x24,  0xb1,  0xfe,
14506   0x50,  0x1b,  0xfe,  0xd4,  0x14,  0x31,  0x02,  0xc9,  0x2b,  0xfe,  0x26,  0x1b,  0xfe,  0xba,  0x10,  0x1c,
14507   0x1a,  0x87,  0xfe,  0x83,  0x5a,  0xfe,  0x18,  0xdf,  0xfe,  0x19,  0xde,  0xfe,  0x1d,  0xf7,  0x54,  0xb1,
14508   0xfe,  0x72,  0x1b,  0xfe,  0xb2,  0x14,  0xfc,  0xb3,  0x54,  0x7c,  0x12,  0xfe,  0xaf,  0x19,  0xfe,  0x98,
14509   0xe7,  0x00,  0x02,  0xc9,  0x2b,  0xfe,  0x66,  0x1b,  0xfe,  0x8a,  0x10,  0x1c,  0x1a,  0x87,  0x8b,  0x0f,
14510   0xfe,  0x30,  0x90,  0x04,  0xfe,  0xb0,  0x93,  0x3a,  0x0b,  0xfe,  0x18,  0x58,  0xfe,  0x32,  0x90,  0x04,
14511   0xfe,  0xb2,  0x93,  0x3a,  0x0b,  0xfe,  0x19,  0x58,  0x0e,  0xa8,  0xb3,  0x4a,  0x7c,  0x12,  0xfe,  0x0f,
14512   0x79,  0xfe,  0x1c,  0xf7,  0x4a,  0xb1,  0xfe,  0xc6,  0x1b,  0xfe,  0x5e,  0x14,  0x31,  0x02,  0xc9,  0x2b,
14513   0xfe,  0x96,  0x1b,  0x5c,  0xfe,  0x02,  0xf6,  0x1a,  0x87,  0xfe,  0x18,  0xfe,  0x6a,  0xfe,  0x19,  0xfe,
14514   0x6b,  0x01,  0xfe,  0x1e,  0x1f,  0xfe,  0x1d,  0xf7,  0x65,  0xb1,  0xfe,  0xee,  0x1b,  0xfe,  0x36,  0x14,
14515   0xfe,  0x1c,  0x13,  0xb3,  0x65,  0x3e,  0xfe,  0x83,  0x58,  0xfe,  0xaf,  0x19,  0xfe,  0x80,  0xe7,  0x1a,
14516   0xfe,  0x81,  0xe7,  0x1a,  0x15,  0xfe,  0xdd,  0x00,  0x7a,  0x30,  0x02,  0x7a,  0x30,  0xfe,  0x12,  0x45,
14517   0x2b,  0xfe,  0xdc,  0x1b,  0x1f,  0x07,  0x47,  0xb5,  0xc3,  0x05,  0x35,  0xfe,  0x39,  0xf0,  0x75,  0x26,
14518   0x02,  0xfe,  0x7e,  0x18,  0x23,  0x1d,  0x36,  0x13,  0x11,  0x02,  0x87,  0x03,  0xe3,  0x23,  0x07,  0xfe,
14519   0xef,  0x12,  0xfe,  0xe1,  0x10,  0x90,  0x34,  0x60,  0xfe,  0x02,  0x80,  0x09,  0x56,  0xfe,  0x3c,  0x13,
14520   0xfe,  0x82,  0x14,  0xfe,  0x42,  0x13,  0x51,  0xfe,  0x06,  0x83,  0x0a,  0x5a,  0x01,  0x18,  0xcb,  0xfe,
14521   0x3e,  0x12,  0xfe,  0x41,  0x48,  0xfe,  0x45,  0x48,  0x01,  0xfe,  0xb2,  0x16,  0xfe,  0x00,  0xcc,  0xcb,
14522   0xfe,  0xf3,  0x13,  0x3f,  0x89,  0x09,  0x1a,  0xa5,  0x0a,  0x9d,  0x01,  0x18,  0xfe,  0x80,  0x4c,  0x01,
14523   0x85,  0xfe,  0x16,  0x10,  0x09,  0x9b,  0x4e,  0xfe,  0x40,  0x14,  0xfe,  0x24,  0x12,  0xfe,  0x14,  0x56,
14524   0xfe,  0xd6,  0xf0,  0xfe,  0x52,  0x1c,  0x1c,  0x0d,  0x02,  0xfe,  0x9c,  0xe7,  0x0d,  0x19,  0xfe,  0x15,
14525   0x00,  0x40,  0x8d,  0x30,  0x01,  0xf4,  0x1c,  0x07,  0x02,  0x51,  0xfe,  0x06,  0x83,  0xfe,  0x18,  0x80,
14526   0x61,  0x28,  0x44,  0x15,  0x56,  0x01,  0x85,  0x1c,  0x07,  0x02,  0xfe,  0x38,  0x90,  0xfe,  0xba,  0x90,
14527   0x91,  0xde,  0x7e,  0xdf,  0xfe,  0x48,  0x55,  0x31,  0xfe,  0xc9,  0x55,  0x02,  0x21,  0xb9,  0x88,  0x20,
14528   0xb9,  0x02,  0x0a,  0xba,  0x01,  0x18,  0xfe,  0x41,  0x48,  0x0a,  0x57,  0x01,  0x18,  0xfe,  0x49,  0x44,
14529   0x1b,  0xfe,  0x1e,  0x1d,  0x88,  0x89,  0x02,  0x0a,  0x5a,  0x01,  0x18,  0x09,  0x1a,  0xa4,  0x0a,  0x67,
14530   0x01,  0xa3,  0x0a,  0x57,  0x01,  0x18,  0x88,  0x89,  0x02,  0xfe,  0x4e,  0xe4,  0x1d,  0x7b,  0xfe,  0x52,
14531   0x1d,  0x03,  0xfe,  0x90,  0x00,  0xfe,  0x3a,  0x45,  0xfe,  0x2c,  0x10,  0xfe,  0x4e,  0xe4,  0xdd,  0x7b,
14532   0xfe,  0x64,  0x1d,  0x03,  0xfe,  0x92,  0x00,  0xd1,  0x12,  0xfe,  0x1a,  0x10,  0xfe,  0x4e,  0xe4,  0xfe,
14533   0x0b,  0x00,  0x7b,  0xfe,  0x76,  0x1d,  0x03,  0xfe,  0x94,  0x00,  0xd1,  0x24,  0xfe,  0x08,  0x10,  0x03,
14534   0xfe,  0x96,  0x00,  0xd1,  0x63,  0xfe,  0x4e,  0x45,  0x83,  0xca,  0xff,  0x04,  0x68,  0x54,  0xfe,  0xf1,
14535   0x10,  0x23,  0x49,  0xfe,  0x08,  0x1c,  0xfe,  0x67,  0x19,  0xfe,  0x0a,  0x1c,  0xfe,  0x1a,  0xf4,  0xfe,
14536   0x00,  0x04,  0x83,  0xb2,  0x1d,  0x48,  0xfe,  0xaa,  0x1d,  0x13,  0x1d,  0x02,  0x09,  0x92,  0xfe,  0x5a,
14537   0xf0,  0xfe,  0xba,  0x1d,  0x2e,  0x93,  0xfe,  0x34,  0x10,  0x09,  0x12,  0xfe,  0x5a,  0xf0,  0xfe,  0xc8,
14538   0x1d,  0x2e,  0xb4,  0xfe,  0x26,  0x10,  0x09,  0x1d,  0x36,  0x2e,  0x63,  0xfe,  0x1a,  0x10,  0x09,  0x0d,
14539   0x36,  0x2e,  0x94,  0xf2,  0x09,  0x07,  0x36,  0x2e,  0x95,  0xa1,  0xc8,  0x02,  0x1f,  0x93,  0x01,  0x42,
14540   0xfe,  0x04,  0xfe,  0x99,  0x03,  0x9c,  0x8b,  0x02,  0x2a,  0xfe,  0x1c,  0x1e,  0xfe,  0x14,  0xf0,  0x08,
14541   0x2f,  0xfe,  0x0c,  0x1e,  0x2a,  0xfe,  0x1c,  0x1e,  0x8f,  0xfe,  0x1c,  0x1e,  0xfe,  0x82,  0xf0,  0xfe,
14542   0x10,  0x1e,  0x02,  0x0f,  0x3f,  0x04,  0xfe,  0x80,  0x83,  0x33,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x18,
14543   0x80,  0x04,  0xfe,  0x98,  0x83,  0x33,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x02,  0x80,  0x04,  0xfe,  0x82,
14544   0x83,  0x33,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x06,  0x80,  0x04,  0xfe,  0x86,  0x83,  0x33,  0x0b,  0x0e,
14545   0x02,  0x0f,  0xfe,  0x1b,  0x80,  0x04,  0xfe,  0x9b,  0x83,  0x33,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x04,
14546   0x80,  0x04,  0xfe,  0x84,  0x83,  0x33,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x80,  0x80,  0x04,  0xfe,  0x80,
14547   0x83,  0xfe,  0xc9,  0x47,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x19,  0x81,  0x04,  0xfe,  0x99,  0x83,  0xfe,
14548   0xca,  0x47,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x06,  0x83,  0x04,  0xfe,  0x86,  0x83,  0xfe,  0xce,  0x47,
14549   0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x2c,  0x90,  0x04,  0xfe,  0xac,  0x93,  0x3a,  0x0b,  0x0e,  0x02,  0x0f,
14550   0xfe,  0xae,  0x90,  0x04,  0xfe,  0xae,  0x93,  0x79,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x08,  0x90,  0x04,
14551   0xfe,  0x88,  0x93,  0x3a,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x8a,  0x90,  0x04,  0xfe,  0x8a,  0x93,  0x79,
14552   0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x0c,  0x90,  0x04,  0xfe,  0x8c,  0x93,  0x3a,  0x0b,  0x0e,  0x02,  0x0f,
14553   0xfe,  0x8e,  0x90,  0x04,  0xfe,  0x8e,  0x93,  0x79,  0x0b,  0x0e,  0x02,  0x0f,  0xfe,  0x3c,  0x90,  0x04,
14554   0xfe,  0xbc,  0x93,  0x3a,  0x0b,  0x0e,  0x02,  0x8b,  0x0f,  0xfe,  0x03,  0x80,  0x04,  0xfe,  0x83,  0x83,
14555   0x33,  0x0b,  0x77,  0x0e,  0xa8,  0x02,  0xff,  0x66,  0x00,  0x00,
14556 };
14557 
14558 STATIC unsigned short _adv_asc38C1600_size =
14559         sizeof(_adv_asc38C1600_buf); /* 0x1673 */
14560 STATIC ADV_DCNT _adv_asc38C1600_chksum =
14561         0x0604EF77UL; /* Expanded little-endian checksum. */
14562 
14563 /* a_init.c */
14564 /*
14565  * EEPROM Configuration.
14566  *
14567  * All drivers should use this structure to set the default EEPROM
14568  * configuration. The BIOS now uses this structure when it is built.
14569  * Additional structure information can be found in a_condor.h where
14570  * the structure is defined.
14571  *
14572  * The *_Field_IsChar structs are needed to correct for endianness.
14573  * These values are read from the board 16 bits at a time directly
14574  * into the structs. Because some fields are char, the values will be
14575  * in the wrong order. The *_Field_IsChar tells when to flip the
14576  * bytes. Data read and written to PCI memory is automatically swapped
14577  * on big-endian platforms so char fields read as words are actually being
14578  * unswapped on big-endian platforms.
14579  */
14580 STATIC ADVEEP_3550_CONFIG
14581 Default_3550_EEPROM_Config ASC_INITDATA = {
14582     ADV_EEPROM_BIOS_ENABLE,     /* cfg_lsw */
14583     0x0000,                     /* cfg_msw */
14584     0xFFFF,                     /* disc_enable */
14585     0xFFFF,                     /* wdtr_able */
14586     0xFFFF,                     /* sdtr_able */
14587     0xFFFF,                     /* start_motor */
14588     0xFFFF,                     /* tagqng_able */
14589     0xFFFF,                     /* bios_scan */
14590     0,                          /* scam_tolerant */
14591     7,                          /* adapter_scsi_id */
14592     0,                          /* bios_boot_delay */
14593     3,                          /* scsi_reset_delay */
14594     0,                          /* bios_id_lun */
14595     0,                          /* termination */
14596     0,                          /* reserved1 */
14597     0xFFE7,                     /* bios_ctrl */
14598     0xFFFF,                     /* ultra_able */
14599     0,                          /* reserved2 */
14600     ASC_DEF_MAX_HOST_QNG,       /* max_host_qng */
14601     ASC_DEF_MAX_DVC_QNG,        /* max_dvc_qng */
14602     0,                          /* dvc_cntl */
14603     0,                          /* bug_fix */
14604     0,                          /* serial_number_word1 */
14605     0,                          /* serial_number_word2 */
14606     0,                          /* serial_number_word3 */
14607     0,                          /* check_sum */
14608     { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* oem_name[16] */
14609     0,                          /* dvc_err_code */
14610     0,                          /* adv_err_code */
14611     0,                          /* adv_err_addr */
14612     0,                          /* saved_dvc_err_code */
14613     0,                          /* saved_adv_err_code */
14614     0,                          /* saved_adv_err_addr */
14615     0                           /* num_of_err */
14616 };
14617 
14618 STATIC ADVEEP_3550_CONFIG
14619 ADVEEP_3550_Config_Field_IsChar ASC_INITDATA = {
14620     0,                          /* cfg_lsw */
14621     0,                          /* cfg_msw */
14622     0,                          /* -disc_enable */
14623     0,                          /* wdtr_able */
14624     0,                          /* sdtr_able */
14625     0,                          /* start_motor */
14626     0,                          /* tagqng_able */
14627     0,                          /* bios_scan */
14628     0,                          /* scam_tolerant */
14629     1,                          /* adapter_scsi_id */
14630     1,                          /* bios_boot_delay */
14631     1,                          /* scsi_reset_delay */
14632     1,                          /* bios_id_lun */
14633     1,                          /* termination */
14634     1,                          /* reserved1 */
14635     0,                          /* bios_ctrl */
14636     0,                          /* ultra_able */
14637     0,                          /* reserved2 */
14638     1,                          /* max_host_qng */
14639     1,                          /* max_dvc_qng */
14640     0,                          /* dvc_cntl */
14641     0,                          /* bug_fix */
14642     0,                          /* serial_number_word1 */
14643     0,                          /* serial_number_word2 */
14644     0,                          /* serial_number_word3 */
14645     0,                          /* check_sum */
14646     { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* oem_name[16] */
14647     0,                          /* dvc_err_code */
14648     0,                          /* adv_err_code */
14649     0,                          /* adv_err_addr */
14650     0,                          /* saved_dvc_err_code */
14651     0,                          /* saved_adv_err_code */
14652     0,                          /* saved_adv_err_addr */
14653     0                           /* num_of_err */
14654 };
14655 
14656 STATIC ADVEEP_38C0800_CONFIG
14657 Default_38C0800_EEPROM_Config ASC_INITDATA = {
14658     ADV_EEPROM_BIOS_ENABLE,     /* 00 cfg_lsw */
14659     0x0000,                     /* 01 cfg_msw */
14660     0xFFFF,                     /* 02 disc_enable */
14661     0xFFFF,                     /* 03 wdtr_able */
14662     0x4444,                     /* 04 sdtr_speed1 */
14663     0xFFFF,                     /* 05 start_motor */
14664     0xFFFF,                     /* 06 tagqng_able */
14665     0xFFFF,                     /* 07 bios_scan */
14666     0,                          /* 08 scam_tolerant */
14667     7,                          /* 09 adapter_scsi_id */
14668     0,                          /*    bios_boot_delay */
14669     3,                          /* 10 scsi_reset_delay */
14670     0,                          /*    bios_id_lun */
14671     0,                          /* 11 termination_se */
14672     0,                          /*    termination_lvd */
14673     0xFFE7,                     /* 12 bios_ctrl */
14674     0x4444,                     /* 13 sdtr_speed2 */
14675     0x4444,                     /* 14 sdtr_speed3 */
14676     ASC_DEF_MAX_HOST_QNG,       /* 15 max_host_qng */
14677     ASC_DEF_MAX_DVC_QNG,        /*    max_dvc_qng */
14678     0,                          /* 16 dvc_cntl */
14679     0x4444,                     /* 17 sdtr_speed4 */
14680     0,                          /* 18 serial_number_word1 */
14681     0,                          /* 19 serial_number_word2 */
14682     0,                          /* 20 serial_number_word3 */
14683     0,                          /* 21 check_sum */
14684     { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */
14685     0,                          /* 30 dvc_err_code */
14686     0,                          /* 31 adv_err_code */
14687     0,                          /* 32 adv_err_addr */
14688     0,                          /* 33 saved_dvc_err_code */
14689     0,                          /* 34 saved_adv_err_code */
14690     0,                          /* 35 saved_adv_err_addr */
14691     0,                          /* 36 reserved */
14692     0,                          /* 37 reserved */
14693     0,                          /* 38 reserved */
14694     0,                          /* 39 reserved */
14695     0,                          /* 40 reserved */
14696     0,                          /* 41 reserved */
14697     0,                          /* 42 reserved */
14698     0,                          /* 43 reserved */
14699     0,                          /* 44 reserved */
14700     0,                          /* 45 reserved */
14701     0,                          /* 46 reserved */
14702     0,                          /* 47 reserved */
14703     0,                          /* 48 reserved */
14704     0,                          /* 49 reserved */
14705     0,                          /* 50 reserved */
14706     0,                          /* 51 reserved */
14707     0,                          /* 52 reserved */
14708     0,                          /* 53 reserved */
14709     0,                          /* 54 reserved */
14710     0,                          /* 55 reserved */
14711     0,                          /* 56 cisptr_lsw */
14712     0,                          /* 57 cisprt_msw */
14713     ADV_PCI_VENDOR_ID,          /* 58 subsysvid */
14714     ADV_PCI_DEVID_38C0800_REV1, /* 59 subsysid */
14715     0,                          /* 60 reserved */
14716     0,                          /* 61 reserved */
14717     0,                          /* 62 reserved */
14718     0                           /* 63 reserved */
14719 };
14720 
14721 STATIC ADVEEP_38C0800_CONFIG
14722 ADVEEP_38C0800_Config_Field_IsChar ASC_INITDATA = {
14723     0,                          /* 00 cfg_lsw */
14724     0,                          /* 01 cfg_msw */
14725     0,                          /* 02 disc_enable */
14726     0,                          /* 03 wdtr_able */
14727     0,                          /* 04 sdtr_speed1 */
14728     0,                          /* 05 start_motor */
14729     0,                          /* 06 tagqng_able */
14730     0,                          /* 07 bios_scan */
14731     0,                          /* 08 scam_tolerant */
14732     1,                          /* 09 adapter_scsi_id */
14733     1,                          /*    bios_boot_delay */
14734     1,                          /* 10 scsi_reset_delay */
14735     1,                          /*    bios_id_lun */
14736     1,                          /* 11 termination_se */
14737     1,                          /*    termination_lvd */
14738     0,                          /* 12 bios_ctrl */
14739     0,                          /* 13 sdtr_speed2 */
14740     0,                          /* 14 sdtr_speed3 */
14741     1,                          /* 15 max_host_qng */
14742     1,                          /*    max_dvc_qng */
14743     0,                          /* 16 dvc_cntl */
14744     0,                          /* 17 sdtr_speed4 */
14745     0,                          /* 18 serial_number_word1 */
14746     0,                          /* 19 serial_number_word2 */
14747     0,                          /* 20 serial_number_word3 */
14748     0,                          /* 21 check_sum */
14749     { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* 22-29 oem_name[16] */
14750     0,                          /* 30 dvc_err_code */
14751     0,                          /* 31 adv_err_code */
14752     0,                          /* 32 adv_err_addr */
14753     0,                          /* 33 saved_dvc_err_code */
14754     0,                          /* 34 saved_adv_err_code */
14755     0,                          /* 35 saved_adv_err_addr */
14756     0,                          /* 36 reserved */
14757     0,                          /* 37 reserved */
14758     0,                          /* 38 reserved */
14759     0,                          /* 39 reserved */
14760     0,                          /* 40 reserved */
14761     0,                          /* 41 reserved */
14762     0,                          /* 42 reserved */
14763     0,                          /* 43 reserved */
14764     0,                          /* 44 reserved */
14765     0,                          /* 45 reserved */
14766     0,                          /* 46 reserved */
14767     0,                          /* 47 reserved */
14768     0,                          /* 48 reserved */
14769     0,                          /* 49 reserved */
14770     0,                          /* 50 reserved */
14771     0,                          /* 51 reserved */
14772     0,                          /* 52 reserved */
14773     0,                          /* 53 reserved */
14774     0,                          /* 54 reserved */
14775     0,                          /* 55 reserved */
14776     0,                          /* 56 cisptr_lsw */
14777     0,                          /* 57 cisprt_msw */
14778     0,                          /* 58 subsysvid */
14779     0,                          /* 59 subsysid */
14780     0,                          /* 60 reserved */
14781     0,                          /* 61 reserved */
14782     0,                          /* 62 reserved */
14783     0                           /* 63 reserved */
14784 };
14785 
14786 STATIC ADVEEP_38C1600_CONFIG
14787 Default_38C1600_EEPROM_Config ASC_INITDATA = {
14788     ADV_EEPROM_BIOS_ENABLE,     /* 00 cfg_lsw */
14789     0x0000,                     /* 01 cfg_msw */
14790     0xFFFF,                     /* 02 disc_enable */
14791     0xFFFF,                     /* 03 wdtr_able */
14792     0x5555,                     /* 04 sdtr_speed1 */
14793     0xFFFF,                     /* 05 start_motor */
14794     0xFFFF,                     /* 06 tagqng_able */
14795     0xFFFF,                     /* 07 bios_scan */
14796     0,                          /* 08 scam_tolerant */
14797     7,                          /* 09 adapter_scsi_id */
14798     0,                          /*    bios_boot_delay */
14799     3,                          /* 10 scsi_reset_delay */
14800     0,                          /*    bios_id_lun */
14801     0,                          /* 11 termination_se */
14802     0,                          /*    termination_lvd */
14803     0xFFE7,                     /* 12 bios_ctrl */
14804     0x5555,                     /* 13 sdtr_speed2 */
14805     0x5555,                     /* 14 sdtr_speed3 */
14806     ASC_DEF_MAX_HOST_QNG,       /* 15 max_host_qng */
14807     ASC_DEF_MAX_DVC_QNG,        /*    max_dvc_qng */
14808     0,                          /* 16 dvc_cntl */
14809     0x5555,                     /* 17 sdtr_speed4 */
14810     0,                          /* 18 serial_number_word1 */
14811     0,                          /* 19 serial_number_word2 */
14812     0,                          /* 20 serial_number_word3 */
14813     0,                          /* 21 check_sum */
14814     { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */
14815     0,                          /* 30 dvc_err_code */
14816     0,                          /* 31 adv_err_code */
14817     0,                          /* 32 adv_err_addr */
14818     0,                          /* 33 saved_dvc_err_code */
14819     0,                          /* 34 saved_adv_err_code */
14820     0,                          /* 35 saved_adv_err_addr */
14821     0,                          /* 36 reserved */
14822     0,                          /* 37 reserved */
14823     0,                          /* 38 reserved */
14824     0,                          /* 39 reserved */
14825     0,                          /* 40 reserved */
14826     0,                          /* 41 reserved */
14827     0,                          /* 42 reserved */
14828     0,                          /* 43 reserved */
14829     0,                          /* 44 reserved */
14830     0,                          /* 45 reserved */
14831     0,                          /* 46 reserved */
14832     0,                          /* 47 reserved */
14833     0,                          /* 48 reserved */
14834     0,                          /* 49 reserved */
14835     0,                          /* 50 reserved */
14836     0,                          /* 51 reserved */
14837     0,                          /* 52 reserved */
14838     0,                          /* 53 reserved */
14839     0,                          /* 54 reserved */
14840     0,                          /* 55 reserved */
14841     0,                          /* 56 cisptr_lsw */
14842     0,                          /* 57 cisprt_msw */
14843     ADV_PCI_VENDOR_ID,          /* 58 subsysvid */
14844     ADV_PCI_DEVID_38C1600_REV1, /* 59 subsysid */
14845     0,                          /* 60 reserved */
14846     0,                          /* 61 reserved */
14847     0,                          /* 62 reserved */
14848     0                           /* 63 reserved */
14849 };
14850 
14851 STATIC ADVEEP_38C1600_CONFIG
14852 ADVEEP_38C1600_Config_Field_IsChar ASC_INITDATA = {
14853     0,                          /* 00 cfg_lsw */
14854     0,                          /* 01 cfg_msw */
14855     0,                          /* 02 disc_enable */
14856     0,                          /* 03 wdtr_able */
14857     0,                          /* 04 sdtr_speed1 */
14858     0,                          /* 05 start_motor */
14859     0,                          /* 06 tagqng_able */
14860     0,                          /* 07 bios_scan */
14861     0,                          /* 08 scam_tolerant */
14862     1,                          /* 09 adapter_scsi_id */
14863     1,                          /*    bios_boot_delay */
14864     1,                          /* 10 scsi_reset_delay */
14865     1,                          /*    bios_id_lun */
14866     1,                          /* 11 termination_se */
14867     1,                          /*    termination_lvd */
14868     0,                          /* 12 bios_ctrl */
14869     0,                          /* 13 sdtr_speed2 */
14870     0,                          /* 14 sdtr_speed3 */
14871     1,                          /* 15 max_host_qng */
14872     1,                          /*    max_dvc_qng */
14873     0,                          /* 16 dvc_cntl */
14874     0,                          /* 17 sdtr_speed4 */
14875     0,                          /* 18 serial_number_word1 */
14876     0,                          /* 19 serial_number_word2 */
14877     0,                          /* 20 serial_number_word3 */
14878     0,                          /* 21 check_sum */
14879     { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* 22-29 oem_name[16] */
14880     0,                          /* 30 dvc_err_code */
14881     0,                          /* 31 adv_err_code */
14882     0,                          /* 32 adv_err_addr */
14883     0,                          /* 33 saved_dvc_err_code */
14884     0,                          /* 34 saved_adv_err_code */
14885     0,                          /* 35 saved_adv_err_addr */
14886     0,                          /* 36 reserved */
14887     0,                          /* 37 reserved */
14888     0,                          /* 38 reserved */
14889     0,                          /* 39 reserved */
14890     0,                          /* 40 reserved */
14891     0,                          /* 41 reserved */
14892     0,                          /* 42 reserved */
14893     0,                          /* 43 reserved */
14894     0,                          /* 44 reserved */
14895     0,                          /* 45 reserved */
14896     0,                          /* 46 reserved */
14897     0,                          /* 47 reserved */
14898     0,                          /* 48 reserved */
14899     0,                          /* 49 reserved */
14900     0,                          /* 50 reserved */
14901     0,                          /* 51 reserved */
14902     0,                          /* 52 reserved */
14903     0,                          /* 53 reserved */
14904     0,                          /* 54 reserved */
14905     0,                          /* 55 reserved */
14906     0,                          /* 56 cisptr_lsw */
14907     0,                          /* 57 cisprt_msw */
14908     0,                          /* 58 subsysvid */
14909     0,                          /* 59 subsysid */
14910     0,                          /* 60 reserved */
14911     0,                          /* 61 reserved */
14912     0,                          /* 62 reserved */
14913     0                           /* 63 reserved */
14914 };
14915 
14916 /*
14917  * Initialize the ADV_DVC_VAR structure.
14918  *
14919  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14920  *
14921  * For a non-fatal error return a warning code. If there are no warnings
14922  * then 0 is returned.
14923  */
ASC_INITFUNC(STATIC int,AdvInitGetConfig (ADV_DVC_VAR * asc_dvc))14924 ASC_INITFUNC(
14925 STATIC int,
14926 AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
14927 )
14928 {
14929     ushort      warn_code;
14930     AdvPortAddr iop_base;
14931     uchar       pci_cmd_reg;
14932     int         status;
14933 
14934     warn_code = 0;
14935     asc_dvc->err_code = 0;
14936     iop_base = asc_dvc->iop_base;
14937 
14938     /*
14939      * PCI Command Register
14940      *
14941      * Note: AscPCICmdRegBits_BusMastering definition (0x0007) includes
14942      * I/O Space Control, Memory Space Control and Bus Master Control bits.
14943      */
14944 
14945     if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
14946                             AscPCIConfigCommandRegister))
14947          & AscPCICmdRegBits_BusMastering)
14948         != AscPCICmdRegBits_BusMastering)
14949     {
14950         pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
14951 
14952         DvcAdvWritePCIConfigByte(asc_dvc,
14953                 AscPCIConfigCommandRegister, pci_cmd_reg);
14954 
14955         if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister))
14956              & AscPCICmdRegBits_BusMastering)
14957             != AscPCICmdRegBits_BusMastering)
14958         {
14959             warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14960         }
14961     }
14962 
14963     /*
14964      * PCI Latency Timer
14965      *
14966      * If the "latency timer" register is 0x20 or above, then we don't need
14967      * to change it.  Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
14968      * comes up less than 0x20).
14969      */
14970     if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
14971         DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer, 0x20);
14972         if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20)
14973         {
14974             warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14975         }
14976     }
14977 
14978     /*
14979      * Save the state of the PCI Configuration Command Register
14980      * "Parity Error Response Control" Bit. If the bit is clear (0),
14981      * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
14982      * DMA parity errors.
14983      */
14984     asc_dvc->cfg->control_flag = 0;
14985     if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
14986          & AscPCICmdRegBits_ParErrRespCtrl)) == 0)
14987     {
14988         asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
14989     }
14990 
14991     asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
14992       ADV_LIB_VERSION_MINOR;
14993     asc_dvc->cfg->chip_version =
14994       AdvGetChipVersion(iop_base, asc_dvc->bus_type);
14995 
14996     ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
14997         (ushort) AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
14998         (ushort) ADV_CHIP_ID_BYTE);
14999 
15000     ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
15001         (ushort) AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
15002         (ushort) ADV_CHIP_ID_WORD);
15003 
15004     /*
15005      * Reset the chip to start and allow register writes.
15006      */
15007     if (AdvFindSignature(iop_base) == 0)
15008     {
15009         asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
15010         return ADV_ERROR;
15011     }
15012     else {
15013         /*
15014          * The caller must set 'chip_type' to a valid setting.
15015          */
15016         if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
15017             asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
15018             asc_dvc->chip_type != ADV_CHIP_ASC38C1600)
15019         {
15020             asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
15021             return ADV_ERROR;
15022         }
15023 
15024         /*
15025          * Reset Chip.
15026          */
15027         AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
15028             ADV_CTRL_REG_CMD_RESET);
15029         DvcSleepMilliSecond(100);
15030         AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
15031             ADV_CTRL_REG_CMD_WR_IO_REG);
15032 
15033         if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
15034         {
15035             if ((status = AdvInitFrom38C1600EEP(asc_dvc)) == ADV_ERROR)
15036             {
15037                 return ADV_ERROR;
15038             }
15039         } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
15040         {
15041             if ((status = AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR)
15042             {
15043                 return ADV_ERROR;
15044             }
15045         } else
15046         {
15047             if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR)
15048             {
15049                 return ADV_ERROR;
15050             }
15051         }
15052         warn_code |= status;
15053     }
15054 
15055     return warn_code;
15056 }
15057 
15058 /*
15059  * Initialize the ASC-3550.
15060  *
15061  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15062  *
15063  * For a non-fatal error return a warning code. If there are no warnings
15064  * then 0 is returned.
15065  *
15066  * Needed after initialization for error recovery.
15067  */
15068 STATIC int
AdvInitAsc3550Driver(ADV_DVC_VAR * asc_dvc)15069 AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
15070 {
15071     AdvPortAddr iop_base;
15072     ushort      warn_code;
15073     ADV_DCNT    sum;
15074     int         begin_addr;
15075     int         end_addr;
15076     ushort      code_sum;
15077     int         word;
15078     int         j;
15079     int         adv_asc3550_expanded_size;
15080     ADV_CARR_T  *carrp;
15081     ADV_DCNT    contig_len;
15082     ADV_SDCNT   buf_size;
15083     ADV_PADDR   carr_paddr;
15084     int         i;
15085     ushort      scsi_cfg1;
15086     uchar       tid;
15087     ushort      bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
15088     ushort      wdtr_able = 0, sdtr_able, tagqng_able;
15089     uchar       max_cmd[ADV_MAX_TID + 1];
15090 
15091     /* If there is already an error, don't continue. */
15092     if (asc_dvc->err_code != 0)
15093     {
15094         return ADV_ERROR;
15095     }
15096 
15097     /*
15098      * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
15099      */
15100     if (asc_dvc->chip_type != ADV_CHIP_ASC3550)
15101     {
15102         asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
15103         return ADV_ERROR;
15104     }
15105 
15106     warn_code = 0;
15107     iop_base = asc_dvc->iop_base;
15108 
15109     /*
15110      * Save the RISC memory BIOS region before writing the microcode.
15111      * The BIOS may already be loaded and using its RISC LRAM region
15112      * so its region must be saved and restored.
15113      *
15114      * Note: This code makes the assumption, which is currently true,
15115      * that a chip reset does not clear RISC LRAM.
15116      */
15117     for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15118     {
15119         AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15120     }
15121 
15122     /*
15123      * Save current per TID negotiated values.
15124      */
15125     if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
15126     {
15127         ushort  bios_version, major, minor;
15128 
15129         bios_version = bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM)/2];
15130         major = (bios_version  >> 12) & 0xF;
15131         minor = (bios_version  >> 8) & 0xF;
15132         if (major < 3 || (major == 3 && minor == 1))
15133         {
15134             /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
15135             AdvReadWordLram(iop_base, 0x120, wdtr_able);
15136         } else
15137         {
15138             AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15139         }
15140     }
15141     AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15142     AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15143     for (tid = 0; tid <= ADV_MAX_TID; tid++)
15144     {
15145         AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15146             max_cmd[tid]);
15147     }
15148 
15149     /*
15150      * Load the Microcode
15151      *
15152      * Write the microcode image to RISC memory starting at address 0.
15153      */
15154     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15155     /* Assume the following compressed format of the microcode buffer:
15156      *
15157      *  254 word (508 byte) table indexed by byte code followed
15158      *  by the following byte codes:
15159      *
15160      *    1-Byte Code:
15161      *      00: Emit word 0 in table.
15162      *      01: Emit word 1 in table.
15163      *      .
15164      *      FD: Emit word 253 in table.
15165      *
15166      *    Multi-Byte Code:
15167      *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15168      *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15169      */
15170     word = 0;
15171     for (i = 253 * 2; i < _adv_asc3550_size; i++)
15172     {
15173         if (_adv_asc3550_buf[i] == 0xff)
15174         {
15175             for (j = 0; j < _adv_asc3550_buf[i + 1]; j++)
15176             {
15177                 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15178                     _adv_asc3550_buf[i + 3] << 8) |
15179                 _adv_asc3550_buf[i + 2]));
15180                 word++;
15181             }
15182             i += 3;
15183         } else if (_adv_asc3550_buf[i] == 0xfe)
15184         {
15185             AdvWriteWordAutoIncLram(iop_base, (((ushort)
15186                 _adv_asc3550_buf[i + 2] << 8) |
15187                 _adv_asc3550_buf[i + 1]));
15188             i += 2;
15189             word++;
15190         } else
15191         {
15192             AdvWriteWordAutoIncLram(iop_base, (((ushort)
15193                 _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) |
15194                 _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
15195             word++;
15196         }
15197     }
15198 
15199     /*
15200      * Set 'word' for later use to clear the rest of memory and save
15201      * the expanded mcode size.
15202      */
15203     word *= 2;
15204     adv_asc3550_expanded_size = word;
15205 
15206     /*
15207      * Clear the rest of ASC-3550 Internal RAM (8KB).
15208      */
15209     for (; word < ADV_3550_MEMSIZE; word += 2)
15210     {
15211         AdvWriteWordAutoIncLram(iop_base, 0);
15212     }
15213 
15214     /*
15215      * Verify the microcode checksum.
15216      */
15217     sum = 0;
15218     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15219 
15220     for (word = 0; word < adv_asc3550_expanded_size; word += 2)
15221     {
15222         sum += AdvReadWordAutoIncLram(iop_base);
15223     }
15224 
15225     if (sum != _adv_asc3550_chksum)
15226     {
15227         asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15228         return ADV_ERROR;
15229     }
15230 
15231     /*
15232      * Restore the RISC memory BIOS region.
15233      */
15234     for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15235     {
15236         AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15237     }
15238 
15239     /*
15240      * Calculate and write the microcode code checksum to the microcode
15241      * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15242      */
15243     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15244     AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15245     code_sum = 0;
15246     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15247     for (word = begin_addr; word < end_addr; word += 2)
15248     {
15249         code_sum += AdvReadWordAutoIncLram(iop_base);
15250     }
15251     AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15252 
15253     /*
15254      * Read and save microcode version and date.
15255      */
15256     AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
15257     AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
15258 
15259     /*
15260      * Set the chip type to indicate the ASC3550.
15261      */
15262     AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
15263 
15264     /*
15265      * If the PCI Configuration Command Register "Parity Error Response
15266      * Control" Bit was clear (0), then set the microcode variable
15267      * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15268      * to ignore DMA parity errors.
15269      */
15270     if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
15271     {
15272         AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15273         word |= CONTROL_FLAG_IGNORE_PERR;
15274         AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15275     }
15276 
15277     /*
15278      * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
15279      * threshold of 128 bytes. This register is only accessible to the host.
15280      */
15281     AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15282         START_CTL_EMFU | READ_CMD_MRM);
15283 
15284     /*
15285      * Microcode operating variables for WDTR, SDTR, and command tag
15286      * queuing will be set in AdvInquiryHandling() based on what a
15287      * device reports it is capable of in Inquiry byte 7.
15288      *
15289      * If SCSI Bus Resets have been disabled, then directly set
15290      * SDTR and WDTR from the EEPROM configuration. This will allow
15291      * the BIOS and warm boot to work without a SCSI bus hang on
15292      * the Inquiry caused by host and target mismatched DTR values.
15293      * Without the SCSI Bus Reset, before an Inquiry a device can't
15294      * be assumed to be in Asynchronous, Narrow mode.
15295      */
15296     if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
15297     {
15298         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
15299         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
15300     }
15301 
15302     /*
15303      * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
15304      * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
15305      * bitmask. These values determine the maximum SDTR speed negotiated
15306      * with a device.
15307      *
15308      * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15309      * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15310      * without determining here whether the device supports SDTR.
15311      *
15312      * 4-bit speed  SDTR speed name
15313      * ===========  ===============
15314      * 0000b (0x0)  SDTR disabled
15315      * 0001b (0x1)  5 Mhz
15316      * 0010b (0x2)  10 Mhz
15317      * 0011b (0x3)  20 Mhz (Ultra)
15318      * 0100b (0x4)  40 Mhz (LVD/Ultra2)
15319      * 0101b (0x5)  80 Mhz (LVD2/Ultra3)
15320      * 0110b (0x6)  Undefined
15321      * .
15322      * 1111b (0xF)  Undefined
15323      */
15324     word = 0;
15325     for (tid = 0; tid <= ADV_MAX_TID; tid++)
15326     {
15327         if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able)
15328         {
15329             /* Set Ultra speed for TID 'tid'. */
15330             word |= (0x3 << (4 * (tid % 4)));
15331         } else
15332         {
15333             /* Set Fast speed for TID 'tid'. */
15334             word |= (0x2 << (4 * (tid % 4)));
15335         }
15336         if (tid == 3) /* Check if done with sdtr_speed1. */
15337         {
15338             AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
15339             word = 0;
15340         } else if (tid == 7) /* Check if done with sdtr_speed2. */
15341         {
15342             AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
15343             word = 0;
15344         } else if (tid == 11) /* Check if done with sdtr_speed3. */
15345         {
15346             AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
15347             word = 0;
15348         } else if (tid == 15) /* Check if done with sdtr_speed4. */
15349         {
15350             AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
15351             /* End of loop. */
15352         }
15353     }
15354 
15355     /*
15356      * Set microcode operating variable for the disconnect per TID bitmask.
15357      */
15358     AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
15359 
15360     /*
15361      * Set SCSI_CFG0 Microcode Default Value.
15362      *
15363      * The microcode will set the SCSI_CFG0 register using this value
15364      * after it is started below.
15365      */
15366     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15367         PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15368         asc_dvc->chip_scsi_id);
15369 
15370     /*
15371      * Determine SCSI_CFG1 Microcode Default Value.
15372      *
15373      * The microcode will set the SCSI_CFG1 register using this value
15374      * after it is started below.
15375      */
15376 
15377     /* Read current SCSI_CFG1 Register value. */
15378     scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15379 
15380     /*
15381      * If all three connectors are in use, return an error.
15382      */
15383     if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
15384         (scsi_cfg1 & CABLE_ILLEGAL_B) == 0)
15385     {
15386             asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
15387             return ADV_ERROR;
15388     }
15389 
15390     /*
15391      * If the internal narrow cable is reversed all of the SCSI_CTRL
15392      * register signals will be set. Check for and return an error if
15393      * this condition is found.
15394      */
15395     if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
15396     {
15397         asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15398         return ADV_ERROR;
15399     }
15400 
15401     /*
15402      * If this is a differential board and a single-ended device
15403      * is attached to one of the connectors, return an error.
15404      */
15405     if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0)
15406     {
15407         asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
15408         return ADV_ERROR;
15409     }
15410 
15411     /*
15412      * If automatic termination control is enabled, then set the
15413      * termination value based on a table listed in a_condor.h.
15414      *
15415      * If manual termination was specified with an EEPROM setting
15416      * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
15417      * is ready to be 'ored' into SCSI_CFG1.
15418      */
15419     if (asc_dvc->cfg->termination == 0)
15420     {
15421         /*
15422          * The software always controls termination by setting TERM_CTL_SEL.
15423          * If TERM_CTL_SEL were set to 0, the hardware would set termination.
15424          */
15425         asc_dvc->cfg->termination |= TERM_CTL_SEL;
15426 
15427         switch(scsi_cfg1 & CABLE_DETECT)
15428         {
15429             /* TERM_CTL_H: on, TERM_CTL_L: on */
15430             case 0x3: case 0x7: case 0xB: case 0xD: case 0xE: case 0xF:
15431                 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
15432                 break;
15433 
15434             /* TERM_CTL_H: on, TERM_CTL_L: off */
15435             case 0x1: case 0x5: case 0x9: case 0xA: case 0xC:
15436                 asc_dvc->cfg->termination |= TERM_CTL_H;
15437                 break;
15438 
15439             /* TERM_CTL_H: off, TERM_CTL_L: off */
15440             case 0x2: case 0x6:
15441                 break;
15442         }
15443     }
15444 
15445     /*
15446      * Clear any set TERM_CTL_H and TERM_CTL_L bits.
15447      */
15448     scsi_cfg1 &= ~TERM_CTL;
15449 
15450     /*
15451      * Invert the TERM_CTL_H and TERM_CTL_L bits and then
15452      * set 'scsi_cfg1'. The TERM_POL bit does not need to be
15453      * referenced, because the hardware internally inverts
15454      * the Termination High and Low bits if TERM_POL is set.
15455      */
15456     scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
15457 
15458     /*
15459      * Set SCSI_CFG1 Microcode Default Value
15460      *
15461      * Set filter value and possibly modified termination control
15462      * bits in the Microcode SCSI_CFG1 Register Value.
15463      *
15464      * The microcode will set the SCSI_CFG1 register using this value
15465      * after it is started below.
15466      */
15467     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
15468         FLTR_DISABLE | scsi_cfg1);
15469 
15470     /*
15471      * Set MEM_CFG Microcode Default Value
15472      *
15473      * The microcode will set the MEM_CFG register using this value
15474      * after it is started below.
15475      *
15476      * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15477      * are defined.
15478      *
15479      * ASC-3550 has 8KB internal memory.
15480      */
15481     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15482         BIOS_EN | RAM_SZ_8KB);
15483 
15484     /*
15485      * Set SEL_MASK Microcode Default Value
15486      *
15487      * The microcode will set the SEL_MASK register using this value
15488      * after it is started below.
15489      */
15490     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15491         ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15492 
15493     /*
15494      * Build carrier freelist.
15495      *
15496      * Driver must have already allocated memory and set 'carrier_buf'.
15497      */
15498     ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15499 
15500     carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15501     asc_dvc->carr_freelist = NULL;
15502     if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
15503     {
15504         buf_size = ADV_CARRIER_BUFSIZE;
15505     } else
15506     {
15507         buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15508     }
15509 
15510     do {
15511         /*
15512          * Get physical address of the carrier 'carrp'.
15513          */
15514         contig_len = sizeof(ADV_CARR_T);
15515         carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
15516             (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
15517 
15518         buf_size -= sizeof(ADV_CARR_T);
15519 
15520         /*
15521          * If the current carrier is not physically contiguous, then
15522          * maybe there was a page crossing. Try the next carrier aligned
15523          * start address.
15524          */
15525         if (contig_len < sizeof(ADV_CARR_T))
15526         {
15527             carrp++;
15528             continue;
15529         }
15530 
15531         carrp->carr_pa = carr_paddr;
15532         carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15533 
15534         /*
15535          * Insert the carrier at the beginning of the freelist.
15536          */
15537         carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15538         asc_dvc->carr_freelist = carrp;
15539 
15540         carrp++;
15541     }
15542     while (buf_size > 0);
15543 
15544     /*
15545      * Set-up the Host->RISC Initiator Command Queue (ICQ).
15546      */
15547 
15548     if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
15549     {
15550         asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15551         return ADV_ERROR;
15552     }
15553     asc_dvc->carr_freelist = (ADV_CARR_T *)
15554         ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15555 
15556     /*
15557      * The first command issued will be placed in the stopper carrier.
15558      */
15559     asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15560 
15561     /*
15562      * Set RISC ICQ physical address start value.
15563      */
15564     AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15565 
15566     /*
15567      * Set-up the RISC->Host Initiator Response Queue (IRQ).
15568      */
15569     if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
15570     {
15571         asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15572         return ADV_ERROR;
15573     }
15574     asc_dvc->carr_freelist = (ADV_CARR_T *)
15575          ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15576 
15577     /*
15578      * The first command completed by the RISC will be placed in
15579      * the stopper.
15580      *
15581      * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15582      * completed the RISC will set the ASC_RQ_STOPPER bit.
15583      */
15584     asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15585 
15586     /*
15587      * Set RISC IRQ physical address start value.
15588      */
15589     AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15590     asc_dvc->carr_pending_cnt = 0;
15591 
15592     AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15593         (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
15594 
15595     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15596     AdvWriteWordRegister(iop_base, IOPW_PC, word);
15597 
15598     /* finally, finally, gentlemen, start your engine */
15599     AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15600 
15601     /*
15602      * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15603      * Resets should be performed. The RISC has to be running
15604      * to issue a SCSI Bus Reset.
15605      */
15606     if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
15607     {
15608         /*
15609          * If the BIOS Signature is present in memory, restore the
15610          * BIOS Handshake Configuration Table and do not perform
15611          * a SCSI Bus Reset.
15612          */
15613         if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
15614         {
15615             /*
15616              * Restore per TID negotiated values.
15617              */
15618             AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15619             AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15620             AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15621             for (tid = 0; tid <= ADV_MAX_TID; tid++)
15622             {
15623                 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15624                     max_cmd[tid]);
15625             }
15626         } else
15627         {
15628             if (AdvResetSB(asc_dvc) != ADV_TRUE)
15629             {
15630                 warn_code = ASC_WARN_BUSRESET_ERROR;
15631             }
15632         }
15633     }
15634 
15635     return warn_code;
15636 }
15637 
15638 /*
15639  * Initialize the ASC-38C0800.
15640  *
15641  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15642  *
15643  * For a non-fatal error return a warning code. If there are no warnings
15644  * then 0 is returned.
15645  *
15646  * Needed after initialization for error recovery.
15647  */
15648 STATIC int
AdvInitAsc38C0800Driver(ADV_DVC_VAR * asc_dvc)15649 AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
15650 {
15651     AdvPortAddr iop_base;
15652     ushort      warn_code;
15653     ADV_DCNT    sum;
15654     int         begin_addr;
15655     int         end_addr;
15656     ushort      code_sum;
15657     int         word;
15658     int         j;
15659     int         adv_asc38C0800_expanded_size;
15660     ADV_CARR_T  *carrp;
15661     ADV_DCNT    contig_len;
15662     ADV_SDCNT   buf_size;
15663     ADV_PADDR   carr_paddr;
15664     int         i;
15665     ushort      scsi_cfg1;
15666     uchar       byte;
15667     uchar       tid;
15668     ushort      bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
15669     ushort      wdtr_able, sdtr_able, tagqng_able;
15670     uchar       max_cmd[ADV_MAX_TID + 1];
15671 
15672     /* If there is already an error, don't continue. */
15673     if (asc_dvc->err_code != 0)
15674     {
15675         return ADV_ERROR;
15676     }
15677 
15678     /*
15679      * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
15680      */
15681     if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800)
15682     {
15683         asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
15684         return ADV_ERROR;
15685     }
15686 
15687     warn_code = 0;
15688     iop_base = asc_dvc->iop_base;
15689 
15690     /*
15691      * Save the RISC memory BIOS region before writing the microcode.
15692      * The BIOS may already be loaded and using its RISC LRAM region
15693      * so its region must be saved and restored.
15694      *
15695      * Note: This code makes the assumption, which is currently true,
15696      * that a chip reset does not clear RISC LRAM.
15697      */
15698     for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15699     {
15700         AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15701     }
15702 
15703     /*
15704      * Save current per TID negotiated values.
15705      */
15706     AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15707     AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15708     AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15709     for (tid = 0; tid <= ADV_MAX_TID; tid++)
15710     {
15711         AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15712             max_cmd[tid]);
15713     }
15714 
15715     /*
15716      * RAM BIST (RAM Built-In Self Test)
15717      *
15718      * Address : I/O base + offset 0x38h register (byte).
15719      * Function: Bit 7-6(RW) : RAM mode
15720      *                          Normal Mode   : 0x00
15721      *                          Pre-test Mode : 0x40
15722      *                          RAM Test Mode : 0x80
15723      *           Bit 5       : unused
15724      *           Bit 4(RO)   : Done bit
15725      *           Bit 3-0(RO) : Status
15726      *                          Host Error    : 0x08
15727      *                          Int_RAM Error : 0x04
15728      *                          RISC Error    : 0x02
15729      *                          SCSI Error    : 0x01
15730      *                          No Error      : 0x00
15731      *
15732      * Note: RAM BIST code should be put right here, before loading the
15733      * microcode and after saving the RISC memory BIOS region.
15734      */
15735 
15736     /*
15737      * LRAM Pre-test
15738      *
15739      * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15740      * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15741      * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15742      * to NORMAL_MODE, return an error too.
15743      */
15744     for (i = 0; i < 2; i++)
15745     {
15746         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15747         DvcSleepMilliSecond(10);  /* Wait for 10ms before reading back. */
15748         byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15749         if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE)
15750         {
15751             asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15752             return ADV_ERROR;
15753         }
15754 
15755         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15756         DvcSleepMilliSecond(10);  /* Wait for 10ms before reading back. */
15757         if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15758             != NORMAL_VALUE)
15759         {
15760             asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15761             return ADV_ERROR;
15762         }
15763     }
15764 
15765     /*
15766      * LRAM Test - It takes about 1.5 ms to run through the test.
15767      *
15768      * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15769      * If Done bit not set or Status not 0, save register byte, set the
15770      * err_code, and return an error.
15771      */
15772     AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15773     DvcSleepMilliSecond(10);  /* Wait for 10ms before checking status. */
15774 
15775     byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15776     if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0)
15777     {
15778         /* Get here if Done bit not set or Status not 0. */
15779         asc_dvc->bist_err_code = byte;  /* for BIOS display message */
15780         asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15781         return ADV_ERROR;
15782     }
15783 
15784     /* We need to reset back to normal mode after LRAM test passes. */
15785     AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15786 
15787     /*
15788      * Load the Microcode
15789      *
15790      * Write the microcode image to RISC memory starting at address 0.
15791      *
15792      */
15793     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15794 
15795     /* Assume the following compressed format of the microcode buffer:
15796      *
15797      *  254 word (508 byte) table indexed by byte code followed
15798      *  by the following byte codes:
15799      *
15800      *    1-Byte Code:
15801      *      00: Emit word 0 in table.
15802      *      01: Emit word 1 in table.
15803      *      .
15804      *      FD: Emit word 253 in table.
15805      *
15806      *    Multi-Byte Code:
15807      *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15808      *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15809      */
15810     word = 0;
15811     for (i = 253 * 2; i < _adv_asc38C0800_size; i++)
15812     {
15813         if (_adv_asc38C0800_buf[i] == 0xff)
15814         {
15815             for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++)
15816             {
15817                 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15818                     _adv_asc38C0800_buf[i + 3] << 8) |
15819                     _adv_asc38C0800_buf[i + 2]));
15820                 word++;
15821             }
15822             i += 3;
15823         } else if (_adv_asc38C0800_buf[i] == 0xfe)
15824         {
15825             AdvWriteWordAutoIncLram(iop_base, (((ushort)
15826                 _adv_asc38C0800_buf[i + 2] << 8) |
15827                 _adv_asc38C0800_buf[i + 1]));
15828             i += 2;
15829             word++;
15830         } else
15831         {
15832             AdvWriteWordAutoIncLram(iop_base, (((ushort)
15833                 _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) |
15834                 _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
15835             word++;
15836         }
15837     }
15838 
15839     /*
15840      * Set 'word' for later use to clear the rest of memory and save
15841      * the expanded mcode size.
15842      */
15843     word *= 2;
15844     adv_asc38C0800_expanded_size = word;
15845 
15846     /*
15847      * Clear the rest of ASC-38C0800 Internal RAM (16KB).
15848      */
15849     for (; word < ADV_38C0800_MEMSIZE; word += 2)
15850     {
15851         AdvWriteWordAutoIncLram(iop_base, 0);
15852     }
15853 
15854     /*
15855      * Verify the microcode checksum.
15856      */
15857     sum = 0;
15858     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15859 
15860     for (word = 0; word < adv_asc38C0800_expanded_size; word += 2)
15861     {
15862         sum += AdvReadWordAutoIncLram(iop_base);
15863     }
15864     ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
15865 
15866     ASC_DBG2(1,
15867         "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
15868         (ulong) sum, (ulong) _adv_asc38C0800_chksum);
15869 
15870     if (sum != _adv_asc38C0800_chksum)
15871     {
15872         asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15873         return ADV_ERROR;
15874     }
15875 
15876     /*
15877      * Restore the RISC memory BIOS region.
15878      */
15879     for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15880     {
15881         AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15882     }
15883 
15884     /*
15885      * Calculate and write the microcode code checksum to the microcode
15886      * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15887      */
15888     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15889     AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15890     code_sum = 0;
15891     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15892     for (word = begin_addr; word < end_addr; word += 2)
15893     {
15894         code_sum += AdvReadWordAutoIncLram(iop_base);
15895     }
15896     AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15897 
15898     /*
15899      * Read microcode version and date.
15900      */
15901     AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
15902     AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
15903 
15904     /*
15905      * Set the chip type to indicate the ASC38C0800.
15906      */
15907     AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
15908 
15909     /*
15910      * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15911      * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15912      * cable detection and then we are able to read C_DET[3:0].
15913      *
15914      * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15915      * Microcode Default Value' section below.
15916      */
15917     scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15918     AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV);
15919 
15920     /*
15921      * If the PCI Configuration Command Register "Parity Error Response
15922      * Control" Bit was clear (0), then set the microcode variable
15923      * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15924      * to ignore DMA parity errors.
15925      */
15926     if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
15927     {
15928         AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15929         word |= CONTROL_FLAG_IGNORE_PERR;
15930         AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15931     }
15932 
15933     /*
15934      * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
15935      * bits for the default FIFO threshold.
15936      *
15937      * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
15938      *
15939      * For DMA Errata #4 set the BC_THRESH_ENB bit.
15940      */
15941     AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15942         BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
15943 
15944     /*
15945      * Microcode operating variables for WDTR, SDTR, and command tag
15946      * queuing will be set in AdvInquiryHandling() based on what a
15947      * device reports it is capable of in Inquiry byte 7.
15948      *
15949      * If SCSI Bus Resets have been disabled, then directly set
15950      * SDTR and WDTR from the EEPROM configuration. This will allow
15951      * the BIOS and warm boot to work without a SCSI bus hang on
15952      * the Inquiry caused by host and target mismatched DTR values.
15953      * Without the SCSI Bus Reset, before an Inquiry a device can't
15954      * be assumed to be in Asynchronous, Narrow mode.
15955      */
15956     if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
15957     {
15958         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
15959         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
15960     }
15961 
15962     /*
15963      * Set microcode operating variables for DISC and SDTR_SPEED1,
15964      * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15965      * configuration values.
15966      *
15967      * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15968      * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15969      * without determining here whether the device supports SDTR.
15970      */
15971     AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
15972     AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15973     AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15974     AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15975     AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15976 
15977     /*
15978      * Set SCSI_CFG0 Microcode Default Value.
15979      *
15980      * The microcode will set the SCSI_CFG0 register using this value
15981      * after it is started below.
15982      */
15983     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15984         PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15985         asc_dvc->chip_scsi_id);
15986 
15987     /*
15988      * Determine SCSI_CFG1 Microcode Default Value.
15989      *
15990      * The microcode will set the SCSI_CFG1 register using this value
15991      * after it is started below.
15992      */
15993 
15994     /* Read current SCSI_CFG1 Register value. */
15995     scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15996 
15997     /*
15998      * If the internal narrow cable is reversed all of the SCSI_CTRL
15999      * register signals will be set. Check for and return an error if
16000      * this condition is found.
16001      */
16002     if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
16003     {
16004         asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
16005         return ADV_ERROR;
16006     }
16007 
16008     /*
16009      * All kind of combinations of devices attached to one of four connectors
16010      * are acceptable except HVD device attached. For example, LVD device can
16011      * be attached to SE connector while SE device attached to LVD connector.
16012      * If LVD device attached to SE connector, it only runs up to Ultra speed.
16013      *
16014      * If an HVD device is attached to one of LVD connectors, return an error.
16015      * However, there is no way to detect HVD device attached to SE connectors.
16016      */
16017     if (scsi_cfg1 & HVD)
16018     {
16019         asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
16020         return ADV_ERROR;
16021     }
16022 
16023     /*
16024      * If either SE or LVD automatic termination control is enabled, then
16025      * set the termination value based on a table listed in a_condor.h.
16026      *
16027      * If manual termination was specified with an EEPROM setting then
16028      * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
16029      * be 'ored' into SCSI_CFG1.
16030      */
16031     if ((asc_dvc->cfg->termination & TERM_SE) == 0)
16032     {
16033         /* SE automatic termination control is enabled. */
16034         switch(scsi_cfg1 & C_DET_SE)
16035         {
16036             /* TERM_SE_HI: on, TERM_SE_LO: on */
16037             case 0x1: case 0x2: case 0x3:
16038                 asc_dvc->cfg->termination |= TERM_SE;
16039                 break;
16040 
16041             /* TERM_SE_HI: on, TERM_SE_LO: off */
16042             case 0x0:
16043                 asc_dvc->cfg->termination |= TERM_SE_HI;
16044                 break;
16045         }
16046     }
16047 
16048     if ((asc_dvc->cfg->termination & TERM_LVD) == 0)
16049     {
16050         /* LVD automatic termination control is enabled. */
16051         switch(scsi_cfg1 & C_DET_LVD)
16052         {
16053             /* TERM_LVD_HI: on, TERM_LVD_LO: on */
16054             case 0x4: case 0x8: case 0xC:
16055                 asc_dvc->cfg->termination |= TERM_LVD;
16056                 break;
16057 
16058             /* TERM_LVD_HI: off, TERM_LVD_LO: off */
16059             case 0x0:
16060                 break;
16061         }
16062     }
16063 
16064     /*
16065      * Clear any set TERM_SE and TERM_LVD bits.
16066      */
16067     scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
16068 
16069     /*
16070      * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
16071      */
16072     scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
16073 
16074     /*
16075      * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
16076      * and set possibly modified termination control bits in the Microcode
16077      * SCSI_CFG1 Register Value.
16078      */
16079     scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
16080 
16081     /*
16082      * Set SCSI_CFG1 Microcode Default Value
16083      *
16084      * Set possibly modified termination control and reset DIS_TERM_DRV
16085      * bits in the Microcode SCSI_CFG1 Register Value.
16086      *
16087      * The microcode will set the SCSI_CFG1 register using this value
16088      * after it is started below.
16089      */
16090     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
16091 
16092     /*
16093      * Set MEM_CFG Microcode Default Value
16094      *
16095      * The microcode will set the MEM_CFG register using this value
16096      * after it is started below.
16097      *
16098      * MEM_CFG may be accessed as a word or byte, but only bits 0-7
16099      * are defined.
16100      *
16101      * ASC-38C0800 has 16KB internal memory.
16102      */
16103     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
16104         BIOS_EN | RAM_SZ_16KB);
16105 
16106     /*
16107      * Set SEL_MASK Microcode Default Value
16108      *
16109      * The microcode will set the SEL_MASK register using this value
16110      * after it is started below.
16111      */
16112     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
16113         ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
16114 
16115     /*
16116      * Build the carrier freelist.
16117      *
16118      * Driver must have already allocated memory and set 'carrier_buf'.
16119      */
16120     ASC_ASSERT(asc_dvc->carrier_buf != NULL);
16121 
16122     carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
16123     asc_dvc->carr_freelist = NULL;
16124     if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
16125     {
16126         buf_size = ADV_CARRIER_BUFSIZE;
16127     } else
16128     {
16129         buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
16130     }
16131 
16132     do {
16133         /*
16134          * Get physical address for the carrier 'carrp'.
16135          */
16136         contig_len = sizeof(ADV_CARR_T);
16137         carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
16138             (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
16139 
16140         buf_size -= sizeof(ADV_CARR_T);
16141 
16142         /*
16143          * If the current carrier is not physically contiguous, then
16144          * maybe there was a page crossing. Try the next carrier aligned
16145          * start address.
16146          */
16147         if (contig_len < sizeof(ADV_CARR_T))
16148         {
16149             carrp++;
16150             continue;
16151         }
16152 
16153         carrp->carr_pa = carr_paddr;
16154         carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
16155 
16156         /*
16157          * Insert the carrier at the beginning of the freelist.
16158          */
16159         carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
16160         asc_dvc->carr_freelist = carrp;
16161 
16162         carrp++;
16163     }
16164     while (buf_size > 0);
16165 
16166     /*
16167      * Set-up the Host->RISC Initiator Command Queue (ICQ).
16168      */
16169 
16170     if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
16171     {
16172         asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16173         return ADV_ERROR;
16174     }
16175     asc_dvc->carr_freelist = (ADV_CARR_T *)
16176         ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
16177 
16178     /*
16179      * The first command issued will be placed in the stopper carrier.
16180      */
16181     asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16182 
16183     /*
16184      * Set RISC ICQ physical address start value.
16185      * carr_pa is LE, must be native before write
16186      */
16187     AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
16188 
16189     /*
16190      * Set-up the RISC->Host Initiator Response Queue (IRQ).
16191      */
16192     if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
16193     {
16194         asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16195         return ADV_ERROR;
16196     }
16197     asc_dvc->carr_freelist = (ADV_CARR_T *)
16198         ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
16199 
16200     /*
16201      * The first command completed by the RISC will be placed in
16202      * the stopper.
16203      *
16204      * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
16205      * completed the RISC will set the ASC_RQ_STOPPER bit.
16206      */
16207     asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16208 
16209     /*
16210      * Set RISC IRQ physical address start value.
16211      *
16212      * carr_pa is LE, must be native before write *
16213      */
16214     AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
16215     asc_dvc->carr_pending_cnt = 0;
16216 
16217     AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
16218         (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
16219 
16220     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
16221     AdvWriteWordRegister(iop_base, IOPW_PC, word);
16222 
16223     /* finally, finally, gentlemen, start your engine */
16224     AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
16225 
16226     /*
16227      * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
16228      * Resets should be performed. The RISC has to be running
16229      * to issue a SCSI Bus Reset.
16230      */
16231     if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
16232     {
16233         /*
16234          * If the BIOS Signature is present in memory, restore the
16235          * BIOS Handshake Configuration Table and do not perform
16236          * a SCSI Bus Reset.
16237          */
16238         if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
16239         {
16240             /*
16241              * Restore per TID negotiated values.
16242              */
16243             AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16244             AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16245             AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16246             for (tid = 0; tid <= ADV_MAX_TID; tid++)
16247             {
16248                 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16249                     max_cmd[tid]);
16250             }
16251         } else
16252         {
16253             if (AdvResetSB(asc_dvc) != ADV_TRUE)
16254             {
16255                 warn_code = ASC_WARN_BUSRESET_ERROR;
16256             }
16257         }
16258     }
16259 
16260     return warn_code;
16261 }
16262 
16263 /*
16264  * Initialize the ASC-38C1600.
16265  *
16266  * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
16267  *
16268  * For a non-fatal error return a warning code. If there are no warnings
16269  * then 0 is returned.
16270  *
16271  * Needed after initialization for error recovery.
16272  */
16273 STATIC int
AdvInitAsc38C1600Driver(ADV_DVC_VAR * asc_dvc)16274 AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
16275 {
16276     AdvPortAddr iop_base;
16277     ushort      warn_code;
16278     ADV_DCNT    sum;
16279     int         begin_addr;
16280     int         end_addr;
16281     ushort      code_sum;
16282     long        word;
16283     int         j;
16284     int         adv_asc38C1600_expanded_size;
16285     ADV_CARR_T  *carrp;
16286     ADV_DCNT    contig_len;
16287     ADV_SDCNT   buf_size;
16288     ADV_PADDR   carr_paddr;
16289     int         i;
16290     ushort      scsi_cfg1;
16291     uchar       byte;
16292     uchar       tid;
16293     ushort      bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
16294     ushort      wdtr_able, sdtr_able, ppr_able, tagqng_able;
16295     uchar       max_cmd[ASC_MAX_TID + 1];
16296 
16297     /* If there is already an error, don't continue. */
16298     if (asc_dvc->err_code != 0)
16299     {
16300         return ADV_ERROR;
16301     }
16302 
16303     /*
16304      * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
16305      */
16306     if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600)
16307     {
16308         asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
16309         return ADV_ERROR;
16310     }
16311 
16312     warn_code = 0;
16313     iop_base = asc_dvc->iop_base;
16314 
16315     /*
16316      * Save the RISC memory BIOS region before writing the microcode.
16317      * The BIOS may already be loaded and using its RISC LRAM region
16318      * so its region must be saved and restored.
16319      *
16320      * Note: This code makes the assumption, which is currently true,
16321      * that a chip reset does not clear RISC LRAM.
16322      */
16323     for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
16324     {
16325         AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
16326     }
16327 
16328     /*
16329      * Save current per TID negotiated values.
16330      */
16331     AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16332     AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16333     AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16334     AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16335     for (tid = 0; tid <= ASC_MAX_TID; tid++)
16336     {
16337         AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16338             max_cmd[tid]);
16339     }
16340 
16341     /*
16342      * RAM BIST (Built-In Self Test)
16343      *
16344      * Address : I/O base + offset 0x38h register (byte).
16345      * Function: Bit 7-6(RW) : RAM mode
16346      *                          Normal Mode   : 0x00
16347      *                          Pre-test Mode : 0x40
16348      *                          RAM Test Mode : 0x80
16349      *           Bit 5       : unused
16350      *           Bit 4(RO)   : Done bit
16351      *           Bit 3-0(RO) : Status
16352      *                          Host Error    : 0x08
16353      *                          Int_RAM Error : 0x04
16354      *                          RISC Error    : 0x02
16355      *                          SCSI Error    : 0x01
16356      *                          No Error      : 0x00
16357      *
16358      * Note: RAM BIST code should be put right here, before loading the
16359      * microcode and after saving the RISC memory BIOS region.
16360      */
16361 
16362     /*
16363      * LRAM Pre-test
16364      *
16365      * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
16366      * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
16367      * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
16368      * to NORMAL_MODE, return an error too.
16369      */
16370     for (i = 0; i < 2; i++)
16371     {
16372         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
16373         DvcSleepMilliSecond(10);  /* Wait for 10ms before reading back. */
16374         byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
16375         if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE)
16376         {
16377             asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
16378             return ADV_ERROR;
16379         }
16380 
16381         AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
16382         DvcSleepMilliSecond(10);  /* Wait for 10ms before reading back. */
16383         if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
16384             != NORMAL_VALUE)
16385         {
16386             asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
16387             return ADV_ERROR;
16388         }
16389     }
16390 
16391     /*
16392      * LRAM Test - It takes about 1.5 ms to run through the test.
16393      *
16394      * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
16395      * If Done bit not set or Status not 0, save register byte, set the
16396      * err_code, and return an error.
16397      */
16398     AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
16399     DvcSleepMilliSecond(10);  /* Wait for 10ms before checking status. */
16400 
16401     byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
16402     if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0)
16403     {
16404         /* Get here if Done bit not set or Status not 0. */
16405         asc_dvc->bist_err_code = byte;  /* for BIOS display message */
16406         asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
16407         return ADV_ERROR;
16408     }
16409 
16410     /* We need to reset back to normal mode after LRAM test passes. */
16411     AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
16412 
16413     /*
16414      * Load the Microcode
16415      *
16416      * Write the microcode image to RISC memory starting at address 0.
16417      *
16418      */
16419     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
16420 
16421     /*
16422      * Assume the following compressed format of the microcode buffer:
16423      *
16424      *  254 word (508 byte) table indexed by byte code followed
16425      *  by the following byte codes:
16426      *
16427      *    1-Byte Code:
16428      *      00: Emit word 0 in table.
16429      *      01: Emit word 1 in table.
16430      *      .
16431      *      FD: Emit word 253 in table.
16432      *
16433      *    Multi-Byte Code:
16434      *      FE WW WW: (3 byte code) Word to emit is the next word WW WW.
16435      *      FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
16436      */
16437     word = 0;
16438     for (i = 253 * 2; i < _adv_asc38C1600_size; i++)
16439     {
16440         if (_adv_asc38C1600_buf[i] == 0xff)
16441         {
16442             for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++)
16443             {
16444                 AdvWriteWordAutoIncLram(iop_base, (((ushort)
16445                      _adv_asc38C1600_buf[i + 3] << 8) |
16446                      _adv_asc38C1600_buf[i + 2]));
16447                 word++;
16448             }
16449            i += 3;
16450         } else if (_adv_asc38C1600_buf[i] == 0xfe)
16451         {
16452                 AdvWriteWordAutoIncLram(iop_base, (((ushort)
16453                      _adv_asc38C1600_buf[i + 2] << 8) |
16454                      _adv_asc38C1600_buf[i + 1]));
16455             i += 2;
16456             word++;
16457         } else
16458         {
16459             AdvWriteWordAutoIncLram(iop_base, (((ushort)
16460                  _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) |
16461                  _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
16462             word++;
16463         }
16464     }
16465 
16466     /*
16467      * Set 'word' for later use to clear the rest of memory and save
16468      * the expanded mcode size.
16469      */
16470     word *= 2;
16471     adv_asc38C1600_expanded_size = word;
16472 
16473     /*
16474      * Clear the rest of ASC-38C1600 Internal RAM (32KB).
16475      */
16476     for (; word < ADV_38C1600_MEMSIZE; word += 2)
16477     {
16478         AdvWriteWordAutoIncLram(iop_base, 0);
16479     }
16480 
16481     /*
16482      * Verify the microcode checksum.
16483      */
16484     sum = 0;
16485     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
16486 
16487     for (word = 0; word < adv_asc38C1600_expanded_size; word += 2)
16488     {
16489         sum += AdvReadWordAutoIncLram(iop_base);
16490     }
16491 
16492     if (sum != _adv_asc38C1600_chksum)
16493     {
16494         asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
16495         return ADV_ERROR;
16496     }
16497 
16498     /*
16499      * Restore the RISC memory BIOS region.
16500      */
16501     for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
16502     {
16503         AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
16504     }
16505 
16506     /*
16507      * Calculate and write the microcode code checksum to the microcode
16508      * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
16509      */
16510     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
16511     AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
16512     code_sum = 0;
16513     AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
16514     for (word = begin_addr; word < end_addr; word += 2)
16515     {
16516         code_sum += AdvReadWordAutoIncLram(iop_base);
16517     }
16518     AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
16519 
16520     /*
16521      * Read microcode version and date.
16522      */
16523     AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
16524     AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
16525 
16526     /*
16527      * Set the chip type to indicate the ASC38C1600.
16528      */
16529     AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
16530 
16531     /*
16532      * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
16533      * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
16534      * cable detection and then we are able to read C_DET[3:0].
16535      *
16536      * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
16537      * Microcode Default Value' section below.
16538      */
16539     scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
16540     AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV);
16541 
16542     /*
16543      * If the PCI Configuration Command Register "Parity Error Response
16544      * Control" Bit was clear (0), then set the microcode variable
16545      * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
16546      * to ignore DMA parity errors.
16547      */
16548     if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
16549     {
16550         AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16551         word |= CONTROL_FLAG_IGNORE_PERR;
16552         AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16553     }
16554 
16555     /*
16556      * If the BIOS control flag AIPP (Asynchronous Information
16557      * Phase Protection) disable bit is not set, then set the firmware
16558      * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
16559      * AIPP checking and encoding.
16560      */
16561     if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0)
16562     {
16563         AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16564         word |= CONTROL_FLAG_ENABLE_AIPP;
16565         AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16566     }
16567 
16568     /*
16569      * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
16570      * and START_CTL_TH [3:2].
16571      */
16572     AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
16573         FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
16574 
16575     /*
16576      * Microcode operating variables for WDTR, SDTR, and command tag
16577      * queuing will be set in AdvInquiryHandling() based on what a
16578      * device reports it is capable of in Inquiry byte 7.
16579      *
16580      * If SCSI Bus Resets have been disabled, then directly set
16581      * SDTR and WDTR from the EEPROM configuration. This will allow
16582      * the BIOS and warm boot to work without a SCSI bus hang on
16583      * the Inquiry caused by host and target mismatched DTR values.
16584      * Without the SCSI Bus Reset, before an Inquiry a device can't
16585      * be assumed to be in Asynchronous, Narrow mode.
16586      */
16587     if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
16588     {
16589         AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
16590         AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
16591     }
16592 
16593     /*
16594      * Set microcode operating variables for DISC and SDTR_SPEED1,
16595      * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
16596      * configuration values.
16597      *
16598      * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
16599      * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
16600      * without determining here whether the device supports SDTR.
16601      */
16602     AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
16603     AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
16604     AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
16605     AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
16606     AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
16607 
16608     /*
16609      * Set SCSI_CFG0 Microcode Default Value.
16610      *
16611      * The microcode will set the SCSI_CFG0 register using this value
16612      * after it is started below.
16613      */
16614     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
16615         PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
16616         asc_dvc->chip_scsi_id);
16617 
16618     /*
16619      * Calculate SCSI_CFG1 Microcode Default Value.
16620      *
16621      * The microcode will set the SCSI_CFG1 register using this value
16622      * after it is started below.
16623      *
16624      * Each ASC-38C1600 function has only two cable detect bits.
16625      * The bus mode override bits are in IOPB_SOFT_OVER_WR.
16626      */
16627     scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
16628 
16629     /*
16630      * If the cable is reversed all of the SCSI_CTRL register signals
16631      * will be set. Check for and return an error if this condition is
16632      * found.
16633      */
16634     if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
16635     {
16636         asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
16637         return ADV_ERROR;
16638     }
16639 
16640     /*
16641      * Each ASC-38C1600 function has two connectors. Only an HVD device
16642      * can not be connected to either connector. An LVD device or SE device
16643      * may be connected to either connecor. If an SE device is connected,
16644      * then at most Ultra speed (20 Mhz) can be used on both connectors.
16645      *
16646      * If an HVD device is attached, return an error.
16647      */
16648     if (scsi_cfg1 & HVD)
16649     {
16650         asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
16651         return ADV_ERROR;
16652     }
16653 
16654     /*
16655      * Each function in the ASC-38C1600 uses only the SE cable detect and
16656      * termination because there are two connectors for each function. Each
16657      * function may use either LVD or SE mode. Corresponding the SE automatic
16658      * termination control EEPROM bits are used for each function. Each
16659      * function has its own EEPROM. If SE automatic control is enabled for
16660      * the function, then set the termination value based on a table listed
16661      * in a_condor.h.
16662      *
16663      * If manual termination is specified in the EEPROM for the function,
16664      * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
16665      * ready to be 'ored' into SCSI_CFG1.
16666      */
16667     if ((asc_dvc->cfg->termination & TERM_SE) == 0)
16668     {
16669         /* SE automatic termination control is enabled. */
16670         switch(scsi_cfg1 & C_DET_SE)
16671         {
16672             /* TERM_SE_HI: on, TERM_SE_LO: on */
16673             case 0x1: case 0x2: case 0x3:
16674                 asc_dvc->cfg->termination |= TERM_SE;
16675                 break;
16676 
16677             case 0x0:
16678                 if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0)
16679                 {
16680                     /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
16681                 }
16682                 else
16683                 {
16684                     /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
16685                     asc_dvc->cfg->termination |= TERM_SE_HI;
16686                 }
16687                 break;
16688         }
16689     }
16690 
16691     /*
16692      * Clear any set TERM_SE bits.
16693      */
16694     scsi_cfg1 &= ~TERM_SE;
16695 
16696     /*
16697      * Invert the TERM_SE bits and then set 'scsi_cfg1'.
16698      */
16699     scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
16700 
16701     /*
16702      * Clear Big Endian and Terminator Polarity bits and set possibly
16703      * modified termination control bits in the Microcode SCSI_CFG1
16704      * Register Value.
16705      *
16706      * Big Endian bit is not used even on big endian machines.
16707      */
16708     scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
16709 
16710     /*
16711      * Set SCSI_CFG1 Microcode Default Value
16712      *
16713      * Set possibly modified termination control bits in the Microcode
16714      * SCSI_CFG1 Register Value.
16715      *
16716      * The microcode will set the SCSI_CFG1 register using this value
16717      * after it is started below.
16718      */
16719     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
16720 
16721     /*
16722      * Set MEM_CFG Microcode Default Value
16723      *
16724      * The microcode will set the MEM_CFG register using this value
16725      * after it is started below.
16726      *
16727      * MEM_CFG may be accessed as a word or byte, but only bits 0-7
16728      * are defined.
16729      *
16730      * ASC-38C1600 has 32KB internal memory.
16731      *
16732      * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
16733      * out a special 16K Adv Library and Microcode version. After the issue
16734      * resolved, we should turn back to the 32K support. Both a_condor.h and
16735      * mcode.sas files also need to be updated.
16736      *
16737      * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
16738      *  BIOS_EN | RAM_SZ_32KB);
16739      */
16740      AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, BIOS_EN | RAM_SZ_16KB);
16741 
16742     /*
16743      * Set SEL_MASK Microcode Default Value
16744      *
16745      * The microcode will set the SEL_MASK register using this value
16746      * after it is started below.
16747      */
16748     AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
16749         ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
16750 
16751     /*
16752      * Build the carrier freelist.
16753      *
16754      * Driver must have already allocated memory and set 'carrier_buf'.
16755      */
16756 
16757     ASC_ASSERT(asc_dvc->carrier_buf != NULL);
16758 
16759     carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
16760     asc_dvc->carr_freelist = NULL;
16761     if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
16762     {
16763         buf_size = ADV_CARRIER_BUFSIZE;
16764     } else
16765     {
16766         buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
16767     }
16768 
16769     do {
16770         /*
16771          * Get physical address for the carrier 'carrp'.
16772          */
16773         contig_len = sizeof(ADV_CARR_T);
16774         carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
16775             (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
16776 
16777         buf_size -= sizeof(ADV_CARR_T);
16778 
16779         /*
16780          * If the current carrier is not physically contiguous, then
16781          * maybe there was a page crossing. Try the next carrier aligned
16782          * start address.
16783          */
16784         if (contig_len < sizeof(ADV_CARR_T))
16785         {
16786             carrp++;
16787             continue;
16788         }
16789 
16790         carrp->carr_pa = carr_paddr;
16791         carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
16792 
16793         /*
16794          * Insert the carrier at the beginning of the freelist.
16795          */
16796         carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
16797         asc_dvc->carr_freelist = carrp;
16798 
16799         carrp++;
16800     }
16801     while (buf_size > 0);
16802 
16803     /*
16804      * Set-up the Host->RISC Initiator Command Queue (ICQ).
16805      */
16806     if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
16807     {
16808         asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16809         return ADV_ERROR;
16810     }
16811     asc_dvc->carr_freelist = (ADV_CARR_T *)
16812         ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
16813 
16814     /*
16815      * The first command issued will be placed in the stopper carrier.
16816      */
16817     asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16818 
16819     /*
16820      * Set RISC ICQ physical address start value. Initialize the
16821      * COMMA register to the same value otherwise the RISC will
16822      * prematurely detect a command is available.
16823      */
16824     AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
16825     AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
16826         le32_to_cpu(asc_dvc->icq_sp->carr_pa));
16827 
16828     /*
16829      * Set-up the RISC->Host Initiator Response Queue (IRQ).
16830      */
16831     if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
16832     {
16833         asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16834         return ADV_ERROR;
16835     }
16836     asc_dvc->carr_freelist = (ADV_CARR_T *)
16837         ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
16838 
16839     /*
16840      * The first command completed by the RISC will be placed in
16841      * the stopper.
16842      *
16843      * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
16844      * completed the RISC will set the ASC_RQ_STOPPER bit.
16845      */
16846     asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16847 
16848     /*
16849      * Set RISC IRQ physical address start value.
16850      */
16851     AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
16852     asc_dvc->carr_pending_cnt = 0;
16853 
16854     AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
16855         (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
16856     AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
16857     AdvWriteWordRegister(iop_base, IOPW_PC, word);
16858 
16859     /* finally, finally, gentlemen, start your engine */
16860     AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
16861 
16862     /*
16863      * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
16864      * Resets should be performed. The RISC has to be running
16865      * to issue a SCSI Bus Reset.
16866      */
16867     if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
16868     {
16869         /*
16870          * If the BIOS Signature is present in memory, restore the
16871          * per TID microcode operating variables.
16872          */
16873         if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
16874         {
16875             /*
16876              * Restore per TID negotiated values.
16877              */
16878             AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16879             AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16880             AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16881             AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16882             for (tid = 0; tid <= ASC_MAX_TID; tid++)
16883             {
16884                 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16885                     max_cmd[tid]);
16886             }
16887         } else
16888         {
16889             if (AdvResetSB(asc_dvc) != ADV_TRUE)
16890             {
16891                 warn_code = ASC_WARN_BUSRESET_ERROR;
16892             }
16893         }
16894     }
16895 
16896     return warn_code;
16897 }
16898 
16899 /*
16900  * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16901  * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16902  * all of this is done.
16903  *
16904  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16905  *
16906  * For a non-fatal error return a warning code. If there are no warnings
16907  * then 0 is returned.
16908  *
16909  * Note: Chip is stopped on entry.
16910  */
ASC_INITFUNC(STATIC int,AdvInitFrom3550EEP (ADV_DVC_VAR * asc_dvc))16911 ASC_INITFUNC(
16912 STATIC int,
16913 AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
16914 )
16915 {
16916     AdvPortAddr         iop_base;
16917     ushort              warn_code;
16918     ADVEEP_3550_CONFIG  eep_config;
16919     int                 i;
16920 
16921     iop_base = asc_dvc->iop_base;
16922 
16923     warn_code = 0;
16924 
16925     /*
16926      * Read the board's EEPROM configuration.
16927      *
16928      * Set default values if a bad checksum is found.
16929      */
16930     if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16931     {
16932         warn_code |= ASC_WARN_EEPROM_CHKSUM;
16933 
16934         /*
16935          * Set EEPROM default values.
16936          */
16937         for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++)
16938         {
16939             *((uchar *) &eep_config + i) =
16940                 *((uchar *) &Default_3550_EEPROM_Config + i);
16941         }
16942 
16943         /*
16944          * Assume the 6 byte board serial number that was read
16945          * from EEPROM is correct even if the EEPROM checksum
16946          * failed.
16947          */
16948         eep_config.serial_number_word3 =
16949             AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16950 
16951         eep_config.serial_number_word2 =
16952             AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16953 
16954         eep_config.serial_number_word1 =
16955             AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16956 
16957         AdvSet3550EEPConfig(iop_base, &eep_config);
16958     }
16959     /*
16960      * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16961      * EEPROM configuration that was read.
16962      *
16963      * This is the mapping of EEPROM fields to Adv Library fields.
16964      */
16965     asc_dvc->wdtr_able = eep_config.wdtr_able;
16966     asc_dvc->sdtr_able = eep_config.sdtr_able;
16967     asc_dvc->ultra_able = eep_config.ultra_able;
16968     asc_dvc->tagqng_able = eep_config.tagqng_able;
16969     asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16970     asc_dvc->max_host_qng = eep_config.max_host_qng;
16971     asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16972     asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16973     asc_dvc->start_motor = eep_config.start_motor;
16974     asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16975     asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16976     asc_dvc->no_scam = eep_config.scam_tolerant;
16977     asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16978     asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16979     asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16980 
16981     /*
16982      * Set the host maximum queuing (max. 253, min. 16) and the per device
16983      * maximum queuing (max. 63, min. 4).
16984      */
16985     if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
16986     {
16987         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16988     } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
16989     {
16990         /* If the value is zero, assume it is uninitialized. */
16991         if (eep_config.max_host_qng == 0)
16992         {
16993             eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16994         } else
16995         {
16996             eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16997         }
16998     }
16999 
17000     if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
17001     {
17002         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17003     } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
17004     {
17005         /* If the value is zero, assume it is uninitialized. */
17006         if (eep_config.max_dvc_qng == 0)
17007         {
17008             eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17009         } else
17010         {
17011             eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
17012         }
17013     }
17014 
17015     /*
17016      * If 'max_dvc_qng' is greater than 'max_host_qng', then
17017      * set 'max_dvc_qng' to 'max_host_qng'.
17018      */
17019     if (eep_config.max_dvc_qng > eep_config.max_host_qng)
17020     {
17021         eep_config.max_dvc_qng = eep_config.max_host_qng;
17022     }
17023 
17024     /*
17025      * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
17026      * values based on possibly adjusted EEPROM values.
17027      */
17028     asc_dvc->max_host_qng = eep_config.max_host_qng;
17029     asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
17030 
17031 
17032     /*
17033      * If the EEPROM 'termination' field is set to automatic (0), then set
17034      * the ADV_DVC_CFG 'termination' field to automatic also.
17035      *
17036      * If the termination is specified with a non-zero 'termination'
17037      * value check that a legal value is set and set the ADV_DVC_CFG
17038      * 'termination' field appropriately.
17039      */
17040     if (eep_config.termination == 0)
17041     {
17042         asc_dvc->cfg->termination = 0;    /* auto termination */
17043     } else
17044     {
17045         /* Enable manual control with low off / high off. */
17046         if (eep_config.termination == 1)
17047         {
17048             asc_dvc->cfg->termination = TERM_CTL_SEL;
17049 
17050         /* Enable manual control with low off / high on. */
17051         } else if (eep_config.termination == 2)
17052         {
17053             asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
17054 
17055         /* Enable manual control with low on / high on. */
17056         } else if (eep_config.termination == 3)
17057         {
17058             asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
17059         } else
17060         {
17061             /*
17062              * The EEPROM 'termination' field contains a bad value. Use
17063              * automatic termination instead.
17064              */
17065             asc_dvc->cfg->termination = 0;
17066             warn_code |= ASC_WARN_EEPROM_TERMINATION;
17067         }
17068     }
17069 
17070     return warn_code;
17071 }
17072 
17073 /*
17074  * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
17075  * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
17076  * all of this is done.
17077  *
17078  * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
17079  *
17080  * For a non-fatal error return a warning code. If there are no warnings
17081  * then 0 is returned.
17082  *
17083  * Note: Chip is stopped on entry.
17084  */
ASC_INITFUNC(STATIC int,AdvInitFrom38C0800EEP (ADV_DVC_VAR * asc_dvc))17085 ASC_INITFUNC(
17086 STATIC int,
17087 AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
17088 )
17089 {
17090     AdvPortAddr              iop_base;
17091     ushort                   warn_code;
17092     ADVEEP_38C0800_CONFIG    eep_config;
17093     int                      i;
17094     uchar                    tid, termination;
17095     ushort                   sdtr_speed = 0;
17096 
17097     iop_base = asc_dvc->iop_base;
17098 
17099     warn_code = 0;
17100 
17101     /*
17102      * Read the board's EEPROM configuration.
17103      *
17104      * Set default values if a bad checksum is found.
17105      */
17106     if (AdvGet38C0800EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
17107     {
17108         warn_code |= ASC_WARN_EEPROM_CHKSUM;
17109 
17110         /*
17111          * Set EEPROM default values.
17112          */
17113         for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++)
17114         {
17115             *((uchar *) &eep_config + i) =
17116                 *((uchar *) &Default_38C0800_EEPROM_Config + i);
17117         }
17118 
17119         /*
17120          * Assume the 6 byte board serial number that was read
17121          * from EEPROM is correct even if the EEPROM checksum
17122          * failed.
17123          */
17124         eep_config.serial_number_word3 =
17125             AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
17126 
17127         eep_config.serial_number_word2 =
17128             AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
17129 
17130         eep_config.serial_number_word1 =
17131             AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
17132 
17133         AdvSet38C0800EEPConfig(iop_base, &eep_config);
17134     }
17135     /*
17136      * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
17137      * EEPROM configuration that was read.
17138      *
17139      * This is the mapping of EEPROM fields to Adv Library fields.
17140      */
17141     asc_dvc->wdtr_able = eep_config.wdtr_able;
17142     asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
17143     asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
17144     asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
17145     asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
17146     asc_dvc->tagqng_able = eep_config.tagqng_able;
17147     asc_dvc->cfg->disc_enable = eep_config.disc_enable;
17148     asc_dvc->max_host_qng = eep_config.max_host_qng;
17149     asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
17150     asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
17151     asc_dvc->start_motor = eep_config.start_motor;
17152     asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
17153     asc_dvc->bios_ctrl = eep_config.bios_ctrl;
17154     asc_dvc->no_scam = eep_config.scam_tolerant;
17155     asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
17156     asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
17157     asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
17158 
17159     /*
17160      * For every Target ID if any of its 'sdtr_speed[1234]' bits
17161      * are set, then set an 'sdtr_able' bit for it.
17162      */
17163     asc_dvc->sdtr_able = 0;
17164     for (tid = 0; tid <= ADV_MAX_TID; tid++)
17165     {
17166         if (tid == 0)
17167         {
17168             sdtr_speed = asc_dvc->sdtr_speed1;
17169         } else if (tid == 4)
17170         {
17171             sdtr_speed = asc_dvc->sdtr_speed2;
17172         } else if (tid == 8)
17173         {
17174             sdtr_speed = asc_dvc->sdtr_speed3;
17175         } else if (tid == 12)
17176         {
17177             sdtr_speed = asc_dvc->sdtr_speed4;
17178         }
17179         if (sdtr_speed & ADV_MAX_TID)
17180         {
17181             asc_dvc->sdtr_able |= (1 << tid);
17182         }
17183         sdtr_speed >>= 4;
17184     }
17185 
17186     /*
17187      * Set the host maximum queuing (max. 253, min. 16) and the per device
17188      * maximum queuing (max. 63, min. 4).
17189      */
17190     if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
17191     {
17192         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17193     } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
17194     {
17195         /* If the value is zero, assume it is uninitialized. */
17196         if (eep_config.max_host_qng == 0)
17197         {
17198             eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17199         } else
17200         {
17201             eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
17202         }
17203     }
17204 
17205     if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
17206     {
17207         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17208     } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
17209     {
17210         /* If the value is zero, assume it is uninitialized. */
17211         if (eep_config.max_dvc_qng == 0)
17212         {
17213             eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17214         } else
17215         {
17216             eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
17217         }
17218     }
17219 
17220     /*
17221      * If 'max_dvc_qng' is greater than 'max_host_qng', then
17222      * set 'max_dvc_qng' to 'max_host_qng'.
17223      */
17224     if (eep_config.max_dvc_qng > eep_config.max_host_qng)
17225     {
17226         eep_config.max_dvc_qng = eep_config.max_host_qng;
17227     }
17228 
17229     /*
17230      * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
17231      * values based on possibly adjusted EEPROM values.
17232      */
17233     asc_dvc->max_host_qng = eep_config.max_host_qng;
17234     asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
17235 
17236     /*
17237      * If the EEPROM 'termination' field is set to automatic (0), then set
17238      * the ADV_DVC_CFG 'termination' field to automatic also.
17239      *
17240      * If the termination is specified with a non-zero 'termination'
17241      * value check that a legal value is set and set the ADV_DVC_CFG
17242      * 'termination' field appropriately.
17243      */
17244     if (eep_config.termination_se == 0)
17245     {
17246         termination = 0;                         /* auto termination for SE */
17247     } else
17248     {
17249         /* Enable manual control with low off / high off. */
17250         if (eep_config.termination_se == 1)
17251         {
17252             termination = 0;
17253 
17254         /* Enable manual control with low off / high on. */
17255         } else if (eep_config.termination_se == 2)
17256         {
17257             termination = TERM_SE_HI;
17258 
17259         /* Enable manual control with low on / high on. */
17260         } else if (eep_config.termination_se == 3)
17261         {
17262             termination = TERM_SE;
17263         } else
17264         {
17265             /*
17266              * The EEPROM 'termination_se' field contains a bad value.
17267              * Use automatic termination instead.
17268              */
17269             termination = 0;
17270             warn_code |= ASC_WARN_EEPROM_TERMINATION;
17271         }
17272     }
17273 
17274     if (eep_config.termination_lvd == 0)
17275     {
17276         asc_dvc->cfg->termination = termination; /* auto termination for LVD */
17277     } else
17278     {
17279         /* Enable manual control with low off / high off. */
17280         if (eep_config.termination_lvd == 1)
17281         {
17282             asc_dvc->cfg->termination = termination;
17283 
17284         /* Enable manual control with low off / high on. */
17285         } else if (eep_config.termination_lvd == 2)
17286         {
17287             asc_dvc->cfg->termination = termination | TERM_LVD_HI;
17288 
17289         /* Enable manual control with low on / high on. */
17290         } else if (eep_config.termination_lvd == 3)
17291         {
17292             asc_dvc->cfg->termination =
17293                 termination | TERM_LVD;
17294         } else
17295         {
17296             /*
17297              * The EEPROM 'termination_lvd' field contains a bad value.
17298              * Use automatic termination instead.
17299              */
17300             asc_dvc->cfg->termination = termination;
17301             warn_code |= ASC_WARN_EEPROM_TERMINATION;
17302         }
17303     }
17304 
17305     return warn_code;
17306 }
17307 
17308 /*
17309  * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
17310  * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
17311  * all of this is done.
17312  *
17313  * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
17314  *
17315  * For a non-fatal error return a warning code. If there are no warnings
17316  * then 0 is returned.
17317  *
17318  * Note: Chip is stopped on entry.
17319  */
ASC_INITFUNC(STATIC int,AdvInitFrom38C1600EEP (ADV_DVC_VAR * asc_dvc))17320 ASC_INITFUNC(
17321 STATIC int,
17322 AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
17323 )
17324 {
17325     AdvPortAddr              iop_base;
17326     ushort                   warn_code;
17327     ADVEEP_38C1600_CONFIG    eep_config;
17328     int                      i;
17329     uchar                    tid, termination;
17330     ushort                   sdtr_speed = 0;
17331 
17332     iop_base = asc_dvc->iop_base;
17333 
17334     warn_code = 0;
17335 
17336     /*
17337      * Read the board's EEPROM configuration.
17338      *
17339      * Set default values if a bad checksum is found.
17340      */
17341     if (AdvGet38C1600EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
17342     {
17343         warn_code |= ASC_WARN_EEPROM_CHKSUM;
17344 
17345         /*
17346          * Set EEPROM default values.
17347          */
17348         for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++)
17349         {
17350             if (i == 1 && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) != 0)
17351             {
17352                 /*
17353                  * Set Function 1 EEPROM Word 0 MSB
17354                  *
17355                  * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11)
17356                  * EEPROM bits.
17357                  *
17358                  * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and
17359                  * old Mac system booting problem. The Expansion ROM must
17360                  * be disabled in Function 1 for these systems.
17361                  *
17362                  */
17363                 *((uchar *) &eep_config + i) =
17364                 ((*((uchar *) &Default_38C1600_EEPROM_Config + i)) &
17365                     (~(((ADV_EEPROM_BIOS_ENABLE | ADV_EEPROM_INTAB) >> 8) &
17366                      0xFF)));
17367 
17368                 /*
17369                  * Set the INTAB (bit 11) if the GPIO 0 input indicates
17370                  * the Function 1 interrupt line is wired to INTA.
17371                  *
17372                  * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
17373                  *   1 - Function 1 interrupt line wired to INT A.
17374                  *   0 - Function 1 interrupt line wired to INT B.
17375                  *
17376                  * Note: Adapter boards always have Function 0 wired to INTA.
17377                  * Put all 5 GPIO bits in input mode and then read
17378                  * their input values.
17379                  */
17380                 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
17381                 if (AdvReadByteRegister(iop_base, IOPB_GPIO_DATA) & 0x01)
17382                 {
17383                     /* Function 1 interrupt wired to INTA; Set EEPROM bit. */
17384                 *((uchar *) &eep_config + i) |=
17385                     ((ADV_EEPROM_INTAB >> 8) & 0xFF);
17386                 }
17387             }
17388             else
17389             {
17390                 *((uchar *) &eep_config + i) =
17391                 *((uchar *) &Default_38C1600_EEPROM_Config + i);
17392             }
17393         }
17394 
17395         /*
17396          * Assume the 6 byte board serial number that was read
17397          * from EEPROM is correct even if the EEPROM checksum
17398          * failed.
17399          */
17400         eep_config.serial_number_word3 =
17401             AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
17402 
17403         eep_config.serial_number_word2 =
17404             AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
17405 
17406         eep_config.serial_number_word1 =
17407             AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
17408 
17409         AdvSet38C1600EEPConfig(iop_base, &eep_config);
17410     }
17411 
17412     /*
17413      * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
17414      * EEPROM configuration that was read.
17415      *
17416      * This is the mapping of EEPROM fields to Adv Library fields.
17417      */
17418     asc_dvc->wdtr_able = eep_config.wdtr_able;
17419     asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
17420     asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
17421     asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
17422     asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
17423     asc_dvc->ppr_able = 0;
17424     asc_dvc->tagqng_able = eep_config.tagqng_able;
17425     asc_dvc->cfg->disc_enable = eep_config.disc_enable;
17426     asc_dvc->max_host_qng = eep_config.max_host_qng;
17427     asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
17428     asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
17429     asc_dvc->start_motor = eep_config.start_motor;
17430     asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
17431     asc_dvc->bios_ctrl = eep_config.bios_ctrl;
17432     asc_dvc->no_scam = eep_config.scam_tolerant;
17433 
17434     /*
17435      * For every Target ID if any of its 'sdtr_speed[1234]' bits
17436      * are set, then set an 'sdtr_able' bit for it.
17437      */
17438     asc_dvc->sdtr_able = 0;
17439     for (tid = 0; tid <= ASC_MAX_TID; tid++)
17440     {
17441         if (tid == 0)
17442         {
17443             sdtr_speed = asc_dvc->sdtr_speed1;
17444         } else if (tid == 4)
17445         {
17446             sdtr_speed = asc_dvc->sdtr_speed2;
17447         } else if (tid == 8)
17448         {
17449             sdtr_speed = asc_dvc->sdtr_speed3;
17450         } else if (tid == 12)
17451         {
17452             sdtr_speed = asc_dvc->sdtr_speed4;
17453         }
17454         if (sdtr_speed & ASC_MAX_TID)
17455         {
17456             asc_dvc->sdtr_able |= (1 << tid);
17457         }
17458         sdtr_speed >>= 4;
17459     }
17460 
17461     /*
17462      * Set the host maximum queuing (max. 253, min. 16) and the per device
17463      * maximum queuing (max. 63, min. 4).
17464      */
17465     if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
17466     {
17467         eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17468     } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
17469     {
17470         /* If the value is zero, assume it is uninitialized. */
17471         if (eep_config.max_host_qng == 0)
17472         {
17473             eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17474         } else
17475         {
17476             eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
17477         }
17478     }
17479 
17480     if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
17481     {
17482         eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17483     } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
17484     {
17485         /* If the value is zero, assume it is uninitialized. */
17486         if (eep_config.max_dvc_qng == 0)
17487         {
17488             eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17489         } else
17490         {
17491             eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
17492         }
17493     }
17494 
17495     /*
17496      * If 'max_dvc_qng' is greater than 'max_host_qng', then
17497      * set 'max_dvc_qng' to 'max_host_qng'.
17498      */
17499     if (eep_config.max_dvc_qng > eep_config.max_host_qng)
17500     {
17501         eep_config.max_dvc_qng = eep_config.max_host_qng;
17502     }
17503 
17504     /*
17505      * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
17506      * values based on possibly adjusted EEPROM values.
17507      */
17508     asc_dvc->max_host_qng = eep_config.max_host_qng;
17509     asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
17510 
17511     /*
17512      * If the EEPROM 'termination' field is set to automatic (0), then set
17513      * the ASC_DVC_CFG 'termination' field to automatic also.
17514      *
17515      * If the termination is specified with a non-zero 'termination'
17516      * value check that a legal value is set and set the ASC_DVC_CFG
17517      * 'termination' field appropriately.
17518      */
17519     if (eep_config.termination_se == 0)
17520     {
17521         termination = 0;                         /* auto termination for SE */
17522     } else
17523     {
17524         /* Enable manual control with low off / high off. */
17525         if (eep_config.termination_se == 1)
17526         {
17527             termination = 0;
17528 
17529         /* Enable manual control with low off / high on. */
17530         } else if (eep_config.termination_se == 2)
17531         {
17532             termination = TERM_SE_HI;
17533 
17534         /* Enable manual control with low on / high on. */
17535         } else if (eep_config.termination_se == 3)
17536         {
17537             termination = TERM_SE;
17538         } else
17539         {
17540             /*
17541              * The EEPROM 'termination_se' field contains a bad value.
17542              * Use automatic termination instead.
17543              */
17544             termination = 0;
17545             warn_code |= ASC_WARN_EEPROM_TERMINATION;
17546         }
17547     }
17548 
17549     if (eep_config.termination_lvd == 0)
17550     {
17551         asc_dvc->cfg->termination = termination; /* auto termination for LVD */
17552     } else
17553     {
17554         /* Enable manual control with low off / high off. */
17555         if (eep_config.termination_lvd == 1)
17556         {
17557             asc_dvc->cfg->termination = termination;
17558 
17559         /* Enable manual control with low off / high on. */
17560         } else if (eep_config.termination_lvd == 2)
17561         {
17562             asc_dvc->cfg->termination = termination | TERM_LVD_HI;
17563 
17564         /* Enable manual control with low on / high on. */
17565         } else if (eep_config.termination_lvd == 3)
17566         {
17567             asc_dvc->cfg->termination =
17568                 termination | TERM_LVD;
17569         } else
17570         {
17571             /*
17572              * The EEPROM 'termination_lvd' field contains a bad value.
17573              * Use automatic termination instead.
17574              */
17575             asc_dvc->cfg->termination = termination;
17576             warn_code |= ASC_WARN_EEPROM_TERMINATION;
17577         }
17578     }
17579 
17580     return warn_code;
17581 }
17582 
17583 /*
17584  * Read EEPROM configuration into the specified buffer.
17585  *
17586  * Return a checksum based on the EEPROM configuration read.
17587  */
ASC_INITFUNC(STATIC ushort,AdvGet3550EEPConfig (AdvPortAddr iop_base,ADVEEP_3550_CONFIG * cfg_buf))17588 ASC_INITFUNC(
17589 STATIC ushort,
17590 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
17591 )
17592 {
17593     ushort              wval, chksum;
17594     ushort              *wbuf;
17595     int                 eep_addr;
17596     ushort              *charfields;
17597 
17598     charfields = (ushort *) &ADVEEP_3550_Config_Field_IsChar;
17599     wbuf = (ushort *) cfg_buf;
17600     chksum = 0;
17601 
17602     for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17603          eep_addr < ADV_EEP_DVC_CFG_END;
17604          eep_addr++, wbuf++)
17605     {
17606         wval = AdvReadEEPWord(iop_base, eep_addr);
17607         chksum += wval; /* Checksum is calculated from word values. */
17608         if (*charfields++) {
17609             *wbuf = le16_to_cpu(wval);
17610         } else {
17611             *wbuf = wval;
17612         }
17613     }
17614     /* Read checksum word. */
17615     *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17616     wbuf++; charfields++;
17617 
17618     /* Read rest of EEPROM not covered by the checksum. */
17619     for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17620          eep_addr < ADV_EEP_MAX_WORD_ADDR;
17621          eep_addr++, wbuf++)
17622     {
17623         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17624         if (*charfields++) {
17625             *wbuf = le16_to_cpu(*wbuf);
17626         }
17627     }
17628     return chksum;
17629 }
17630 
17631 /*
17632  * Read EEPROM configuration into the specified buffer.
17633  *
17634  * Return a checksum based on the EEPROM configuration read.
17635  */
ASC_INITFUNC(STATIC ushort,AdvGet38C0800EEPConfig (AdvPortAddr iop_base,ADVEEP_38C0800_CONFIG * cfg_buf))17636 ASC_INITFUNC(
17637 STATIC ushort,
17638 AdvGet38C0800EEPConfig(AdvPortAddr iop_base,
17639                        ADVEEP_38C0800_CONFIG *cfg_buf)
17640 )
17641 {
17642     ushort              wval, chksum;
17643     ushort              *wbuf;
17644     int                 eep_addr;
17645     ushort              *charfields;
17646 
17647     charfields = (ushort *) &ADVEEP_38C0800_Config_Field_IsChar;
17648     wbuf = (ushort *) cfg_buf;
17649     chksum = 0;
17650 
17651     for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17652          eep_addr < ADV_EEP_DVC_CFG_END;
17653          eep_addr++, wbuf++)
17654     {
17655         wval = AdvReadEEPWord(iop_base, eep_addr);
17656         chksum += wval; /* Checksum is calculated from word values. */
17657         if (*charfields++) {
17658             *wbuf = le16_to_cpu(wval);
17659         } else {
17660             *wbuf = wval;
17661         }
17662     }
17663     /* Read checksum word. */
17664     *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17665     wbuf++; charfields++;
17666 
17667     /* Read rest of EEPROM not covered by the checksum. */
17668     for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17669          eep_addr < ADV_EEP_MAX_WORD_ADDR;
17670          eep_addr++, wbuf++)
17671     {
17672         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17673         if (*charfields++) {
17674             *wbuf = le16_to_cpu(*wbuf);
17675         }
17676     }
17677     return chksum;
17678 }
17679 
17680 /*
17681  * Read EEPROM configuration into the specified buffer.
17682  *
17683  * Return a checksum based on the EEPROM configuration read.
17684  */
ASC_INITFUNC(STATIC ushort,AdvGet38C1600EEPConfig (AdvPortAddr iop_base,ADVEEP_38C1600_CONFIG * cfg_buf))17685 ASC_INITFUNC(
17686 STATIC ushort,
17687 AdvGet38C1600EEPConfig(AdvPortAddr iop_base,
17688                        ADVEEP_38C1600_CONFIG *cfg_buf)
17689 )
17690 {
17691     ushort              wval, chksum;
17692     ushort              *wbuf;
17693     int                 eep_addr;
17694     ushort              *charfields;
17695 
17696     charfields = (ushort*) &ADVEEP_38C1600_Config_Field_IsChar;
17697     wbuf = (ushort *) cfg_buf;
17698     chksum = 0;
17699 
17700     for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17701          eep_addr < ADV_EEP_DVC_CFG_END;
17702          eep_addr++, wbuf++)
17703     {
17704         wval = AdvReadEEPWord(iop_base, eep_addr);
17705         chksum += wval; /* Checksum is calculated from word values. */
17706         if (*charfields++) {
17707             *wbuf = le16_to_cpu(wval);
17708         } else {
17709             *wbuf = wval;
17710         }
17711     }
17712     /* Read checksum word. */
17713     *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17714     wbuf++; charfields++;
17715 
17716     /* Read rest of EEPROM not covered by the checksum. */
17717     for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17718          eep_addr < ADV_EEP_MAX_WORD_ADDR;
17719          eep_addr++, wbuf++)
17720     {
17721         *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17722         if (*charfields++) {
17723             *wbuf = le16_to_cpu(*wbuf);
17724         }
17725     }
17726     return chksum;
17727 }
17728 
17729 /*
17730  * Read the EEPROM from specified location
17731  */
ASC_INITFUNC(STATIC ushort,AdvReadEEPWord (AdvPortAddr iop_base,int eep_word_addr))17732 ASC_INITFUNC(
17733 STATIC ushort,
17734 AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
17735 )
17736 {
17737     AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
17738         ASC_EEP_CMD_READ | eep_word_addr);
17739     AdvWaitEEPCmd(iop_base);
17740     return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
17741 }
17742 
17743 /*
17744  * Wait for EEPROM command to complete
17745  */
ASC_INITFUNC(STATIC void,AdvWaitEEPCmd (AdvPortAddr iop_base))17746 ASC_INITFUNC(
17747 STATIC void,
17748 AdvWaitEEPCmd(AdvPortAddr iop_base)
17749 )
17750 {
17751     int eep_delay_ms;
17752 
17753     for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++)
17754     {
17755         if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE)
17756         {
17757             break;
17758         }
17759         DvcSleepMilliSecond(1);
17760     }
17761     if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == 0)
17762     {
17763         ASC_ASSERT(0);
17764     }
17765     return;
17766 }
17767 
17768 /*
17769  * Write the EEPROM from 'cfg_buf'.
17770  */
17771 void
AdvSet3550EEPConfig(AdvPortAddr iop_base,ADVEEP_3550_CONFIG * cfg_buf)17772 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
17773 {
17774     ushort *wbuf;
17775     ushort addr, chksum;
17776     ushort *charfields;
17777 
17778     wbuf = (ushort *) cfg_buf;
17779     charfields = (ushort *) &ADVEEP_3550_Config_Field_IsChar;
17780     chksum = 0;
17781 
17782     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17783     AdvWaitEEPCmd(iop_base);
17784 
17785     /*
17786      * Write EEPROM from word 0 to word 20.
17787      */
17788     for (addr = ADV_EEP_DVC_CFG_BEGIN;
17789          addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17790     {
17791         ushort word;
17792 
17793         if (*charfields++) {
17794             word = cpu_to_le16(*wbuf);
17795         } else {
17796             word = *wbuf;
17797         }
17798         chksum += *wbuf; /* Checksum is calculated from word values. */
17799         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17800         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17801         AdvWaitEEPCmd(iop_base);
17802         DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17803     }
17804 
17805     /*
17806      * Write EEPROM checksum at word 21.
17807      */
17808     AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17809     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17810     AdvWaitEEPCmd(iop_base);
17811     wbuf++; charfields++;
17812 
17813     /*
17814      * Write EEPROM OEM name at words 22 to 29.
17815      */
17816     for (addr = ADV_EEP_DVC_CTL_BEGIN;
17817          addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17818     {
17819         ushort word;
17820 
17821         if (*charfields++) {
17822             word = cpu_to_le16(*wbuf);
17823         } else {
17824             word = *wbuf;
17825         }
17826         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17827         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17828         AdvWaitEEPCmd(iop_base);
17829     }
17830     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17831     AdvWaitEEPCmd(iop_base);
17832     return;
17833 }
17834 
17835 /*
17836  * Write the EEPROM from 'cfg_buf'.
17837  */
17838 void
AdvSet38C0800EEPConfig(AdvPortAddr iop_base,ADVEEP_38C0800_CONFIG * cfg_buf)17839 AdvSet38C0800EEPConfig(AdvPortAddr iop_base,
17840                        ADVEEP_38C0800_CONFIG *cfg_buf)
17841 {
17842     ushort *wbuf;
17843     ushort *charfields;
17844     ushort addr, chksum;
17845 
17846     wbuf = (ushort *) cfg_buf;
17847     charfields = (ushort *) &ADVEEP_38C0800_Config_Field_IsChar;
17848     chksum = 0;
17849 
17850     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17851     AdvWaitEEPCmd(iop_base);
17852 
17853     /*
17854      * Write EEPROM from word 0 to word 20.
17855      */
17856     for (addr = ADV_EEP_DVC_CFG_BEGIN;
17857          addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17858     {
17859         ushort word;
17860 
17861         if (*charfields++) {
17862             word = cpu_to_le16(*wbuf);
17863         } else {
17864             word = *wbuf;
17865         }
17866         chksum += *wbuf; /* Checksum is calculated from word values. */
17867         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17868         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17869         AdvWaitEEPCmd(iop_base);
17870         DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17871     }
17872 
17873     /*
17874      * Write EEPROM checksum at word 21.
17875      */
17876     AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17877     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17878     AdvWaitEEPCmd(iop_base);
17879     wbuf++; charfields++;
17880 
17881     /*
17882      * Write EEPROM OEM name at words 22 to 29.
17883      */
17884     for (addr = ADV_EEP_DVC_CTL_BEGIN;
17885          addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17886     {
17887         ushort word;
17888 
17889         if (*charfields++) {
17890             word = cpu_to_le16(*wbuf);
17891         } else {
17892             word = *wbuf;
17893         }
17894         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17895         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17896         AdvWaitEEPCmd(iop_base);
17897     }
17898     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17899     AdvWaitEEPCmd(iop_base);
17900     return;
17901 }
17902 
17903 /*
17904  * Write the EEPROM from 'cfg_buf'.
17905  */
17906 void
AdvSet38C1600EEPConfig(AdvPortAddr iop_base,ADVEEP_38C1600_CONFIG * cfg_buf)17907 AdvSet38C1600EEPConfig(AdvPortAddr iop_base,
17908                        ADVEEP_38C1600_CONFIG *cfg_buf)
17909 {
17910     ushort              *wbuf;
17911     ushort              *charfields;
17912     ushort              addr, chksum;
17913 
17914     wbuf = (ushort *) cfg_buf;
17915     charfields = (ushort *) &ADVEEP_38C1600_Config_Field_IsChar;
17916     chksum = 0;
17917 
17918     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17919     AdvWaitEEPCmd(iop_base);
17920 
17921     /*
17922      * Write EEPROM from word 0 to word 20.
17923      */
17924     for (addr = ADV_EEP_DVC_CFG_BEGIN;
17925          addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17926     {
17927         ushort word;
17928 
17929         if (*charfields++) {
17930             word = cpu_to_le16(*wbuf);
17931         } else {
17932             word = *wbuf;
17933         }
17934         chksum += *wbuf; /* Checksum is calculated from word values. */
17935         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17936         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17937         AdvWaitEEPCmd(iop_base);
17938         DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17939     }
17940 
17941     /*
17942      * Write EEPROM checksum at word 21.
17943      */
17944     AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17945     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17946     AdvWaitEEPCmd(iop_base);
17947     wbuf++; charfields++;
17948 
17949     /*
17950      * Write EEPROM OEM name at words 22 to 29.
17951      */
17952     for (addr = ADV_EEP_DVC_CTL_BEGIN;
17953          addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17954     {
17955         ushort word;
17956 
17957         if (*charfields++) {
17958             word = cpu_to_le16(*wbuf);
17959         } else {
17960             word = *wbuf;
17961         }
17962         AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17963         AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17964         AdvWaitEEPCmd(iop_base);
17965     }
17966     AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17967     AdvWaitEEPCmd(iop_base);
17968     return;
17969 }
17970 
17971 /* a_advlib.c */
17972 /*
17973  * AdvExeScsiQueue() - Send a request to the RISC microcode program.
17974  *
17975  *   Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
17976  *   add the carrier to the ICQ (Initiator Command Queue), and tickle the
17977  *   RISC to notify it a new command is ready to be executed.
17978  *
17979  * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
17980  * set to SCSI_MAX_RETRY.
17981  *
17982  * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
17983  * for DMA addresses or math operations are byte swapped to little-endian
17984  * order.
17985  *
17986  * Return:
17987  *      ADV_SUCCESS(1) - The request was successfully queued.
17988  *      ADV_BUSY(0) -    Resource unavailable; Retry again after pending
17989  *                       request completes.
17990  *      ADV_ERROR(-1) -  Invalid ADV_SCSI_REQ_Q request structure
17991  *                       host IC error.
17992  */
17993 STATIC int
AdvExeScsiQueue(ADV_DVC_VAR * asc_dvc,ADV_SCSI_REQ_Q * scsiq)17994 AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc,
17995                 ADV_SCSI_REQ_Q *scsiq)
17996 {
17997     ulong                  last_int_level;
17998     AdvPortAddr            iop_base;
17999     ADV_DCNT               req_size;
18000     ADV_PADDR              req_paddr;
18001     ADV_CARR_T             *new_carrp;
18002 
18003     ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
18004 
18005     /*
18006      * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
18007      */
18008     if (scsiq->target_id > ADV_MAX_TID)
18009     {
18010         scsiq->host_status = QHSTA_M_INVALID_DEVICE;
18011         scsiq->done_status = QD_WITH_ERROR;
18012         return ADV_ERROR;
18013     }
18014 
18015     iop_base = asc_dvc->iop_base;
18016 
18017     last_int_level = DvcEnterCritical();
18018 
18019     /*
18020      * Allocate a carrier ensuring at least one carrier always
18021      * remains on the freelist and initialize fields.
18022      */
18023     if ((new_carrp = asc_dvc->carr_freelist) == NULL)
18024     {
18025        DvcLeaveCritical(last_int_level);
18026        return ADV_BUSY;
18027     }
18028     asc_dvc->carr_freelist = (ADV_CARR_T *)
18029         ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
18030     asc_dvc->carr_pending_cnt++;
18031 
18032     /*
18033      * Set the carrier to be a stopper by setting 'next_vpa'
18034      * to the stopper value. The current stopper will be changed
18035      * below to point to the new stopper.
18036      */
18037     new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
18038 
18039     /*
18040      * Clear the ADV_SCSI_REQ_Q done flag.
18041      */
18042     scsiq->a_flag &= ~ADV_SCSIQ_DONE;
18043 
18044     req_size = sizeof(ADV_SCSI_REQ_Q);
18045     req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *) scsiq,
18046         (ADV_SDCNT *) &req_size, ADV_IS_SCSIQ_FLAG);
18047 
18048     ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
18049     ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
18050 
18051     /* Wait for assertion before making little-endian */
18052     req_paddr = cpu_to_le32(req_paddr);
18053 
18054     /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
18055     scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
18056     scsiq->scsiq_rptr = req_paddr;
18057 
18058     scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
18059     /*
18060      * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
18061      * order during initialization.
18062      */
18063     scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
18064 
18065    /*
18066     * Use the current stopper to send the ADV_SCSI_REQ_Q command to
18067     * the microcode. The newly allocated stopper will become the new
18068     * stopper.
18069     */
18070     asc_dvc->icq_sp->areq_vpa = req_paddr;
18071 
18072     /*
18073      * Set the 'next_vpa' pointer for the old stopper to be the
18074      * physical address of the new stopper. The RISC can only
18075      * follow physical addresses.
18076      */
18077     asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
18078 
18079     /*
18080      * Set the host adapter stopper pointer to point to the new carrier.
18081      */
18082     asc_dvc->icq_sp = new_carrp;
18083 
18084     if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
18085         asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
18086     {
18087         /*
18088          * Tickle the RISC to tell it to read its Command Queue Head pointer.
18089          */
18090         AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
18091         if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
18092         {
18093             /*
18094              * Clear the tickle value. In the ASC-3550 the RISC flag
18095              * command 'clr_tickle_a' does not work unless the host
18096              * value is cleared.
18097              */
18098             AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
18099         }
18100     } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
18101     {
18102         /*
18103          * Notify the RISC a carrier is ready by writing the physical
18104          * address of the new carrier stopper to the COMMA register.
18105          */
18106         AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
18107                 le32_to_cpu(new_carrp->carr_pa));
18108     }
18109 
18110     DvcLeaveCritical(last_int_level);
18111 
18112     return ADV_SUCCESS;
18113 }
18114 
18115 /*
18116  * Reset SCSI Bus and purge all outstanding requests.
18117  *
18118  * Return Value:
18119  *      ADV_TRUE(1) -   All requests are purged and SCSI Bus is reset.
18120  *      ADV_FALSE(0) -  Microcode command failed.
18121  *      ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
18122  *                      may be hung which requires driver recovery.
18123  */
18124 STATIC int
AdvResetSB(ADV_DVC_VAR * asc_dvc)18125 AdvResetSB(ADV_DVC_VAR *asc_dvc)
18126 {
18127     int         status;
18128 
18129     /*
18130      * Send the SCSI Bus Reset idle start idle command which asserts
18131      * the SCSI Bus Reset signal.
18132      */
18133     status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_START, 0L);
18134     if (status != ADV_TRUE)
18135     {
18136         return status;
18137     }
18138 
18139     /*
18140      * Delay for the specified SCSI Bus Reset hold time.
18141      *
18142      * The hold time delay is done on the host because the RISC has no
18143      * microsecond accurate timer.
18144      */
18145     DvcDelayMicroSecond(asc_dvc, (ushort) ASC_SCSI_RESET_HOLD_TIME_US);
18146 
18147     /*
18148      * Send the SCSI Bus Reset end idle command which de-asserts
18149      * the SCSI Bus Reset signal and purges any pending requests.
18150      */
18151     status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_END, 0L);
18152     if (status != ADV_TRUE)
18153     {
18154         return status;
18155     }
18156 
18157     DvcSleepMilliSecond((ADV_DCNT) asc_dvc->scsi_reset_wait * 1000);
18158 
18159     return status;
18160 }
18161 
18162 /*
18163  * Reset chip and SCSI Bus.
18164  *
18165  * Return Value:
18166  *      ADV_TRUE(1) -   Chip re-initialization and SCSI Bus Reset successful.
18167  *      ADV_FALSE(0) -  Chip re-initialization and SCSI Bus Reset failure.
18168  */
18169 STATIC int
AdvResetChipAndSB(ADV_DVC_VAR * asc_dvc)18170 AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
18171 {
18172     int         status;
18173     ushort      wdtr_able, sdtr_able, tagqng_able;
18174     ushort      ppr_able = 0;
18175     uchar       tid, max_cmd[ADV_MAX_TID + 1];
18176     AdvPortAddr iop_base;
18177     ushort      bios_sig;
18178 
18179     iop_base = asc_dvc->iop_base;
18180 
18181     /*
18182      * Save current per TID negotiated values.
18183      */
18184     AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
18185     AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
18186     if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
18187     {
18188         AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
18189     }
18190     AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
18191     for (tid = 0; tid <= ADV_MAX_TID; tid++)
18192     {
18193         AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
18194             max_cmd[tid]);
18195     }
18196 
18197     /*
18198      * Force the AdvInitAsc3550/38C0800Driver() function to
18199      * perform a SCSI Bus Reset by clearing the BIOS signature word.
18200      * The initialization functions assumes a SCSI Bus Reset is not
18201      * needed if the BIOS signature word is present.
18202      */
18203     AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
18204     AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
18205 
18206     /*
18207      * Stop chip and reset it.
18208      */
18209     AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
18210     AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
18211     DvcSleepMilliSecond(100);
18212     AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG);
18213 
18214     /*
18215      * Reset Adv Library error code, if any, and try
18216      * re-initializing the chip.
18217      */
18218     asc_dvc->err_code = 0;
18219     if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
18220     {
18221         status = AdvInitAsc38C1600Driver(asc_dvc);
18222     }
18223     else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
18224     {
18225         status = AdvInitAsc38C0800Driver(asc_dvc);
18226     } else
18227     {
18228         status = AdvInitAsc3550Driver(asc_dvc);
18229     }
18230 
18231     /* Translate initialization return value to status value. */
18232     if (status == 0)
18233     {
18234         status = ADV_TRUE;
18235     } else
18236     {
18237         status = ADV_FALSE;
18238     }
18239 
18240     /*
18241      * Restore the BIOS signature word.
18242      */
18243     AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
18244 
18245     /*
18246      * Restore per TID negotiated values.
18247      */
18248     AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
18249     AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
18250     if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
18251     {
18252         AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
18253     }
18254     AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
18255     for (tid = 0; tid <= ADV_MAX_TID; tid++)
18256     {
18257         AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
18258             max_cmd[tid]);
18259     }
18260 
18261     return status;
18262 }
18263 
18264 /*
18265  * Adv Library Interrupt Service Routine
18266  *
18267  *  This function is called by a driver's interrupt service routine.
18268  *  The function disables and re-enables interrupts.
18269  *
18270  *  When a microcode idle command is completed, the ADV_DVC_VAR
18271  *  'idle_cmd_done' field is set to ADV_TRUE.
18272  *
18273  *  Note: AdvISR() can be called when interrupts are disabled or even
18274  *  when there is no hardware interrupt condition present. It will
18275  *  always check for completed idle commands and microcode requests.
18276  *  This is an important feature that shouldn't be changed because it
18277  *  allows commands to be completed from polling mode loops.
18278  *
18279  * Return:
18280  *   ADV_TRUE(1) - interrupt was pending
18281  *   ADV_FALSE(0) - no interrupt was pending
18282  */
18283 STATIC int
AdvISR(ADV_DVC_VAR * asc_dvc)18284 AdvISR(ADV_DVC_VAR *asc_dvc)
18285 {
18286     AdvPortAddr                 iop_base;
18287     uchar                       int_stat;
18288     ushort                      target_bit;
18289     ADV_CARR_T                  *free_carrp;
18290     ADV_VADDR                   irq_next_vpa;
18291     int                         flags;
18292     ADV_SCSI_REQ_Q              *scsiq;
18293 
18294     flags = DvcEnterCritical();
18295 
18296     iop_base = asc_dvc->iop_base;
18297 
18298     /* Reading the register clears the interrupt. */
18299     int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
18300 
18301     if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
18302          ADV_INTR_STATUS_INTRC)) == 0)
18303     {
18304         DvcLeaveCritical(flags);
18305         return ADV_FALSE;
18306     }
18307 
18308     /*
18309      * Notify the driver of an asynchronous microcode condition by
18310      * calling the ADV_DVC_VAR.async_callback function. The function
18311      * is passed the microcode ASC_MC_INTRB_CODE byte value.
18312      */
18313     if (int_stat & ADV_INTR_STATUS_INTRB)
18314     {
18315         uchar intrb_code;
18316 
18317         AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
18318 
18319         if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
18320             asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
18321         {
18322             if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
18323                 asc_dvc->carr_pending_cnt != 0)
18324             {
18325                 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
18326                 if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
18327                 {
18328                     AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
18329                 }
18330             }
18331         }
18332 
18333         if (asc_dvc->async_callback != 0)
18334         {
18335             (*asc_dvc->async_callback)(asc_dvc, intrb_code);
18336         }
18337     }
18338 
18339     /*
18340      * Check if the IRQ stopper carrier contains a completed request.
18341      */
18342     while (((irq_next_vpa =
18343              le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0)
18344     {
18345         /*
18346          * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
18347          * The RISC will have set 'areq_vpa' to a virtual address.
18348          *
18349          * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
18350          * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
18351          * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
18352          * in AdvExeScsiQueue().
18353          */
18354         scsiq = (ADV_SCSI_REQ_Q *)
18355             ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
18356 
18357         /*
18358          * Request finished with good status and the queue was not
18359          * DMAed to host memory by the firmware. Set all status fields
18360          * to indicate good status.
18361          */
18362         if ((irq_next_vpa & ASC_RQ_GOOD) != 0)
18363         {
18364             scsiq->done_status = QD_NO_ERROR;
18365             scsiq->host_status = scsiq->scsi_status = 0;
18366             scsiq->data_cnt = 0L;
18367         }
18368 
18369         /*
18370          * Advance the stopper pointer to the next carrier
18371          * ignoring the lower four bits. Free the previous
18372          * stopper carrier.
18373          */
18374         free_carrp = asc_dvc->irq_sp;
18375         asc_dvc->irq_sp = (ADV_CARR_T *)
18376             ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
18377 
18378         free_carrp->next_vpa =
18379                 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
18380         asc_dvc->carr_freelist = free_carrp;
18381         asc_dvc->carr_pending_cnt--;
18382 
18383         ASC_ASSERT(scsiq != NULL);
18384         target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
18385 
18386         /*
18387          * Clear request microcode control flag.
18388          */
18389         scsiq->cntl = 0;
18390 
18391         /*
18392          * If the command that completed was a SCSI INQUIRY and
18393          * LUN 0 was sent the command, then process the INQUIRY
18394          * command information for the device.
18395          *
18396          * Note: If data returned were either VPD or CmdDt data,
18397          * don't process the INQUIRY command information for
18398          * the device, otherwise may erroneously set *_able bits.
18399          */
18400         if (scsiq->done_status == QD_NO_ERROR &&
18401             scsiq->cdb[0] == SCSICMD_Inquiry &&
18402             scsiq->target_lun == 0 &&
18403             (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
18404                 == ADV_INQ_RTN_STD_INQUIRY_DATA)
18405         {
18406             AdvInquiryHandling(asc_dvc, scsiq);
18407         }
18408 
18409         /*
18410          * Notify the driver of the completed request by passing
18411          * the ADV_SCSI_REQ_Q pointer to its callback function.
18412          */
18413         scsiq->a_flag |= ADV_SCSIQ_DONE;
18414         (*asc_dvc->isr_callback)(asc_dvc, scsiq);
18415         /*
18416          * Note: After the driver callback function is called, 'scsiq'
18417          * can no longer be referenced.
18418          *
18419          * Fall through and continue processing other completed
18420          * requests...
18421          */
18422 
18423         /*
18424          * Disable interrupts again in case the driver inadvertently
18425          * enabled interrupts in its callback function.
18426          *
18427          * The DvcEnterCritical() return value is ignored, because
18428          * the 'flags' saved when AdvISR() was first entered will be
18429          * used to restore the interrupt flag on exit.
18430          */
18431         (void) DvcEnterCritical();
18432     }
18433     DvcLeaveCritical(flags);
18434     return ADV_TRUE;
18435 }
18436 
18437 /*
18438  * Send an idle command to the chip and wait for completion.
18439  *
18440  * Command completion is polled for once per microsecond.
18441  *
18442  * The function can be called from anywhere including an interrupt handler.
18443  * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
18444  * functions to prevent reentrancy.
18445  *
18446  * Return Values:
18447  *   ADV_TRUE - command completed successfully
18448  *   ADV_FALSE - command failed
18449  *   ADV_ERROR - command timed out
18450  */
18451 STATIC int
AdvSendIdleCmd(ADV_DVC_VAR * asc_dvc,ushort idle_cmd,ADV_DCNT idle_cmd_parameter)18452 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
18453                ushort idle_cmd,
18454                ADV_DCNT idle_cmd_parameter)
18455 {
18456     ulong       last_int_level;
18457     int         result;
18458     ADV_DCNT    i, j;
18459     AdvPortAddr iop_base;
18460 
18461     last_int_level = DvcEnterCritical();
18462 
18463     iop_base = asc_dvc->iop_base;
18464 
18465     /*
18466      * Clear the idle command status which is set by the microcode
18467      * to a non-zero value to indicate when the command is completed.
18468      * The non-zero result is one of the IDLE_CMD_STATUS_* values
18469      * defined in a_advlib.h.
18470      */
18471     AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort) 0);
18472 
18473     /*
18474      * Write the idle command value after the idle command parameter
18475      * has been written to avoid a race condition. If the order is not
18476      * followed, the microcode may process the idle command before the
18477      * parameters have been written to LRAM.
18478      */
18479     AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
18480         cpu_to_le32(idle_cmd_parameter));
18481     AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
18482 
18483     /*
18484      * Tickle the RISC to tell it to process the idle command.
18485      */
18486     AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
18487     if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
18488     {
18489         /*
18490          * Clear the tickle value. In the ASC-3550 the RISC flag
18491          * command 'clr_tickle_b' does not work unless the host
18492          * value is cleared.
18493          */
18494         AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
18495     }
18496 
18497     /* Wait for up to 100 millisecond for the idle command to timeout. */
18498     for (i = 0; i < SCSI_WAIT_100_MSEC; i++)
18499     {
18500         /* Poll once each microsecond for command completion. */
18501         for (j = 0; j < SCSI_US_PER_MSEC; j++)
18502         {
18503             AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, result);
18504             if (result != 0)
18505             {
18506                 DvcLeaveCritical(last_int_level);
18507                 return result;
18508             }
18509             DvcDelayMicroSecond(asc_dvc, (ushort) 1);
18510         }
18511     }
18512 
18513     ASC_ASSERT(0); /* The idle command should never timeout. */
18514     DvcLeaveCritical(last_int_level);
18515     return ADV_ERROR;
18516 }
18517 
18518 /*
18519  * Inquiry Information Byte 7 Handling
18520  *
18521  * Handle SCSI Inquiry Command information for a device by setting
18522  * microcode operating variables that affect WDTR, SDTR, and Tag
18523  * Queuing.
18524  */
18525 STATIC void
AdvInquiryHandling(ADV_DVC_VAR * asc_dvc,ADV_SCSI_REQ_Q * scsiq)18526 AdvInquiryHandling(
18527     ADV_DVC_VAR                 *asc_dvc,
18528     ADV_SCSI_REQ_Q              *scsiq)
18529 {
18530     AdvPortAddr                 iop_base;
18531     uchar                       tid;
18532     ADV_SCSI_INQUIRY            *inq;
18533     ushort                      tidmask;
18534     ushort                      cfg_word;
18535 
18536     /*
18537      * AdvInquiryHandling() requires up to INQUIRY information Byte 7
18538      * to be available.
18539      *
18540      * If less than 8 bytes of INQUIRY information were requested or less
18541      * than 8 bytes were transferred, then return. cdb[4] is the request
18542      * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
18543      * microcode to the transfer residual count.
18544      */
18545 
18546     if (scsiq->cdb[4] < 8 ||
18547         (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8)
18548     {
18549         return;
18550     }
18551 
18552     iop_base = asc_dvc->iop_base;
18553     tid = scsiq->target_id;
18554 
18555     inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr;
18556 
18557     /*
18558      * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
18559      */
18560     if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2)
18561     {
18562         return;
18563     } else
18564     {
18565         /*
18566          * INQUIRY Byte 7 Handling
18567          *
18568          * Use a device's INQUIRY byte 7 to determine whether it
18569          * supports WDTR, SDTR, and Tag Queuing. If the feature
18570          * is enabled in the EEPROM and the device supports the
18571          * feature, then enable it in the microcode.
18572          */
18573 
18574         tidmask = ADV_TID_TO_TIDMASK(tid);
18575 
18576         /*
18577          * Wide Transfers
18578          *
18579          * If the EEPROM enabled WDTR for the device and the device
18580          * supports wide bus (16 bit) transfers, then turn on the
18581          * device's 'wdtr_able' bit and write the new value to the
18582          * microcode.
18583          */
18584         if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq))
18585         {
18586             AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
18587             if ((cfg_word & tidmask) == 0)
18588             {
18589                 cfg_word |= tidmask;
18590                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
18591 
18592                 /*
18593                  * Clear the microcode "SDTR negotiation" and "WDTR
18594                  * negotiation" done indicators for the target to cause
18595                  * it to negotiate with the new setting set above.
18596                  * WDTR when accepted causes the target to enter
18597                  * asynchronous mode, so SDTR must be negotiated.
18598                  */
18599                 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18600                 cfg_word &= ~tidmask;
18601                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18602                 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
18603                 cfg_word &= ~tidmask;
18604                 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
18605             }
18606         }
18607 
18608         /*
18609          * Synchronous Transfers
18610          *
18611          * If the EEPROM enabled SDTR for the device and the device
18612          * supports synchronous transfers, then turn on the device's
18613          * 'sdtr_able' bit. Write the new value to the microcode.
18614          */
18615         if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq))
18616         {
18617             AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
18618             if ((cfg_word & tidmask) == 0)
18619             {
18620                 cfg_word |= tidmask;
18621                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
18622 
18623                 /*
18624                  * Clear the microcode "SDTR negotiation" done indicator
18625                  * for the target to cause it to negotiate with the new
18626                  * setting set above.
18627                  */
18628                 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18629                 cfg_word &= ~tidmask;
18630                 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18631             }
18632         }
18633         /*
18634          * If the Inquiry data included enough space for the SPI-3
18635          * Clocking field, then check if DT mode is supported.
18636          */
18637         if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 &&
18638             (scsiq->cdb[4] >= 57 ||
18639             (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57))
18640         {
18641             /*
18642              * PPR (Parallel Protocol Request) Capable
18643              *
18644              * If the device supports DT mode, then it must be PPR capable.
18645              * The PPR message will be used in place of the SDTR and WDTR
18646              * messages to negotiate synchronous speed and offset, transfer
18647              * width, and protocol options.
18648              */
18649             if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY)
18650             {
18651                 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, asc_dvc->ppr_able);
18652                 asc_dvc->ppr_able |= tidmask;
18653                 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, asc_dvc->ppr_able);
18654             }
18655         }
18656 
18657         /*
18658          * If the EEPROM enabled Tag Queuing for the device and the
18659          * device supports Tag Queueing, then turn on the device's
18660          * 'tagqng_enable' bit in the microcode and set the microcode
18661          * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
18662          * value.
18663          *
18664          * Tag Queuing is disabled for the BIOS which runs in polled
18665          * mode and would see no benefit from Tag Queuing. Also by
18666          * disabling Tag Queuing in the BIOS devices with Tag Queuing
18667          * bugs will at least work with the BIOS.
18668          */
18669         if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq))
18670         {
18671             AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
18672             cfg_word |= tidmask;
18673             AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
18674 
18675             AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
18676                 asc_dvc->max_dvc_qng);
18677         }
18678     }
18679 }
18680 MODULE_LICENSE("Dual BSD/GPL");
18681