[SCSI] advansys: Convert to EISA driver model
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / scsi / advansys.c
blobe096f19e4dd9b23f2f618c8d4c99f3a2b3d9d67c
1 #define ASC_VERSION "3.4" /* AdvanSys Driver Version */
3 /*
4 * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
6 * Copyright (c) 1995-2000 Advanced System Products, Inc.
7 * Copyright (c) 2000-2001 ConnectCom Solutions, Inc.
8 * Copyright (c) 2007 Matthew Wilcox <matthew@wil.cx>
9 * All Rights Reserved.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
18 * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
19 * changed its name to ConnectCom Solutions, Inc.
20 * On June 18, 2001 Initio Corp. acquired ConnectCom's SCSI assets
25 Documentation for the AdvanSys Driver
27 A. Linux Kernels Supported by this Driver
28 B. Adapters Supported by this Driver
29 C. Linux source files modified by AdvanSys Driver
30 D. Source Comments
31 E. Driver Compile Time Options and Debugging
32 F. Driver LILO Option
33 G. Tests to run before releasing new driver
34 H. Release History
35 I. Known Problems/Fix List
36 J. Credits (Chronological Order)
38 A. Linux Kernels Supported by this Driver
40 This driver has been tested in the following Linux kernels: v2.2.18
41 v2.4.0. The driver is supported on v2.2 and v2.4 kernels and on x86,
42 alpha, and PowerPC platforms.
44 B. Adapters Supported by this Driver
46 AdvanSys (Advanced System Products, Inc.) manufactures the following
47 RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow
48 (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI
49 buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit
50 transfer) SCSI Host Adapters for the PCI bus.
52 The CDB counts below indicate the number of SCSI CDB (Command
53 Descriptor Block) requests that can be stored in the RISC chip
54 cache and board LRAM. A CDB is a single SCSI command. The driver
55 detect routine will display the number of CDBs available for each
56 adapter detected. The number of CDBs used by the driver can be
57 lowered in the BIOS by changing the 'Host Queue Size' adapter setting.
59 Laptop Products:
60 ABP-480 - Bus-Master CardBus (16 CDB) (2.4 kernel and greater)
62 Connectivity Products:
63 ABP510/5150 - Bus-Master ISA (240 CDB)
64 ABP5140 - Bus-Master ISA PnP (16 CDB)
65 ABP5142 - Bus-Master ISA PnP with floppy (16 CDB)
66 ABP902/3902 - Bus-Master PCI (16 CDB)
67 ABP3905 - Bus-Master PCI (16 CDB)
68 ABP915 - Bus-Master PCI (16 CDB)
69 ABP920 - Bus-Master PCI (16 CDB)
70 ABP3922 - Bus-Master PCI (16 CDB)
71 ABP3925 - Bus-Master PCI (16 CDB)
72 ABP930 - Bus-Master PCI (16 CDB)
73 ABP930U - Bus-Master PCI Ultra (16 CDB)
74 ABP930UA - Bus-Master PCI Ultra (16 CDB)
75 ABP960 - Bus-Master PCI MAC/PC (16 CDB)
76 ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
78 Single Channel Products:
79 ABP542 - Bus-Master ISA with floppy (240 CDB)
80 ABP742 - Bus-Master EISA (240 CDB)
81 ABP842 - Bus-Master VL (240 CDB)
82 ABP940 - Bus-Master PCI (240 CDB)
83 ABP940U - Bus-Master PCI Ultra (240 CDB)
84 ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB)
85 ABP970 - Bus-Master PCI MAC/PC (240 CDB)
86 ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
87 ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB)
88 ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB)
89 ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB)
90 ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB)
92 Multi-Channel Products:
93 ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
94 ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
95 ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
96 ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel)
97 ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
98 ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
99 ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.)
100 ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB)
101 ABP3950U3W - Bus-Master PCI Dual LVD2/Ultra3-Wide (253 CDB)
103 C. Linux source files modified by AdvanSys Driver
105 This section for historical purposes documents the changes
106 originally made to the Linux kernel source to add the advansys
107 driver. As Linux has changed some of these files have also
108 been modified.
110 1. linux/arch/i386/config.in:
112 bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
114 2. linux/drivers/scsi/hosts.c:
116 #ifdef CONFIG_SCSI_ADVANSYS
117 #include "advansys.h"
118 #endif
120 and after "static struct scsi_host_template builtin_scsi_hosts[] =":
122 #ifdef CONFIG_SCSI_ADVANSYS
123 ADVANSYS,
124 #endif
126 3. linux/drivers/scsi/Makefile:
128 ifdef CONFIG_SCSI_ADVANSYS
129 SCSI_SRCS := $(SCSI_SRCS) advansys.c
130 SCSI_OBJS := $(SCSI_OBJS) advansys.o
131 else
132 SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
133 endif
135 4. linux/init/main.c:
137 extern void advansys_setup(char *str, int *ints);
139 and add the following lines to the bootsetups[] array.
141 #ifdef CONFIG_SCSI_ADVANSYS
142 { "advansys=", advansys_setup },
143 #endif
145 D. Source Comments
147 1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
149 2. This driver should be maintained in multiple files. But to make
150 it easier to include with Linux and to follow Linux conventions,
151 the whole driver is maintained in the source files advansys.h and
152 advansys.c. In this file logical sections of the driver begin with
153 a comment that contains '---'. The following are the logical sections
154 of the driver below.
156 --- Linux Version
157 --- Linux Include File
158 --- Driver Options
159 --- Debugging Header
160 --- Asc Library Constants and Macros
161 --- Adv Library Constants and Macros
162 --- Driver Constants and Macros
163 --- Driver Structures
164 --- Driver Data
165 --- Driver Function Prototypes
166 --- Linux 'struct scsi_host_template' and advansys_setup() Functions
167 --- Loadable Driver Support
168 --- Miscellaneous Driver Functions
169 --- Functions Required by the Asc Library
170 --- Functions Required by the Adv Library
171 --- Tracing and Debugging Functions
172 --- Asc Library Functions
173 --- Adv Library Functions
175 3. The string 'XXX' is used to flag code that needs to be re-written
176 or that contains a problem that needs to be addressed.
178 4. I have stripped comments from and reformatted the source for the
179 Asc Library and Adv Library to reduce the size of this file. This
180 source can be found under the following headings. The Asc Library
181 is used to support Narrow Boards. The Adv Library is used to
182 support Wide Boards.
184 --- Asc Library Constants and Macros
185 --- Adv Library Constants and Macros
186 --- Asc Library Functions
187 --- Adv Library Functions
189 E. Driver Compile Time Options and Debugging
191 In this source file the following constants can be defined. They are
192 defined in the source below. Both of these options are enabled by
193 default.
195 1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled)
197 Enabling this option adds assertion logic statements to the
198 driver. If an assertion fails a message will be displayed to
199 the console, but the system will continue to operate. Any
200 assertions encountered should be reported to the person
201 responsible for the driver. Assertion statements may proactively
202 detect problems with the driver and facilitate fixing these
203 problems. Enabling assertions will add a small overhead to the
204 execution of the driver.
206 2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled)
208 Enabling this option adds tracing functions to the driver and
209 the ability to set a driver tracing level at boot time. This
210 option will also export symbols not required outside the driver to
211 the kernel name space. This option is very useful for debugging
212 the driver, but it will add to the size of the driver execution
213 image and add overhead to the execution of the driver.
215 The amount of debugging output can be controlled with the global
216 variable 'asc_dbglvl'. The higher the number the more output. By
217 default the debug level is 0.
219 If the driver is loaded at boot time and the LILO Driver Option
220 is included in the system, the debug level can be changed by
221 specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
222 first three hex digits of the pseudo I/O Port must be set to
223 'deb' and the fourth hex digit specifies the debug level: 0 - F.
224 The following command line will look for an adapter at 0x330
225 and set the debug level to 2.
227 linux advansys=0x330,0,0,0,0xdeb2
229 If the driver is built as a loadable module this variable can be
230 defined when the driver is loaded. The following insmod command
231 will set the debug level to one.
233 insmod advansys.o asc_dbglvl=1
235 Debugging Message Levels:
236 0: Errors Only
237 1: High-Level Tracing
238 2-N: Verbose Tracing
240 To enable debug output to console, please make sure that:
242 a. System and kernel logging is enabled (syslogd, klogd running).
243 b. Kernel messages are routed to console output. Check
244 /etc/syslog.conf for an entry similar to this:
246 kern.* /dev/console
248 c. klogd is started with the appropriate -c parameter
249 (e.g. klogd -c 8)
251 This will cause printk() messages to be be displayed on the
252 current console. Refer to the klogd(8) and syslogd(8) man pages
253 for details.
255 Alternatively you can enable printk() to console with this
256 program. However, this is not the 'official' way to do this.
257 Debug output is logged in /var/log/messages.
259 main()
261 syscall(103, 7, 0, 0);
264 Increasing LOG_BUF_LEN in kernel/printk.c to something like
265 40960 allows more debug messages to be buffered in the kernel
266 and written to the console or log file.
268 3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0)
270 Enabling this option adds statistics collection and display
271 through /proc to the driver. The information is useful for
272 monitoring driver and device performance. It will add to the
273 size of the driver execution image and add minor overhead to
274 the execution of the driver.
276 Statistics are maintained on a per adapter basis. Driver entry
277 point call counts and transfer size counts are maintained.
278 Statistics are only available for kernels greater than or equal
279 to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured.
281 AdvanSys SCSI adapter files have the following path name format:
283 /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
285 This information can be displayed with cat. For example:
287 cat /proc/scsi/advansys/0
289 When ADVANSYS_STATS is not defined the AdvanSys /proc files only
290 contain adapter and device configuration information.
292 F. Driver LILO Option
294 If init/main.c is modified as described in the 'Directions for Adding
295 the AdvanSys Driver to Linux' section (B.4.) above, the driver will
296 recognize the 'advansys' LILO command line and /etc/lilo.conf option.
297 This option can be used to either disable I/O port scanning or to limit
298 scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
299 PCI boards will still be searched for and detected. This option only
300 affects searching for ISA and VL boards.
302 Examples:
303 1. Eliminate I/O port scanning:
304 boot: linux advansys=
306 boot: linux advansys=0x0
307 2. Limit I/O port scanning to one I/O port:
308 boot: linux advansys=0x110
309 3. Limit I/O port scanning to four I/O ports:
310 boot: linux advansys=0x110,0x210,0x230,0x330
312 For a loadable module the same effect can be achieved by setting
313 the 'asc_iopflag' variable and 'asc_ioport' array when loading
314 the driver, e.g.
316 insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
318 If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1)
319 I/O Port may be added to specify the driver debug level. Refer to
320 the 'Driver Compile Time Options and Debugging' section above for
321 more information.
323 G. Tests to run before releasing new driver
325 1. In the supported kernels verify there are no warning or compile
326 errors when the kernel is built as both a driver and as a module
327 and with the following options:
329 ADVANSYS_DEBUG - enabled and disabled
330 CONFIG_SMP - enabled and disabled
331 CONFIG_PROC_FS - enabled and disabled
333 2. Run tests on an x86, alpha, and PowerPC with at least one narrow
334 card and one wide card attached to a hard disk and CD-ROM drive:
335 fdisk, mkfs, fsck, bonnie, copy/compare test from the
336 CD-ROM to the hard drive.
338 H. Release History
340 BETA-1.0 (12/23/95):
341 First Release
343 BETA-1.1 (12/28/95):
344 1. Prevent advansys_detect() from being called twice.
345 2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
347 1.2 (1/12/96):
348 1. Prevent re-entrancy in the interrupt handler which
349 resulted in the driver hanging Linux.
350 2. Fix problem that prevented ABP-940 cards from being
351 recognized on some PCI motherboards.
352 3. Add support for the ABP-5140 PnP ISA card.
353 4. Fix check condition return status.
354 5. Add conditionally compiled code for Linux v1.3.X.
356 1.3 (2/23/96):
357 1. Fix problem in advansys_biosparam() that resulted in the
358 wrong drive geometry being returned for drives > 1GB with
359 extended translation enabled.
360 2. Add additional tracing during device initialization.
361 3. Change code that only applies to ISA PnP adapter.
362 4. Eliminate 'make dep' warning.
363 5. Try to fix problem with handling resets by increasing their
364 timeout value.
366 1.4 (5/8/96):
367 1. Change definitions to eliminate conflicts with other subsystems.
368 2. Add versioning code for the shared interrupt changes.
369 3. Eliminate problem in asc_rmqueue() with iterating after removing
370 a request.
371 4. Remove reset request loop problem from the "Known Problems or
372 Issues" section. This problem was isolated and fixed in the
373 mid-level SCSI driver.
375 1.5 (8/8/96):
376 1. Add support for ABP-940U (PCI Ultra) adapter.
377 2. Add support for IRQ sharing by setting the IRQF_SHARED flag for
378 request_irq and supplying a dev_id pointer to both request_irq()
379 and free_irq().
380 3. In AscSearchIOPortAddr11() restore a call to check_region() which
381 should be used before I/O port probing.
382 4. Fix bug in asc_prt_hex() which resulted in the displaying
383 the wrong data.
384 5. Incorporate miscellaneous Asc Library bug fixes and new microcode.
385 6. Change driver versioning to be specific to each Linux sub-level.
386 7. Change statistics gathering to be per adapter instead of global
387 to the driver.
388 8. Add more information and statistics to the adapter /proc file:
389 /proc/scsi/advansys[0...].
390 9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list.
391 This problem has been addressed with the SCSI mid-level changes
392 made in v1.3.89. The advansys_select_queue_depths() function
393 was added for the v1.3.89 changes.
395 1.6 (9/10/96):
396 1. Incorporate miscellaneous Asc Library bug fixes and new microcode.
398 1.7 (9/25/96):
399 1. Enable clustering and optimize the setting of the maximum number
400 of scatter gather elements for any particular board. Clustering
401 increases CPU utilization, but results in a relatively larger
402 increase in I/O throughput.
403 2. Improve the performance of the request queuing functions by
404 adding a last pointer to the queue structure.
405 3. Correct problems with reset and abort request handling that
406 could have hung or crashed Linux.
407 4. Add more information to the adapter /proc file:
408 /proc/scsi/advansys[0...].
409 5. Remove the request timeout issue form the driver issues list.
410 6. Miscellaneous documentation additions and changes.
412 1.8 (10/4/96):
413 1. Make changes to handle the new v2.1.0 kernel memory mapping
414 in which a kernel virtual address may not be equivalent to its
415 bus or DMA memory address.
416 2. Change abort and reset request handling to make it yet even
417 more robust.
418 3. Try to mitigate request starvation by sending ordered requests
419 to heavily loaded, tag queuing enabled devices.
420 4. Maintain statistics on request response time.
421 5. Add request response time statistics and other information to
422 the adapter /proc file: /proc/scsi/advansys[0...].
424 1.9 (10/21/96):
425 1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to
426 make use of mid-level SCSI driver device queue depth flow
427 control mechanism. This will eliminate aborts caused by a
428 device being unable to keep up with requests and eliminate
429 repeat busy or QUEUE FULL status returned by a device.
430 2. Incorporate miscellaneous Asc Library bug fixes.
431 3. To allow the driver to work in kernels with broken module
432 support set 'cmd_per_lun' if the driver is compiled as a
433 module. This change affects kernels v1.3.89 to present.
434 4. Remove PCI BIOS address from the driver banner. The PCI BIOS
435 is relocated by the motherboard BIOS and its new address can
436 not be determined by the driver.
437 5. Add mid-level SCSI queue depth information to the adapter
438 /proc file: /proc/scsi/advansys[0...].
440 2.0 (11/14/96):
441 1. Change allocation of global structures used for device
442 initialization to guarantee they are in DMA-able memory.
443 Previously when the driver was loaded as a module these
444 structures might not have been in DMA-able memory, causing
445 device initialization to fail.
447 2.1 (12/30/96):
448 1. In advansys_reset(), if the request is a synchronous reset
449 request, even if the request serial number has changed, then
450 complete the request.
451 2. Add Asc Library bug fixes including new microcode.
452 3. Clear inquiry buffer before using it.
453 4. Correct ifdef typo.
455 2.2 (1/15/97):
456 1. Add Asc Library bug fixes including new microcode.
457 2. Add synchronous data transfer rate information to the
458 adapter /proc file: /proc/scsi/advansys[0...].
459 3. Change ADVANSYS_DEBUG to be disabled by default. This
460 will reduce the size of the driver image, eliminate execution
461 overhead, and remove unneeded symbols from the kernel symbol
462 space that were previously added by the driver.
463 4. Add new compile-time option ADVANSYS_ASSERT for assertion
464 code that used to be defined within ADVANSYS_DEBUG. This
465 option is enabled by default.
467 2.8 (5/26/97):
468 1. Change version number to 2.8 to synchronize the Linux driver
469 version numbering with other AdvanSys drivers.
470 2. Reformat source files without tabs to present the same view
471 of the file to everyone regardless of the editor tab setting
472 being used.
473 3. Add Asc Library bug fixes.
475 3.1A (1/8/98):
476 1. Change version number to 3.1 to indicate that support for
477 Ultra-Wide adapters (ABP-940UW) is included in this release.
478 2. Add Asc Library (Narrow Board) bug fixes.
479 3. Report an underrun condition with the host status byte set
480 to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which
481 causes the underrun condition to be ignored. When Linux defines
482 its own DID_UNDERRUN the constant defined in this file can be
483 removed.
484 4. Add patch to AscWaitTixISRDone().
485 5. Add support for up to 16 different AdvanSys host adapter SCSI
486 channels in one system. This allows four cards with four channels
487 to be used in one system.
489 3.1B (1/9/98):
490 1. Handle that PCI register base addresses are not always page
491 aligned even though ioremap() requires that the address argument
492 be page aligned.
494 3.1C (1/10/98):
495 1. Update latest BIOS version checked for from the /proc file.
496 2. Don't set microcode SDTR variable at initialization. Instead
497 wait until device capabilities have been detected from an Inquiry
498 command.
500 3.1D (1/21/98):
501 1. Improve performance when the driver is compiled as module by
502 allowing up to 64 scatter-gather elements instead of 8.
504 3.1E (5/1/98):
505 1. Set time delay in AscWaitTixISRDone() to 1000 ms.
506 2. Include SMP locking changes.
507 3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS
508 access functions.
509 4. Update board serial number printing.
510 5. Try allocating an IRQ both with and without the IRQF_DISABLED
511 flag set to allow IRQ sharing with drivers that do not set
512 the IRQF_DISABLED flag. Also display a more descriptive error
513 message if request_irq() fails.
514 6. Update to latest Asc and Adv Libraries.
516 3.2A (7/22/99):
517 1. Update Adv Library to 4.16 which includes support for
518 the ASC38C0800 (Ultra2/LVD) IC.
520 3.2B (8/23/99):
521 1. Correct PCI compile time option for v2.1.93 and greater
522 kernels, advansys_info() string, and debug compile time
523 option.
524 2. Correct DvcSleepMilliSecond() for v2.1.0 and greater
525 kernels. This caused an LVD detection/BIST problem problem
526 among other things.
527 3. Sort PCI cards by PCI Bus, Slot, Function ascending order
528 to be consistent with the BIOS.
529 4. Update to Asc Library S121 and Adv Library 5.2.
531 3.2C (8/24/99):
532 1. Correct PCI card detection bug introduced in 3.2B that
533 prevented PCI cards from being detected in kernels older
534 than v2.1.93.
536 3.2D (8/26/99):
537 1. Correct /proc device synchronous speed information display.
538 Also when re-negotiation is pending for a target device
539 note this condition with an * and footnote.
540 2. Correct initialization problem with Ultra-Wide cards that
541 have a pre-3.2 BIOS. A microcode variable changed locations
542 in 3.2 and greater BIOSes which caused WDTR to be attempted
543 erroneously with drives that don't support WDTR.
545 3.2E (8/30/99):
546 1. Fix compile error caused by v2.3.13 PCI structure change.
547 2. Remove field from ASCEEP_CONFIG that resulted in an EEPROM
548 checksum error for ISA cards.
549 3. Remove ASC_QUEUE_FLOW_CONTROL conditional code. The mid-level
550 SCSI changes that it depended on were never included in Linux.
552 3.2F (9/3/99):
553 1. Handle new initial function code added in v2.3.16 for all
554 driver versions.
556 3.2G (9/8/99):
557 1. Fix PCI board detection in v2.3.13 and greater kernels.
558 2. Fix comiple errors in v2.3.X with debugging enabled.
560 3.2H (9/13/99):
561 1. Add 64-bit address, long support for Alpha and UltraSPARC.
562 The driver has been verified to work on an Alpha system.
563 2. Add partial byte order handling support for Power PC and
564 other big-endian platforms. This support has not yet been
565 completed or verified.
566 3. For wide boards replace block zeroing of request and
567 scatter-gather structures with individual field initialization
568 to improve performance.
569 4. Correct and clarify ROM BIOS version detection.
571 3.2I (10/8/99):
572 1. Update to Adv Library 5.4.
573 2. Add v2.3.19 underrun reporting to asc_isr_callback() and
574 adv_isr_callback(). Remove DID_UNDERRUN constant and other
575 no longer needed code that previously documented the lack
576 of underrun handling.
578 3.2J (10/14/99):
579 1. Eliminate compile errors for v2.0 and earlier kernels.
581 3.2K (11/15/99):
582 1. Correct debug compile error in asc_prt_adv_scsi_req_q().
583 2. Update Adv Library to 5.5.
584 3. Add ifdef handling for /proc changes added in v2.3.28.
585 4. Increase Wide board scatter-gather list maximum length to
586 255 when the driver is compiled into the kernel.
588 3.2L (11/18/99):
589 1. Fix bug in adv_get_sglist() that caused an assertion failure
590 at line 7475. The reqp->sgblkp pointer must be initialized
591 to NULL in adv_get_sglist().
593 3.2M (11/29/99):
594 1. Really fix bug in adv_get_sglist().
595 2. Incorporate v2.3.29 changes into driver.
597 3.2N (4/1/00):
598 1. Add CONFIG_ISA ifdef code.
599 2. Include advansys_interrupts_enabled name change patch.
600 3. For >= v2.3.28 use new SCSI error handling with new function
601 advansys_eh_bus_reset(). Don't include an abort function
602 because of base library limitations.
603 4. For >= v2.3.28 use per board lock instead of io_request_lock.
604 5. For >= v2.3.28 eliminate advansys_command() and
605 advansys_command_done().
606 6. Add some changes for PowerPC (Big Endian) support, but it isn't
607 working yet.
608 7. Fix "nonexistent resource free" problem that occurred on a module
609 unload for boards with an I/O space >= 255. The 'n_io_port' field
610 is only one byte and can not be used to hold an ioport length more
611 than 255.
613 3.3A (4/4/00):
614 1. Update to Adv Library 5.8.
615 2. For wide cards add support for CDBs up to 16 bytes.
616 3. Eliminate warnings when CONFIG_PROC_FS is not defined.
618 3.3B (5/1/00):
619 1. Support for PowerPC (Big Endian) wide cards. Narrow cards
620 still need work.
621 2. Change bitfields to shift and mask access for endian
622 portability.
624 3.3C (10/13/00):
625 1. Update for latest 2.4 kernel.
626 2. Test ABP-480 CardBus support in 2.4 kernel - works!
627 3. Update to Asc Library S123.
628 4. Update to Adv Library 5.12.
630 3.3D (11/22/00):
631 1. Update for latest 2.4 kernel.
632 2. Create patches for 2.2 and 2.4 kernels.
634 3.3E (1/9/01):
635 1. Now that 2.4 is released remove ifdef code for kernel versions
636 less than 2.2. The driver is now only supported in kernels 2.2,
637 2.4, and greater.
638 2. Add code to release and acquire the io_request_lock in
639 the driver entrypoint functions: advansys_detect and
640 advansys_queuecommand. In kernel 2.4 the SCSI mid-level driver
641 still holds the io_request_lock on entry to SCSI low-level drivers.
642 This was supposed to be removed before 2.4 was released but never
643 happened. When the mid-level SCSI driver is changed all references
644 to the io_request_lock should be removed from the driver.
645 3. Simplify error handling by removing advansys_abort(),
646 AscAbortSRB(), AscResetDevice(). SCSI bus reset requests are
647 now handled by resetting the SCSI bus and fully re-initializing
648 the chip. This simple method of error recovery has proven to work
649 most reliably after attempts at different methods. Also now only
650 support the "new" error handling method and remove the obsolete
651 error handling interface.
652 4. Fix debug build errors.
654 3.3F (1/24/01):
655 1. Merge with ConnectCom version from Andy Kellner which
656 updates Adv Library to 5.14.
657 2. Make PowerPC (Big Endian) work for narrow cards and
658 fix problems writing EEPROM for wide cards.
659 3. Remove interrupts_enabled assertion function.
661 3.3G (2/16/01):
662 1. Return an error from narrow boards if passed a 16 byte
663 CDB. The wide board can already handle 16 byte CDBs.
665 3.3GJ (4/15/02):
666 1. hacks for lk 2.5 series (D. Gilbert)
668 3.3GJD (10/14/02):
669 1. change select_queue_depths to slave_configure
670 2. make cmd_per_lun be sane again
672 3.3K [2004/06/24]:
673 1. continuing cleanup for lk 2.6 series
674 2. Fix problem in lk 2.6.7-bk2 that broke PCI wide cards
675 3. Fix problem that oopsed ISA cards
677 I. Known Problems/Fix List (XXX)
679 1. Need to add memory mapping workaround. Test the memory mapping.
680 If it doesn't work revert to I/O port access. Can a test be done
681 safely?
682 2. Handle an interrupt not working. Keep an interrupt counter in
683 the interrupt handler. In the timeout function if the interrupt
684 has not occurred then print a message and run in polled mode.
685 3. Allow bus type scanning order to be changed.
686 4. Need to add support for target mode commands, cf. CAM XPT.
688 J. Credits (Chronological Order)
690 Bob Frey <bfrey@turbolinux.com.cn> wrote the AdvanSys SCSI driver
691 and maintained it up to 3.3F. He continues to answer questions
692 and help maintain the driver.
694 Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and
695 basis for the Linux v1.3.X changes which were included in the
696 1.2 release.
698 Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug
699 in advansys_biosparam() which was fixed in the 1.3 release.
701 Erik Ratcliffe <erik@caldera.com> has done testing of the
702 AdvanSys driver in the Caldera releases.
704 Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to
705 AscWaitTixISRDone() which he found necessary to make the
706 driver work with a SCSI-1 disk.
708 Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide
709 support in the 3.1A driver.
711 Doug Gilbert <dgilbert@interlog.com> has made changes and
712 suggestions to improve the driver and done a lot of testing.
714 Ken Mort <ken@mort.net> reported a DEBUG compile bug fixed
715 in 3.2K.
717 Tom Rini <trini@kernel.crashing.org> provided the CONFIG_ISA
718 patch and helped with PowerPC wide and narrow board support.
720 Philip Blundell <philb@gnu.org> provided an
721 advansys_interrupts_enabled patch.
723 Dave Jones <dave@denial.force9.co.uk> reported the compiler
724 warnings generated when CONFIG_PROC_FS was not defined in
725 the 3.2M driver.
727 Jerry Quinn <jlquinn@us.ibm.com> fixed PowerPC support (endian
728 problems) for wide cards.
730 Bryan Henderson <bryanh@giraffe-data.com> helped debug narrow
731 card error handling.
733 Manuel Veloso <veloso@pobox.com> worked hard on PowerPC narrow
734 board support and fixed a bug in AscGetEEPConfig().
736 Arnaldo Carvalho de Melo <acme@conectiva.com.br> made
737 save_flags/restore_flags changes.
739 Andy Kellner <AKellner@connectcom.net> continues the Advansys SCSI
740 driver development for ConnectCom (Version > 3.3F).
742 K. ConnectCom (AdvanSys) Contact Information
744 Mail: ConnectCom Solutions, Inc.
745 1150 Ringwood Court
746 San Jose, CA 95131
747 Operator/Sales: 1-408-383-9400
748 FAX: 1-408-383-9612
749 Tech Support: 1-408-467-2930
750 Tech Support E-Mail: linux@connectcom.net
751 FTP Site: ftp.connectcom.net (login: anonymous)
752 Web Site: http://www.connectcom.net
757 * --- Linux Include Files
760 #include <linux/module.h>
761 #include <linux/string.h>
762 #include <linux/kernel.h>
763 #include <linux/types.h>
764 #include <linux/ioport.h>
765 #include <linux/interrupt.h>
766 #include <linux/delay.h>
767 #include <linux/slab.h>
768 #include <linux/mm.h>
769 #include <linux/proc_fs.h>
770 #include <linux/init.h>
771 #include <linux/blkdev.h>
772 #include <linux/eisa.h>
773 #include <linux/pci.h>
774 #include <linux/spinlock.h>
775 #include <linux/dma-mapping.h>
777 #include <asm/io.h>
778 #include <asm/system.h>
779 #include <asm/dma.h>
781 #include <scsi/scsi_cmnd.h>
782 #include <scsi/scsi_device.h>
783 #include <scsi/scsi_tcq.h>
784 #include <scsi/scsi.h>
785 #include <scsi/scsi_host.h>
787 /* FIXME: (by jejb@steeleye.com)
789 * Although all of the necessary command mapping places have the
790 * appropriate dma_map.. APIs, the driver still processes its internal
791 * queue using bus_to_virt() and virt_to_bus() which are illegal under
792 * the API. The entire queue processing structure will need to be
793 * altered to fix this.
795 #warning this driver is still not properly converted to the DMA API
798 * --- Driver Options
801 /* Enable driver assertions. */
802 #define ADVANSYS_ASSERT
804 /* Enable driver /proc statistics. */
805 #define ADVANSYS_STATS
807 /* Enable driver tracing. */
808 /* #define ADVANSYS_DEBUG */
811 * --- Asc Library Constants and Macros
814 #define ASC_LIB_VERSION_MAJOR 1
815 #define ASC_LIB_VERSION_MINOR 24
816 #define ASC_LIB_SERIAL_NUMBER 123
819 * Portable Data Types
821 * Any instance where a 32-bit long or pointer type is assumed
822 * for precision or HW defined structures, the following define
823 * types must be used. In Linux the char, short, and int types
824 * are all consistent at 8, 16, and 32 bits respectively. Pointers
825 * and long types are 64 bits on Alpha and UltraSPARC.
827 #define ASC_PADDR __u32 /* Physical/Bus address data type. */
828 #define ASC_VADDR __u32 /* Virtual address data type. */
829 #define ASC_DCNT __u32 /* Unsigned Data count type. */
830 #define ASC_SDCNT __s32 /* Signed Data count type. */
833 * These macros are used to convert a virtual address to a
834 * 32-bit value. This currently can be used on Linux Alpha
835 * which uses 64-bit virtual address but a 32-bit bus address.
836 * This is likely to break in the future, but doing this now
837 * will give us time to change the HW and FW to handle 64-bit
838 * addresses.
840 #define ASC_VADDR_TO_U32 virt_to_bus
841 #define ASC_U32_TO_VADDR bus_to_virt
843 typedef unsigned char uchar;
845 #ifndef TRUE
846 #define TRUE (1)
847 #endif
848 #ifndef FALSE
849 #define FALSE (0)
850 #endif
852 #define EOF (-1)
853 #define ERR (-1)
854 #define UW_ERR (uint)(0xFFFF)
855 #define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
856 #define AscPCIConfigVendorIDRegister 0x0000
857 #define AscPCIConfigDeviceIDRegister 0x0002
858 #define AscPCIConfigCommandRegister 0x0004
859 #define AscPCIConfigStatusRegister 0x0006
860 #define AscPCIConfigRevisionIDRegister 0x0008
861 #define AscPCIConfigCacheSize 0x000C
862 #define AscPCIConfigLatencyTimer 0x000D
863 #define AscPCIIOBaseRegister 0x0010
864 #define AscPCICmdRegBits_IOMemBusMaster 0x0007
865 #define ASC_PCI_ID2FUNC(id) (((id) >> 8) & 0x7)
866 #define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
868 #define ASC_DVCLIB_CALL_DONE (1)
869 #define ASC_DVCLIB_CALL_FAILED (0)
870 #define ASC_DVCLIB_CALL_ERROR (-1)
872 #define PCI_VENDOR_ID_ASP 0x10cd
873 #define PCI_DEVICE_ID_ASP_1200A 0x1100
874 #define PCI_DEVICE_ID_ASP_ABP940 0x1200
875 #define PCI_DEVICE_ID_ASP_ABP940U 0x1300
876 #define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
877 #define PCI_DEVICE_ID_38C0800_REV1 0x2500
878 #define PCI_DEVICE_ID_38C1600_REV1 0x2700
881 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
882 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
883 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
884 * SRB structure.
886 #define CC_VERY_LONG_SG_LIST 0
887 #define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
889 #define PortAddr unsigned short /* port address size */
890 #define inp(port) inb(port)
891 #define outp(port, byte) outb((byte), (port))
893 #define inpw(port) inw(port)
894 #define outpw(port, word) outw((word), (port))
896 #define ASC_MAX_SG_QUEUE 7
897 #define ASC_MAX_SG_LIST 255
899 #define ASC_CS_TYPE unsigned short
901 #define ASC_IS_ISA (0x0001)
902 #define ASC_IS_ISAPNP (0x0081)
903 #define ASC_IS_EISA (0x0002)
904 #define ASC_IS_PCI (0x0004)
905 #define ASC_IS_PCI_ULTRA (0x0104)
906 #define ASC_IS_PCMCIA (0x0008)
907 #define ASC_IS_MCA (0x0020)
908 #define ASC_IS_VL (0x0040)
909 #define ASC_ISA_PNP_PORT_ADDR (0x279)
910 #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
911 #define ASC_IS_WIDESCSI_16 (0x0100)
912 #define ASC_IS_WIDESCSI_32 (0x0200)
913 #define ASC_IS_BIG_ENDIAN (0x8000)
914 #define ASC_CHIP_MIN_VER_VL (0x01)
915 #define ASC_CHIP_MAX_VER_VL (0x07)
916 #define ASC_CHIP_MIN_VER_PCI (0x09)
917 #define ASC_CHIP_MAX_VER_PCI (0x0F)
918 #define ASC_CHIP_VER_PCI_BIT (0x08)
919 #define ASC_CHIP_MIN_VER_ISA (0x11)
920 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
921 #define ASC_CHIP_MAX_VER_ISA (0x27)
922 #define ASC_CHIP_VER_ISA_BIT (0x30)
923 #define ASC_CHIP_VER_ISAPNP_BIT (0x20)
924 #define ASC_CHIP_VER_ASYN_BUG (0x21)
925 #define ASC_CHIP_VER_PCI 0x08
926 #define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
927 #define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
928 #define ASC_CHIP_MIN_VER_EISA (0x41)
929 #define ASC_CHIP_MAX_VER_EISA (0x47)
930 #define ASC_CHIP_VER_EISA_BIT (0x40)
931 #define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
932 #define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER 0x21
933 #define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER 0x0A
934 #define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL)
935 #define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
936 #define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL)
937 #define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
938 #define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL)
939 #define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
940 #define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL)
941 #define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL)
943 #define ASC_SCSI_ID_BITS 3
944 #define ASC_SCSI_TIX_TYPE uchar
945 #define ASC_ALL_DEVICE_BIT_SET 0xFF
946 #define ASC_SCSI_BIT_ID_TYPE uchar
947 #define ASC_MAX_TID 7
948 #define ASC_MAX_LUN 7
949 #define ASC_SCSI_WIDTH_BIT_SET 0xFF
950 #define ASC_MAX_SENSE_LEN 32
951 #define ASC_MIN_SENSE_LEN 14
952 #define ASC_MAX_CDB_LEN 12
953 #define ASC_SCSI_RESET_HOLD_TIME_US 60
955 #define ADV_INQ_CLOCKING_ST_ONLY 0x0
956 #define ADV_INQ_CLOCKING_DT_ONLY 0x1
957 #define ADV_INQ_CLOCKING_ST_AND_DT 0x3
960 * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
961 * and CmdDt (Command Support Data) field bit definitions.
963 #define ADV_INQ_RTN_VPD_AND_CMDDT 0x3
964 #define ADV_INQ_RTN_CMDDT_FOR_OP_CODE 0x2
965 #define ADV_INQ_RTN_VPD_FOR_PG_CODE 0x1
966 #define ADV_INQ_RTN_STD_INQUIRY_DATA 0x0
968 #define ASC_SCSIDIR_NOCHK 0x00
969 #define ASC_SCSIDIR_T2H 0x08
970 #define ASC_SCSIDIR_H2T 0x10
971 #define ASC_SCSIDIR_NODATA 0x18
972 #define SCSI_ASC_NOMEDIA 0x3A
973 #define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4))
974 #define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F))
975 #define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13))
976 #define PUT_CDB1(x) ((uchar)((uint)(x) >> 8))
977 #define MS_CMD_DONE 0x00
978 #define MS_EXTEND 0x01
979 #define MS_SDTR_LEN 0x03
980 #define MS_SDTR_CODE 0x01
981 #define MS_WDTR_LEN 0x02
982 #define MS_WDTR_CODE 0x03
983 #define MS_MDP_LEN 0x05
984 #define MS_MDP_CODE 0x00
987 * Inquiry data structure and bitfield macros
989 * Only quantities of more than 1 bit are shifted, since the others are
990 * just tested for true or false. C bitfields aren't portable between big
991 * and little-endian platforms so they are not used.
994 #define ASC_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f)
995 #define ASC_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5)
996 #define ASC_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f)
997 #define ASC_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80)
998 #define ASC_INQ_ANSI_VER(inq) ((inq)->ver & 0x07)
999 #define ASC_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3)
1000 #define ASC_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6)
1001 #define ASC_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f)
1002 #define ASC_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40)
1003 #define ASC_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80)
1004 #define ASC_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01)
1005 #define ASC_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02)
1006 #define ASC_INQ_LINK_CMD(inq) ((inq)->flags & 0x08)
1007 #define ASC_INQ_SYNC(inq) ((inq)->flags & 0x10)
1008 #define ASC_INQ_WIDE16(inq) ((inq)->flags & 0x20)
1009 #define ASC_INQ_WIDE32(inq) ((inq)->flags & 0x40)
1010 #define ASC_INQ_REL_ADDR(inq) ((inq)->flags & 0x80)
1011 #define ASC_INQ_INFO_UNIT(inq) ((inq)->info & 0x01)
1012 #define ASC_INQ_QUICK_ARB(inq) ((inq)->info & 0x02)
1013 #define ASC_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2)
1015 typedef struct {
1016 uchar periph;
1017 uchar devtype;
1018 uchar ver;
1019 uchar byte3;
1020 uchar add_len;
1021 uchar res1;
1022 uchar res2;
1023 uchar flags;
1024 uchar vendor_id[8];
1025 uchar product_id[16];
1026 uchar product_rev_level[4];
1027 } ASC_SCSI_INQUIRY;
1029 #define ASC_SG_LIST_PER_Q 7
1030 #define QS_FREE 0x00
1031 #define QS_READY 0x01
1032 #define QS_DISC1 0x02
1033 #define QS_DISC2 0x04
1034 #define QS_BUSY 0x08
1035 #define QS_ABORTED 0x40
1036 #define QS_DONE 0x80
1037 #define QC_NO_CALLBACK 0x01
1038 #define QC_SG_SWAP_QUEUE 0x02
1039 #define QC_SG_HEAD 0x04
1040 #define QC_DATA_IN 0x08
1041 #define QC_DATA_OUT 0x10
1042 #define QC_URGENT 0x20
1043 #define QC_MSG_OUT 0x40
1044 #define QC_REQ_SENSE 0x80
1045 #define QCSG_SG_XFER_LIST 0x02
1046 #define QCSG_SG_XFER_MORE 0x04
1047 #define QCSG_SG_XFER_END 0x08
1048 #define QD_IN_PROGRESS 0x00
1049 #define QD_NO_ERROR 0x01
1050 #define QD_ABORTED_BY_HOST 0x02
1051 #define QD_WITH_ERROR 0x04
1052 #define QD_INVALID_REQUEST 0x80
1053 #define QD_INVALID_HOST_NUM 0x81
1054 #define QD_INVALID_DEVICE 0x82
1055 #define QD_ERR_INTERNAL 0xFF
1056 #define QHSTA_NO_ERROR 0x00
1057 #define QHSTA_M_SEL_TIMEOUT 0x11
1058 #define QHSTA_M_DATA_OVER_RUN 0x12
1059 #define QHSTA_M_DATA_UNDER_RUN 0x12
1060 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
1061 #define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
1062 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1063 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
1064 #define QHSTA_D_HOST_ABORT_FAILED 0x23
1065 #define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
1066 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1067 #define QHSTA_D_ASPI_NO_BUF_POOL 0x26
1068 #define QHSTA_M_WTM_TIMEOUT 0x41
1069 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
1070 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
1071 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1072 #define QHSTA_M_TARGET_STATUS_BUSY 0x45
1073 #define QHSTA_M_BAD_TAG_CODE 0x46
1074 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
1075 #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1076 #define QHSTA_D_LRAM_CMP_ERROR 0x81
1077 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1078 #define ASC_FLAG_SCSIQ_REQ 0x01
1079 #define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
1080 #define ASC_FLAG_BIOS_ASYNC_IO 0x04
1081 #define ASC_FLAG_SRB_LINEAR_ADDR 0x08
1082 #define ASC_FLAG_WIN16 0x10
1083 #define ASC_FLAG_WIN32 0x20
1084 #define ASC_FLAG_ISA_OVER_16MB 0x40
1085 #define ASC_FLAG_DOS_VM_CALLBACK 0x80
1086 #define ASC_TAG_FLAG_EXTRA_BYTES 0x10
1087 #define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
1088 #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
1089 #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1090 #define ASC_SCSIQ_CPY_BEG 4
1091 #define ASC_SCSIQ_SGHD_CPY_BEG 2
1092 #define ASC_SCSIQ_B_FWD 0
1093 #define ASC_SCSIQ_B_BWD 1
1094 #define ASC_SCSIQ_B_STATUS 2
1095 #define ASC_SCSIQ_B_QNO 3
1096 #define ASC_SCSIQ_B_CNTL 4
1097 #define ASC_SCSIQ_B_SG_QUEUE_CNT 5
1098 #define ASC_SCSIQ_D_DATA_ADDR 8
1099 #define ASC_SCSIQ_D_DATA_CNT 12
1100 #define ASC_SCSIQ_B_SENSE_LEN 20
1101 #define ASC_SCSIQ_DONE_INFO_BEG 22
1102 #define ASC_SCSIQ_D_SRBPTR 22
1103 #define ASC_SCSIQ_B_TARGET_IX 26
1104 #define ASC_SCSIQ_B_CDB_LEN 28
1105 #define ASC_SCSIQ_B_TAG_CODE 29
1106 #define ASC_SCSIQ_W_VM_ID 30
1107 #define ASC_SCSIQ_DONE_STATUS 32
1108 #define ASC_SCSIQ_HOST_STATUS 33
1109 #define ASC_SCSIQ_SCSI_STATUS 34
1110 #define ASC_SCSIQ_CDB_BEG 36
1111 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1112 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
1113 #define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
1114 #define ASC_SCSIQ_B_SG_WK_QP 49
1115 #define ASC_SCSIQ_B_SG_WK_IX 50
1116 #define ASC_SCSIQ_W_ALT_DC1 52
1117 #define ASC_SCSIQ_B_LIST_CNT 6
1118 #define ASC_SCSIQ_B_CUR_LIST_CNT 7
1119 #define ASC_SGQ_B_SG_CNTL 4
1120 #define ASC_SGQ_B_SG_HEAD_QP 5
1121 #define ASC_SGQ_B_SG_LIST_CNT 6
1122 #define ASC_SGQ_B_SG_CUR_LIST_CNT 7
1123 #define ASC_SGQ_LIST_BEG 8
1124 #define ASC_DEF_SCSI1_QNG 4
1125 #define ASC_MAX_SCSI1_QNG 4
1126 #define ASC_DEF_SCSI2_QNG 16
1127 #define ASC_MAX_SCSI2_QNG 32
1128 #define ASC_TAG_CODE_MASK 0x23
1129 #define ASC_STOP_REQ_RISC_STOP 0x01
1130 #define ASC_STOP_ACK_RISC_STOP 0x03
1131 #define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
1132 #define ASC_STOP_CLEAN_UP_DISC_Q 0x20
1133 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1134 #define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1135 #define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1136 #define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
1137 #define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
1138 #define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
1139 #define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1140 #define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
1142 typedef struct asc_scsiq_1 {
1143 uchar status;
1144 uchar q_no;
1145 uchar cntl;
1146 uchar sg_queue_cnt;
1147 uchar target_id;
1148 uchar target_lun;
1149 ASC_PADDR data_addr;
1150 ASC_DCNT data_cnt;
1151 ASC_PADDR sense_addr;
1152 uchar sense_len;
1153 uchar extra_bytes;
1154 } ASC_SCSIQ_1;
1156 typedef struct asc_scsiq_2 {
1157 ASC_VADDR srb_ptr;
1158 uchar target_ix;
1159 uchar flag;
1160 uchar cdb_len;
1161 uchar tag_code;
1162 ushort vm_id;
1163 } ASC_SCSIQ_2;
1165 typedef struct asc_scsiq_3 {
1166 uchar done_stat;
1167 uchar host_stat;
1168 uchar scsi_stat;
1169 uchar scsi_msg;
1170 } ASC_SCSIQ_3;
1172 typedef struct asc_scsiq_4 {
1173 uchar cdb[ASC_MAX_CDB_LEN];
1174 uchar y_first_sg_list_qp;
1175 uchar y_working_sg_qp;
1176 uchar y_working_sg_ix;
1177 uchar y_res;
1178 ushort x_req_count;
1179 ushort x_reconnect_rtn;
1180 ASC_PADDR x_saved_data_addr;
1181 ASC_DCNT x_saved_data_cnt;
1182 } ASC_SCSIQ_4;
1184 typedef struct asc_q_done_info {
1185 ASC_SCSIQ_2 d2;
1186 ASC_SCSIQ_3 d3;
1187 uchar q_status;
1188 uchar q_no;
1189 uchar cntl;
1190 uchar sense_len;
1191 uchar extra_bytes;
1192 uchar res;
1193 ASC_DCNT remain_bytes;
1194 } ASC_QDONE_INFO;
1196 typedef struct asc_sg_list {
1197 ASC_PADDR addr;
1198 ASC_DCNT bytes;
1199 } ASC_SG_LIST;
1201 typedef struct asc_sg_head {
1202 ushort entry_cnt;
1203 ushort queue_cnt;
1204 ushort entry_to_copy;
1205 ushort res;
1206 ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1207 } ASC_SG_HEAD;
1209 #define ASC_MIN_SG_LIST 2
1211 typedef struct asc_min_sg_head {
1212 ushort entry_cnt;
1213 ushort queue_cnt;
1214 ushort entry_to_copy;
1215 ushort res;
1216 ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
1217 } ASC_MIN_SG_HEAD;
1219 #define QCX_SORT (0x0001)
1220 #define QCX_COALEASE (0x0002)
1222 typedef struct asc_scsi_q {
1223 ASC_SCSIQ_1 q1;
1224 ASC_SCSIQ_2 q2;
1225 uchar *cdbptr;
1226 ASC_SG_HEAD *sg_head;
1227 ushort remain_sg_entry_cnt;
1228 ushort next_sg_index;
1229 } ASC_SCSI_Q;
1231 typedef struct asc_scsi_req_q {
1232 ASC_SCSIQ_1 r1;
1233 ASC_SCSIQ_2 r2;
1234 uchar *cdbptr;
1235 ASC_SG_HEAD *sg_head;
1236 uchar *sense_ptr;
1237 ASC_SCSIQ_3 r3;
1238 uchar cdb[ASC_MAX_CDB_LEN];
1239 uchar sense[ASC_MIN_SENSE_LEN];
1240 } ASC_SCSI_REQ_Q;
1242 typedef struct asc_scsi_bios_req_q {
1243 ASC_SCSIQ_1 r1;
1244 ASC_SCSIQ_2 r2;
1245 uchar *cdbptr;
1246 ASC_SG_HEAD *sg_head;
1247 uchar *sense_ptr;
1248 ASC_SCSIQ_3 r3;
1249 uchar cdb[ASC_MAX_CDB_LEN];
1250 uchar sense[ASC_MIN_SENSE_LEN];
1251 } ASC_SCSI_BIOS_REQ_Q;
1253 typedef struct asc_risc_q {
1254 uchar fwd;
1255 uchar bwd;
1256 ASC_SCSIQ_1 i1;
1257 ASC_SCSIQ_2 i2;
1258 ASC_SCSIQ_3 i3;
1259 ASC_SCSIQ_4 i4;
1260 } ASC_RISC_Q;
1262 typedef struct asc_sg_list_q {
1263 uchar seq_no;
1264 uchar q_no;
1265 uchar cntl;
1266 uchar sg_head_qp;
1267 uchar sg_list_cnt;
1268 uchar sg_cur_list_cnt;
1269 } ASC_SG_LIST_Q;
1271 typedef struct asc_risc_sg_list_q {
1272 uchar fwd;
1273 uchar bwd;
1274 ASC_SG_LIST_Q sg;
1275 ASC_SG_LIST sg_list[7];
1276 } ASC_RISC_SG_LIST_Q;
1278 #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL
1279 #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024
1280 #define ASCQ_ERR_NO_ERROR 0
1281 #define ASCQ_ERR_IO_NOT_FOUND 1
1282 #define ASCQ_ERR_LOCAL_MEM 2
1283 #define ASCQ_ERR_CHKSUM 3
1284 #define ASCQ_ERR_START_CHIP 4
1285 #define ASCQ_ERR_INT_TARGET_ID 5
1286 #define ASCQ_ERR_INT_LOCAL_MEM 6
1287 #define ASCQ_ERR_HALT_RISC 7
1288 #define ASCQ_ERR_GET_ASPI_ENTRY 8
1289 #define ASCQ_ERR_CLOSE_ASPI 9
1290 #define ASCQ_ERR_HOST_INQUIRY 0x0A
1291 #define ASCQ_ERR_SAVED_SRB_BAD 0x0B
1292 #define ASCQ_ERR_QCNTL_SG_LIST 0x0C
1293 #define ASCQ_ERR_Q_STATUS 0x0D
1294 #define ASCQ_ERR_WR_SCSIQ 0x0E
1295 #define ASCQ_ERR_PC_ADDR 0x0F
1296 #define ASCQ_ERR_SYN_OFFSET 0x10
1297 #define ASCQ_ERR_SYN_XFER_TIME 0x11
1298 #define ASCQ_ERR_LOCK_DMA 0x12
1299 #define ASCQ_ERR_UNLOCK_DMA 0x13
1300 #define ASCQ_ERR_VDS_CHK_INSTALL 0x14
1301 #define ASCQ_ERR_MICRO_CODE_HALT 0x15
1302 #define ASCQ_ERR_SET_LRAM_ADDR 0x16
1303 #define ASCQ_ERR_CUR_QNG 0x17
1304 #define ASCQ_ERR_SG_Q_LINKS 0x18
1305 #define ASCQ_ERR_SCSIQ_PTR 0x19
1306 #define ASCQ_ERR_ISR_RE_ENTRY 0x1A
1307 #define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
1308 #define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
1309 #define ASCQ_ERR_SG_LIST_ODD_ADDRESS 0x1D
1310 #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1311 #define ASCQ_ERR_SCSIQ_NULL_PTR 0x1F
1312 #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR 0x20
1313 #define ASCQ_ERR_GET_NUM_OF_FREE_Q 0x21
1314 #define ASCQ_ERR_SEND_SCSI_Q 0x22
1315 #define ASCQ_ERR_HOST_REQ_RISC_HALT 0x23
1316 #define ASCQ_ERR_RESET_SDTR 0x24
1319 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
1321 #define ASC_WARN_NO_ERROR 0x0000
1322 #define ASC_WARN_IO_PORT_ROTATE 0x0001
1323 #define ASC_WARN_EEPROM_CHKSUM 0x0002
1324 #define ASC_WARN_IRQ_MODIFIED 0x0004
1325 #define ASC_WARN_AUTO_CONFIG 0x0008
1326 #define ASC_WARN_CMD_QNG_CONFLICT 0x0010
1327 #define ASC_WARN_EEPROM_RECOVER 0x0020
1328 #define ASC_WARN_CFG_MSW_RECOVER 0x0040
1329 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1332 * Error code values are set in ASC_DVC_VAR 'err_code'.
1334 #define ASC_IERR_WRITE_EEPROM 0x0001
1335 #define ASC_IERR_MCODE_CHKSUM 0x0002
1336 #define ASC_IERR_SET_PC_ADDR 0x0004
1337 #define ASC_IERR_START_STOP_CHIP 0x0008
1338 #define ASC_IERR_IRQ_NO 0x0010
1339 #define ASC_IERR_SET_IRQ_NO 0x0020
1340 #define ASC_IERR_CHIP_VERSION 0x0040
1341 #define ASC_IERR_SET_SCSI_ID 0x0080
1342 #define ASC_IERR_GET_PHY_ADDR 0x0100
1343 #define ASC_IERR_BAD_SIGNATURE 0x0200
1344 #define ASC_IERR_NO_BUS_TYPE 0x0400
1345 #define ASC_IERR_SCAM 0x0800
1346 #define ASC_IERR_SET_SDTR 0x1000
1347 #define ASC_IERR_RW_LRAM 0x8000
1349 #define ASC_DEF_IRQ_NO 10
1350 #define ASC_MAX_IRQ_NO 15
1351 #define ASC_MIN_IRQ_NO 10
1352 #define ASC_MIN_REMAIN_Q (0x02)
1353 #define ASC_DEF_MAX_TOTAL_QNG (0xF0)
1354 #define ASC_MIN_TAG_Q_PER_DVC (0x04)
1355 #define ASC_DEF_TAG_Q_PER_DVC (0x04)
1356 #define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q
1357 #define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1358 #define ASC_MAX_TOTAL_QNG 240
1359 #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1360 #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
1361 #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
1362 #define ASC_MAX_INRAM_TAG_QNG 16
1363 #define ASC_IOADR_TABLE_MAX_IX 11
1364 #define ASC_IOADR_GAP 0x10
1365 #define ASC_SEARCH_IOP_GAP 0x10
1366 #define ASC_MIN_IOP_ADDR (PortAddr)0x0100
1367 #define ASC_MAX_IOP_ADDR (PortAddr)0x3F0
1368 #define ASC_IOADR_1 (PortAddr)0x0110
1369 #define ASC_IOADR_2 (PortAddr)0x0130
1370 #define ASC_IOADR_3 (PortAddr)0x0150
1371 #define ASC_IOADR_4 (PortAddr)0x0190
1372 #define ASC_IOADR_5 (PortAddr)0x0210
1373 #define ASC_IOADR_6 (PortAddr)0x0230
1374 #define ASC_IOADR_7 (PortAddr)0x0250
1375 #define ASC_IOADR_8 (PortAddr)0x0330
1376 #define ASC_IOADR_DEF ASC_IOADR_8
1377 #define ASC_LIB_SCSIQ_WK_SP 256
1378 #define ASC_MAX_SYN_XFER_NO 16
1379 #define ASC_SYN_MAX_OFFSET 0x0F
1380 #define ASC_DEF_SDTR_OFFSET 0x0F
1381 #define ASC_DEF_SDTR_INDEX 0x00
1382 #define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
1383 #define SYN_XFER_NS_0 25
1384 #define SYN_XFER_NS_1 30
1385 #define SYN_XFER_NS_2 35
1386 #define SYN_XFER_NS_3 40
1387 #define SYN_XFER_NS_4 50
1388 #define SYN_XFER_NS_5 60
1389 #define SYN_XFER_NS_6 70
1390 #define SYN_XFER_NS_7 85
1391 #define SYN_ULTRA_XFER_NS_0 12
1392 #define SYN_ULTRA_XFER_NS_1 19
1393 #define SYN_ULTRA_XFER_NS_2 25
1394 #define SYN_ULTRA_XFER_NS_3 32
1395 #define SYN_ULTRA_XFER_NS_4 38
1396 #define SYN_ULTRA_XFER_NS_5 44
1397 #define SYN_ULTRA_XFER_NS_6 50
1398 #define SYN_ULTRA_XFER_NS_7 57
1399 #define SYN_ULTRA_XFER_NS_8 63
1400 #define SYN_ULTRA_XFER_NS_9 69
1401 #define SYN_ULTRA_XFER_NS_10 75
1402 #define SYN_ULTRA_XFER_NS_11 82
1403 #define SYN_ULTRA_XFER_NS_12 88
1404 #define SYN_ULTRA_XFER_NS_13 94
1405 #define SYN_ULTRA_XFER_NS_14 100
1406 #define SYN_ULTRA_XFER_NS_15 107
1408 typedef struct ext_msg {
1409 uchar msg_type;
1410 uchar msg_len;
1411 uchar msg_req;
1412 union {
1413 struct {
1414 uchar sdtr_xfer_period;
1415 uchar sdtr_req_ack_offset;
1416 } sdtr;
1417 struct {
1418 uchar wdtr_width;
1419 } wdtr;
1420 struct {
1421 uchar mdp_b3;
1422 uchar mdp_b2;
1423 uchar mdp_b1;
1424 uchar mdp_b0;
1425 } mdp;
1426 } u_ext_msg;
1427 uchar res;
1428 } EXT_MSG;
1430 #define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
1431 #define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
1432 #define wdtr_width u_ext_msg.wdtr.wdtr_width
1433 #define mdp_b3 u_ext_msg.mdp_b3
1434 #define mdp_b2 u_ext_msg.mdp_b2
1435 #define mdp_b1 u_ext_msg.mdp_b1
1436 #define mdp_b0 u_ext_msg.mdp_b0
1438 typedef struct asc_dvc_cfg {
1439 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1440 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1441 ASC_SCSI_BIT_ID_TYPE disc_enable;
1442 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1443 uchar chip_scsi_id;
1444 uchar isa_dma_speed;
1445 uchar isa_dma_channel;
1446 uchar chip_version;
1447 ushort lib_serial_no;
1448 ushort lib_version;
1449 ushort mcode_date;
1450 ushort mcode_version;
1451 uchar max_tag_qng[ASC_MAX_TID + 1];
1452 uchar *overrun_buf;
1453 uchar sdtr_period_offset[ASC_MAX_TID + 1];
1454 ushort pci_slot_info;
1455 uchar adapter_info[6];
1456 struct device *dev;
1457 } ASC_DVC_CFG;
1459 #define ASC_DEF_DVC_CNTL 0xFFFF
1460 #define ASC_DEF_CHIP_SCSI_ID 7
1461 #define ASC_DEF_ISA_DMA_SPEED 4
1462 #define ASC_INIT_STATE_NULL 0x0000
1463 #define ASC_INIT_STATE_BEG_GET_CFG 0x0001
1464 #define ASC_INIT_STATE_END_GET_CFG 0x0002
1465 #define ASC_INIT_STATE_BEG_SET_CFG 0x0004
1466 #define ASC_INIT_STATE_END_SET_CFG 0x0008
1467 #define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
1468 #define ASC_INIT_STATE_END_LOAD_MC 0x0020
1469 #define ASC_INIT_STATE_BEG_INQUIRY 0x0040
1470 #define ASC_INIT_STATE_END_INQUIRY 0x0080
1471 #define ASC_INIT_RESET_SCSI_DONE 0x0100
1472 #define ASC_INIT_STATE_WITHOUT_EEP 0x8000
1473 #define ASC_BUG_FIX_IF_NOT_DWB 0x0001
1474 #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
1475 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1476 #define ASC_MIN_TAGGED_CMD 7
1477 #define ASC_MAX_SCSI_RESET_WAIT 30
1479 struct asc_dvc_var; /* Forward Declaration. */
1481 typedef void (*ASC_ISR_CALLBACK) (struct asc_dvc_var *, ASC_QDONE_INFO *);
1482 typedef int (*ASC_EXE_CALLBACK) (struct asc_dvc_var *, ASC_SCSI_Q *);
1484 typedef struct asc_dvc_var {
1485 PortAddr iop_base;
1486 ushort err_code;
1487 ushort dvc_cntl;
1488 ushort bug_fix_cntl;
1489 ushort bus_type;
1490 ASC_ISR_CALLBACK isr_callback;
1491 ASC_EXE_CALLBACK exe_callback;
1492 ASC_SCSI_BIT_ID_TYPE init_sdtr;
1493 ASC_SCSI_BIT_ID_TYPE sdtr_done;
1494 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1495 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1496 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1497 ASC_SCSI_BIT_ID_TYPE start_motor;
1498 uchar scsi_reset_wait;
1499 uchar chip_no;
1500 char is_in_int;
1501 uchar max_total_qng;
1502 uchar cur_total_qng;
1503 uchar in_critical_cnt;
1504 uchar irq_no;
1505 uchar last_q_shortage;
1506 ushort init_state;
1507 uchar cur_dvc_qng[ASC_MAX_TID + 1];
1508 uchar max_dvc_qng[ASC_MAX_TID + 1];
1509 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
1510 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
1511 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1512 ASC_DVC_CFG *cfg;
1513 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1514 char redo_scam;
1515 ushort res2;
1516 uchar dos_int13_table[ASC_MAX_TID + 1];
1517 ASC_DCNT max_dma_count;
1518 ASC_SCSI_BIT_ID_TYPE no_scam;
1519 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1520 uchar max_sdtr_index;
1521 uchar host_init_sdtr_index;
1522 struct asc_board *drv_ptr;
1523 ASC_DCNT uc_break;
1524 } ASC_DVC_VAR;
1526 typedef struct asc_dvc_inq_info {
1527 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1528 } ASC_DVC_INQ_INFO;
1530 typedef struct asc_cap_info {
1531 ASC_DCNT lba;
1532 ASC_DCNT blk_size;
1533 } ASC_CAP_INFO;
1535 typedef struct asc_cap_info_array {
1536 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1537 } ASC_CAP_INFO_ARRAY;
1539 #define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
1540 #define ASC_MCNTL_NULL_TARGET (ushort)0x0002
1541 #define ASC_CNTL_INITIATOR (ushort)0x0001
1542 #define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
1543 #define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
1544 #define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
1545 #define ASC_CNTL_NO_SCAM (ushort)0x0010
1546 #define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
1547 #define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
1548 #define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
1549 #define ASC_CNTL_RESET_SCSI (ushort)0x0200
1550 #define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
1551 #define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
1552 #define ASC_CNTL_SCSI_PARITY (ushort)0x1000
1553 #define ASC_CNTL_BURST_MODE (ushort)0x2000
1554 #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1555 #define ASC_EEP_DVC_CFG_BEG_VL 2
1556 #define ASC_EEP_MAX_DVC_ADDR_VL 15
1557 #define ASC_EEP_DVC_CFG_BEG 32
1558 #define ASC_EEP_MAX_DVC_ADDR 45
1559 #define ASC_EEP_DEFINED_WORDS 10
1560 #define ASC_EEP_MAX_ADDR 63
1561 #define ASC_EEP_RES_WORDS 0
1562 #define ASC_EEP_MAX_RETRY 20
1563 #define ASC_MAX_INIT_BUSY_RETRY 8
1564 #define ASC_EEP_ISA_PNP_WSIZE 16
1567 * These macros keep the chip SCSI id and ISA DMA speed
1568 * bitfields in board order. C bitfields aren't portable
1569 * between big and little-endian platforms so they are
1570 * not used.
1573 #define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
1574 #define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
1575 #define ASC_EEP_SET_CHIP_ID(cfg, sid) \
1576 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
1577 #define ASC_EEP_SET_DMA_SPD(cfg, spd) \
1578 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
1580 typedef struct asceep_config {
1581 ushort cfg_lsw;
1582 ushort cfg_msw;
1583 uchar init_sdtr;
1584 uchar disc_enable;
1585 uchar use_cmd_qng;
1586 uchar start_motor;
1587 uchar max_total_qng;
1588 uchar max_tag_qng;
1589 uchar bios_scan;
1590 uchar power_up_wait;
1591 uchar no_scam;
1592 uchar id_speed; /* low order 4 bits is chip scsi id */
1593 /* high order 4 bits is isa dma speed */
1594 uchar dos_int13_table[ASC_MAX_TID + 1];
1595 uchar adapter_info[6];
1596 ushort cntl;
1597 ushort chksum;
1598 } ASCEEP_CONFIG;
1600 #define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800
1601 #define ASC_PCI_CFG_LSW_BURST_MODE 0x0080
1602 #define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020
1604 #define ASC_EEP_CMD_READ 0x80
1605 #define ASC_EEP_CMD_WRITE 0x40
1606 #define ASC_EEP_CMD_WRITE_ABLE 0x30
1607 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
1608 #define ASC_OVERRUN_BSIZE 0x00000048UL
1609 #define ASC_CTRL_BREAK_ONCE 0x0001
1610 #define ASC_CTRL_BREAK_STAY_IDLE 0x0002
1611 #define ASCV_MSGOUT_BEG 0x0000
1612 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1613 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1614 #define ASCV_BREAK_SAVED_CODE (ushort)0x0006
1615 #define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
1616 #define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
1617 #define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
1618 #define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
1619 #define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
1620 #define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
1621 #define ASCV_BREAK_ADDR (ushort)0x0028
1622 #define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
1623 #define ASCV_BREAK_CONTROL (ushort)0x002C
1624 #define ASCV_BREAK_HIT_COUNT (ushort)0x002E
1626 #define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
1627 #define ASCV_MCODE_CHKSUM_W (ushort)0x0032
1628 #define ASCV_MCODE_SIZE_W (ushort)0x0034
1629 #define ASCV_STOP_CODE_B (ushort)0x0036
1630 #define ASCV_DVC_ERR_CODE_B (ushort)0x0037
1631 #define ASCV_OVERRUN_PADDR_D (ushort)0x0038
1632 #define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
1633 #define ASCV_HALTCODE_W (ushort)0x0040
1634 #define ASCV_CHKSUM_W (ushort)0x0042
1635 #define ASCV_MC_DATE_W (ushort)0x0044
1636 #define ASCV_MC_VER_W (ushort)0x0046
1637 #define ASCV_NEXTRDY_B (ushort)0x0048
1638 #define ASCV_DONENEXT_B (ushort)0x0049
1639 #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1640 #define ASCV_SCSIBUSY_B (ushort)0x004B
1641 #define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
1642 #define ASCV_CURCDB_B (ushort)0x004D
1643 #define ASCV_RCLUN_B (ushort)0x004E
1644 #define ASCV_BUSY_QHEAD_B (ushort)0x004F
1645 #define ASCV_DISC1_QHEAD_B (ushort)0x0050
1646 #define ASCV_DISC_ENABLE_B (ushort)0x0052
1647 #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1648 #define ASCV_HOSTSCSI_ID_B (ushort)0x0055
1649 #define ASCV_MCODE_CNTL_B (ushort)0x0056
1650 #define ASCV_NULL_TARGET_B (ushort)0x0057
1651 #define ASCV_FREE_Q_HEAD_W (ushort)0x0058
1652 #define ASCV_DONE_Q_TAIL_W (ushort)0x005A
1653 #define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
1654 #define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
1655 #define ASCV_HOST_FLAG_B (ushort)0x005D
1656 #define ASCV_TOTAL_READY_Q_B (ushort)0x0064
1657 #define ASCV_VER_SERIAL_B (ushort)0x0065
1658 #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1659 #define ASCV_WTM_FLAG_B (ushort)0x0068
1660 #define ASCV_RISC_FLAG_B (ushort)0x006A
1661 #define ASCV_REQ_SG_LIST_QP (ushort)0x006B
1662 #define ASC_HOST_FLAG_IN_ISR 0x01
1663 #define ASC_HOST_FLAG_ACK_INT 0x02
1664 #define ASC_RISC_FLAG_GEN_INT 0x01
1665 #define ASC_RISC_FLAG_REQ_SG_LIST 0x02
1666 #define IOP_CTRL (0x0F)
1667 #define IOP_STATUS (0x0E)
1668 #define IOP_INT_ACK IOP_STATUS
1669 #define IOP_REG_IFC (0x0D)
1670 #define IOP_SYN_OFFSET (0x0B)
1671 #define IOP_EXTRA_CONTROL (0x0D)
1672 #define IOP_REG_PC (0x0C)
1673 #define IOP_RAM_ADDR (0x0A)
1674 #define IOP_RAM_DATA (0x08)
1675 #define IOP_EEP_DATA (0x06)
1676 #define IOP_EEP_CMD (0x07)
1677 #define IOP_VERSION (0x03)
1678 #define IOP_CONFIG_HIGH (0x04)
1679 #define IOP_CONFIG_LOW (0x02)
1680 #define IOP_SIG_BYTE (0x01)
1681 #define IOP_SIG_WORD (0x00)
1682 #define IOP_REG_DC1 (0x0E)
1683 #define IOP_REG_DC0 (0x0C)
1684 #define IOP_REG_SB (0x0B)
1685 #define IOP_REG_DA1 (0x0A)
1686 #define IOP_REG_DA0 (0x08)
1687 #define IOP_REG_SC (0x09)
1688 #define IOP_DMA_SPEED (0x07)
1689 #define IOP_REG_FLAG (0x07)
1690 #define IOP_FIFO_H (0x06)
1691 #define IOP_FIFO_L (0x04)
1692 #define IOP_REG_ID (0x05)
1693 #define IOP_REG_QP (0x03)
1694 #define IOP_REG_IH (0x02)
1695 #define IOP_REG_IX (0x01)
1696 #define IOP_REG_AX (0x00)
1697 #define IFC_REG_LOCK (0x00)
1698 #define IFC_REG_UNLOCK (0x09)
1699 #define IFC_WR_EN_FILTER (0x10)
1700 #define IFC_RD_NO_EEPROM (0x10)
1701 #define IFC_SLEW_RATE (0x20)
1702 #define IFC_ACT_NEG (0x40)
1703 #define IFC_INP_FILTER (0x80)
1704 #define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
1705 #define SC_SEL (uchar)(0x80)
1706 #define SC_BSY (uchar)(0x40)
1707 #define SC_ACK (uchar)(0x20)
1708 #define SC_REQ (uchar)(0x10)
1709 #define SC_ATN (uchar)(0x08)
1710 #define SC_IO (uchar)(0x04)
1711 #define SC_CD (uchar)(0x02)
1712 #define SC_MSG (uchar)(0x01)
1713 #define SEC_SCSI_CTL (uchar)(0x80)
1714 #define SEC_ACTIVE_NEGATE (uchar)(0x40)
1715 #define SEC_SLEW_RATE (uchar)(0x20)
1716 #define SEC_ENABLE_FILTER (uchar)(0x10)
1717 #define ASC_HALT_EXTMSG_IN (ushort)0x8000
1718 #define ASC_HALT_CHK_CONDITION (ushort)0x8100
1719 #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1720 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
1721 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
1722 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1723 #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1724 #define ASC_MAX_QNO 0xF8
1725 #define ASC_DATA_SEC_BEG (ushort)0x0080
1726 #define ASC_DATA_SEC_END (ushort)0x0080
1727 #define ASC_CODE_SEC_BEG (ushort)0x0080
1728 #define ASC_CODE_SEC_END (ushort)0x0080
1729 #define ASC_QADR_BEG (0x4000)
1730 #define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
1731 #define ASC_QADR_END (ushort)0x7FFF
1732 #define ASC_QLAST_ADR (ushort)0x7FC0
1733 #define ASC_QBLK_SIZE 0x40
1734 #define ASC_BIOS_DATA_QBEG 0xF8
1735 #define ASC_MIN_ACTIVE_QNO 0x01
1736 #define ASC_QLINK_END 0xFF
1737 #define ASC_EEPROM_WORDS 0x10
1738 #define ASC_MAX_MGS_LEN 0x10
1739 #define ASC_BIOS_ADDR_DEF 0xDC00
1740 #define ASC_BIOS_SIZE 0x3800
1741 #define ASC_BIOS_RAM_OFF 0x3800
1742 #define ASC_BIOS_RAM_SIZE 0x800
1743 #define ASC_BIOS_MIN_ADDR 0xC000
1744 #define ASC_BIOS_MAX_ADDR 0xEC00
1745 #define ASC_BIOS_BANK_SIZE 0x0400
1746 #define ASC_MCODE_START_ADDR 0x0080
1747 #define ASC_CFG0_HOST_INT_ON 0x0020
1748 #define ASC_CFG0_BIOS_ON 0x0040
1749 #define ASC_CFG0_VERA_BURST_ON 0x0080
1750 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
1751 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
1752 #define ASC_CFG1_LRAM_8BITS_ON 0x0800
1753 #define ASC_CFG_MSW_CLR_MASK 0x3080
1754 #define CSW_TEST1 (ASC_CS_TYPE)0x8000
1755 #define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
1756 #define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
1757 #define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
1758 #define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
1759 #define CSW_TEST2 (ASC_CS_TYPE)0x0400
1760 #define CSW_TEST3 (ASC_CS_TYPE)0x0200
1761 #define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
1762 #define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
1763 #define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
1764 #define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
1765 #define CSW_HALTED (ASC_CS_TYPE)0x0010
1766 #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1767 #define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
1768 #define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
1769 #define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
1770 #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1771 #define CIW_INT_ACK (ASC_CS_TYPE)0x0100
1772 #define CIW_TEST1 (ASC_CS_TYPE)0x0200
1773 #define CIW_TEST2 (ASC_CS_TYPE)0x0400
1774 #define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
1775 #define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
1776 #define CC_CHIP_RESET (uchar)0x80
1777 #define CC_SCSI_RESET (uchar)0x40
1778 #define CC_HALT (uchar)0x20
1779 #define CC_SINGLE_STEP (uchar)0x10
1780 #define CC_DMA_ABLE (uchar)0x08
1781 #define CC_TEST (uchar)0x04
1782 #define CC_BANK_ONE (uchar)0x02
1783 #define CC_DIAG (uchar)0x01
1784 #define ASC_1000_ID0W 0x04C1
1785 #define ASC_1000_ID0W_FIX 0x00C1
1786 #define ASC_1000_ID1B 0x25
1787 #define ASC_EISA_REV_IOP_MASK (0x0C83)
1788 #define ASC_EISA_PID_IOP_MASK (0x0C80)
1789 #define ASC_EISA_CFG_IOP_MASK (0x0C86)
1790 #define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
1791 #define INS_HALTINT (ushort)0x6281
1792 #define INS_HALT (ushort)0x6280
1793 #define INS_SINT (ushort)0x6200
1794 #define INS_RFLAG_WTM (ushort)0x7380
1795 #define ASC_MC_SAVE_CODE_WSIZE 0x500
1796 #define ASC_MC_SAVE_DATA_WSIZE 0x40
1798 typedef struct asc_mc_saved {
1799 ushort data[ASC_MC_SAVE_DATA_WSIZE];
1800 ushort code[ASC_MC_SAVE_CODE_WSIZE];
1801 } ASC_MC_SAVED;
1803 #define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1804 #define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1805 #define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1806 #define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1807 #define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1808 #define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1809 #define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
1810 #define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
1811 #define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1812 #define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1813 #define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1814 #define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1815 #define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1816 #define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1817 #define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1818 #define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
1819 #define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
1820 #define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
1821 #define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
1822 #define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
1823 #define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
1824 #define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
1825 #define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
1826 #define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
1827 #define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
1828 #define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
1829 #define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1830 #define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1831 #define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
1832 #define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
1833 #define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
1834 #define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
1835 #define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1836 #define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
1837 #define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
1838 #define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
1839 #define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
1840 #define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
1841 #define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
1842 #define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
1843 #define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1844 #define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1845 #define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
1846 #define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
1847 #define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
1848 #define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
1849 #define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
1850 #define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
1851 #define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
1852 #define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
1853 #define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
1854 #define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
1855 #define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
1856 #define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
1857 #define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
1858 #define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
1859 #define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
1860 #define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
1861 #define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
1862 #define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
1863 #define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
1864 #define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
1865 #define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
1866 #define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
1867 #define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
1868 #define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
1869 #define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
1870 #define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
1872 static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1873 static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1874 static void AscWaitEEPRead(void);
1875 static void AscWaitEEPWrite(void);
1876 static ushort AscReadEEPWord(PortAddr, uchar);
1877 static ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1878 static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1879 static int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1880 static int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1881 static int AscStartChip(PortAddr);
1882 static int AscStopChip(PortAddr);
1883 static void AscSetChipIH(PortAddr, ushort);
1884 static int AscIsChipHalted(PortAddr);
1885 static void AscAckInterrupt(PortAddr);
1886 static void AscDisableInterrupt(PortAddr);
1887 static void AscEnableInterrupt(PortAddr);
1888 static void AscSetBank(PortAddr, uchar);
1889 static int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1890 #ifdef CONFIG_ISA
1891 static ushort AscGetIsaDmaChannel(PortAddr);
1892 static ushort AscSetIsaDmaChannel(PortAddr, ushort);
1893 static uchar AscSetIsaDmaSpeed(PortAddr, uchar);
1894 static uchar AscGetIsaDmaSpeed(PortAddr);
1895 #endif /* CONFIG_ISA */
1896 static uchar AscReadLramByte(PortAddr, ushort);
1897 static ushort AscReadLramWord(PortAddr, ushort);
1898 #if CC_VERY_LONG_SG_LIST
1899 static ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1900 #endif /* CC_VERY_LONG_SG_LIST */
1901 static void AscWriteLramWord(PortAddr, ushort, ushort);
1902 static void AscWriteLramByte(PortAddr, ushort, uchar);
1903 static ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
1904 static void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1905 static void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1906 static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1907 static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
1908 static ushort AscInitAscDvcVar(ASC_DVC_VAR *);
1909 static ushort AscInitFromEEP(ASC_DVC_VAR *);
1910 static ushort AscInitFromAscDvcVar(ASC_DVC_VAR *);
1911 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1912 static int AscTestExternalLram(ASC_DVC_VAR *);
1913 static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1914 static uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1915 static void AscSetChipSDTR(PortAddr, uchar, uchar);
1916 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1917 static uchar AscAllocFreeQueue(PortAddr, uchar);
1918 static uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1919 static int AscHostReqRiscHalt(PortAddr);
1920 static int AscStopQueueExe(PortAddr);
1921 static int AscSendScsiQueue(ASC_DVC_VAR *,
1922 ASC_SCSI_Q *scsiq, uchar n_q_required);
1923 static int AscPutReadyQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1924 static int AscPutReadySgListQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1925 static int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1926 static int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1927 static ushort AscInitLram(ASC_DVC_VAR *);
1928 static ushort AscInitQLinkVar(ASC_DVC_VAR *);
1929 static int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1930 static int AscIsrChipHalted(ASC_DVC_VAR *);
1931 static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1932 ASC_QDONE_INFO *, ASC_DCNT);
1933 static int AscIsrQDone(ASC_DVC_VAR *);
1934 static int AscCompareString(uchar *, uchar *, int);
1935 #ifdef CONFIG_ISA
1936 static ushort AscGetEisaChipCfg(PortAddr);
1937 static PortAddr AscSearchIOPortAddr11(PortAddr);
1938 static PortAddr AscSearchIOPortAddr(PortAddr, ushort);
1939 static void AscSetISAPNPWaitForKey(void);
1940 #endif /* CONFIG_ISA */
1941 static uchar AscGetChipScsiCtrl(PortAddr);
1942 static uchar AscSetChipScsiID(PortAddr, uchar);
1943 static uchar AscGetChipVersion(PortAddr, ushort);
1944 static ushort AscGetChipBusType(PortAddr);
1945 static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
1946 static int AscFindSignature(PortAddr);
1947 static void AscToggleIRQAct(PortAddr);
1948 static uchar AscGetChipIRQ(PortAddr, ushort);
1949 static uchar AscSetChipIRQ(PortAddr, uchar, ushort);
1950 static ushort AscGetChipBiosAddress(PortAddr, ushort);
1951 static inline ulong DvcEnterCritical(void);
1952 static inline void DvcLeaveCritical(ulong);
1953 #ifdef CONFIG_PCI
1954 static uchar DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort);
1955 static void DvcWritePCIConfigByte(ASC_DVC_VAR *, ushort, uchar);
1956 #endif /* CONFIG_PCI */
1957 static ushort AscGetChipBiosAddress(PortAddr, ushort);
1958 static void DvcSleepMilliSecond(ASC_DCNT);
1959 static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
1960 static void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1961 static void DvcGetQinfo(PortAddr, ushort, uchar *, int);
1962 static ushort AscInitGetConfig(ASC_DVC_VAR *);
1963 static ushort AscInitSetConfig(ASC_DVC_VAR *);
1964 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
1965 static void AscAsyncFix(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *);
1966 static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
1967 static void AscInquiryHandling(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *);
1968 static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
1969 static int AscISR(ASC_DVC_VAR *);
1970 static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar);
1971 static int AscSgListToQueue(int);
1972 #ifdef CONFIG_ISA
1973 static void AscEnableIsaDma(uchar);
1974 #endif /* CONFIG_ISA */
1975 static ASC_DCNT AscGetMaxDmaCount(ushort);
1976 static const char *advansys_info(struct Scsi_Host *shost);
1979 * --- Adv Library Constants and Macros
1982 #define ADV_LIB_VERSION_MAJOR 5
1983 #define ADV_LIB_VERSION_MINOR 14
1986 * Define Adv Library required special types.
1990 * Portable Data Types
1992 * Any instance where a 32-bit long or pointer type is assumed
1993 * for precision or HW defined structures, the following define
1994 * types must be used. In Linux the char, short, and int types
1995 * are all consistent at 8, 16, and 32 bits respectively. Pointers
1996 * and long types are 64 bits on Alpha and UltraSPARC.
1998 #define ADV_PADDR __u32 /* Physical address data type. */
1999 #define ADV_VADDR __u32 /* Virtual address data type. */
2000 #define ADV_DCNT __u32 /* Unsigned Data count type. */
2001 #define ADV_SDCNT __s32 /* Signed Data count type. */
2004 * These macros are used to convert a virtual address to a
2005 * 32-bit value. This currently can be used on Linux Alpha
2006 * which uses 64-bit virtual address but a 32-bit bus address.
2007 * This is likely to break in the future, but doing this now
2008 * will give us time to change the HW and FW to handle 64-bit
2009 * addresses.
2011 #define ADV_VADDR_TO_U32 virt_to_bus
2012 #define ADV_U32_TO_VADDR bus_to_virt
2014 #define AdvPortAddr void __iomem * /* Virtual memory address size */
2017 * Define Adv Library required memory access macros.
2019 #define ADV_MEM_READB(addr) readb(addr)
2020 #define ADV_MEM_READW(addr) readw(addr)
2021 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
2022 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
2023 #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
2025 #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
2028 * For wide boards a CDB length maximum of 16 bytes
2029 * is supported.
2031 #define ADV_MAX_CDB_LEN 16
2034 * Define total number of simultaneous maximum element scatter-gather
2035 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
2036 * maximum number of outstanding commands per wide host adapter. Each
2037 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
2038 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
2039 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
2040 * structures or 255 scatter-gather elements.
2043 #define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
2046 * Define Adv Library required maximum number of scatter-gather
2047 * elements per request.
2049 #define ADV_MAX_SG_LIST 255
2051 /* Number of SG blocks needed. */
2052 #define ADV_NUM_SG_BLOCK \
2053 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
2055 /* Total contiguous memory needed for SG blocks. */
2056 #define ADV_SG_TOTAL_MEM_SIZE \
2057 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
2059 #define ADV_PAGE_SIZE PAGE_SIZE
2061 #define ADV_NUM_PAGE_CROSSING \
2062 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2064 #define ADV_EEP_DVC_CFG_BEGIN (0x00)
2065 #define ADV_EEP_DVC_CFG_END (0x15)
2066 #define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
2067 #define ADV_EEP_MAX_WORD_ADDR (0x1E)
2069 #define ADV_EEP_DELAY_MS 100
2071 #define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
2072 #define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
2074 * For the ASC3550 Bit 13 is Termination Polarity control bit.
2075 * For later ICs Bit 13 controls whether the CIS (Card Information
2076 * Service Section) is loaded from EEPROM.
2078 #define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
2079 #define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
2081 * ASC38C1600 Bit 11
2083 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
2084 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
2085 * Function 0 will specify INT B.
2087 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
2088 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
2089 * Function 1 will specify INT A.
2091 #define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
2093 typedef struct adveep_3550_config {
2094 /* Word Offset, Description */
2096 ushort cfg_lsw; /* 00 power up initialization */
2097 /* bit 13 set - Term Polarity Control */
2098 /* bit 14 set - BIOS Enable */
2099 /* bit 15 set - Big Endian Mode */
2100 ushort cfg_msw; /* 01 unused */
2101 ushort disc_enable; /* 02 disconnect enable */
2102 ushort wdtr_able; /* 03 Wide DTR able */
2103 ushort sdtr_able; /* 04 Synchronous DTR able */
2104 ushort start_motor; /* 05 send start up motor */
2105 ushort tagqng_able; /* 06 tag queuing able */
2106 ushort bios_scan; /* 07 BIOS device control */
2107 ushort scam_tolerant; /* 08 no scam */
2109 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2110 uchar bios_boot_delay; /* power up wait */
2112 uchar scsi_reset_delay; /* 10 reset delay */
2113 uchar bios_id_lun; /* first boot device scsi id & lun */
2114 /* high nibble is lun */
2115 /* low nibble is scsi id */
2117 uchar termination; /* 11 0 - automatic */
2118 /* 1 - low off / high off */
2119 /* 2 - low off / high on */
2120 /* 3 - low on / high on */
2121 /* There is no low on / high off */
2123 uchar reserved1; /* reserved byte (not used) */
2125 ushort bios_ctrl; /* 12 BIOS control bits */
2126 /* bit 0 BIOS don't act as initiator. */
2127 /* bit 1 BIOS > 1 GB support */
2128 /* bit 2 BIOS > 2 Disk Support */
2129 /* bit 3 BIOS don't support removables */
2130 /* bit 4 BIOS support bootable CD */
2131 /* bit 5 BIOS scan enabled */
2132 /* bit 6 BIOS support multiple LUNs */
2133 /* bit 7 BIOS display of message */
2134 /* bit 8 SCAM disabled */
2135 /* bit 9 Reset SCSI bus during init. */
2136 /* bit 10 */
2137 /* bit 11 No verbose initialization. */
2138 /* bit 12 SCSI parity enabled */
2139 /* bit 13 */
2140 /* bit 14 */
2141 /* bit 15 */
2142 ushort ultra_able; /* 13 ULTRA speed able */
2143 ushort reserved2; /* 14 reserved */
2144 uchar max_host_qng; /* 15 maximum host queuing */
2145 uchar max_dvc_qng; /* maximum per device queuing */
2146 ushort dvc_cntl; /* 16 control bit for driver */
2147 ushort bug_fix; /* 17 control bit for bug fix */
2148 ushort serial_number_word1; /* 18 Board serial number word 1 */
2149 ushort serial_number_word2; /* 19 Board serial number word 2 */
2150 ushort serial_number_word3; /* 20 Board serial number word 3 */
2151 ushort check_sum; /* 21 EEP check sum */
2152 uchar oem_name[16]; /* 22 OEM name */
2153 ushort dvc_err_code; /* 30 last device driver error code */
2154 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2155 ushort adv_err_addr; /* 32 last uc error address */
2156 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2157 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2158 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2159 ushort num_of_err; /* 36 number of error */
2160 } ADVEEP_3550_CONFIG;
2162 typedef struct adveep_38C0800_config {
2163 /* Word Offset, Description */
2165 ushort cfg_lsw; /* 00 power up initialization */
2166 /* bit 13 set - Load CIS */
2167 /* bit 14 set - BIOS Enable */
2168 /* bit 15 set - Big Endian Mode */
2169 ushort cfg_msw; /* 01 unused */
2170 ushort disc_enable; /* 02 disconnect enable */
2171 ushort wdtr_able; /* 03 Wide DTR able */
2172 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2173 ushort start_motor; /* 05 send start up motor */
2174 ushort tagqng_able; /* 06 tag queuing able */
2175 ushort bios_scan; /* 07 BIOS device control */
2176 ushort scam_tolerant; /* 08 no scam */
2178 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2179 uchar bios_boot_delay; /* power up wait */
2181 uchar scsi_reset_delay; /* 10 reset delay */
2182 uchar bios_id_lun; /* first boot device scsi id & lun */
2183 /* high nibble is lun */
2184 /* low nibble is scsi id */
2186 uchar termination_se; /* 11 0 - automatic */
2187 /* 1 - low off / high off */
2188 /* 2 - low off / high on */
2189 /* 3 - low on / high on */
2190 /* There is no low on / high off */
2192 uchar termination_lvd; /* 11 0 - automatic */
2193 /* 1 - low off / high off */
2194 /* 2 - low off / high on */
2195 /* 3 - low on / high on */
2196 /* There is no low on / high off */
2198 ushort bios_ctrl; /* 12 BIOS control bits */
2199 /* bit 0 BIOS don't act as initiator. */
2200 /* bit 1 BIOS > 1 GB support */
2201 /* bit 2 BIOS > 2 Disk Support */
2202 /* bit 3 BIOS don't support removables */
2203 /* bit 4 BIOS support bootable CD */
2204 /* bit 5 BIOS scan enabled */
2205 /* bit 6 BIOS support multiple LUNs */
2206 /* bit 7 BIOS display of message */
2207 /* bit 8 SCAM disabled */
2208 /* bit 9 Reset SCSI bus during init. */
2209 /* bit 10 */
2210 /* bit 11 No verbose initialization. */
2211 /* bit 12 SCSI parity enabled */
2212 /* bit 13 */
2213 /* bit 14 */
2214 /* bit 15 */
2215 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2216 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2217 uchar max_host_qng; /* 15 maximum host queueing */
2218 uchar max_dvc_qng; /* maximum per device queuing */
2219 ushort dvc_cntl; /* 16 control bit for driver */
2220 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2221 ushort serial_number_word1; /* 18 Board serial number word 1 */
2222 ushort serial_number_word2; /* 19 Board serial number word 2 */
2223 ushort serial_number_word3; /* 20 Board serial number word 3 */
2224 ushort check_sum; /* 21 EEP check sum */
2225 uchar oem_name[16]; /* 22 OEM name */
2226 ushort dvc_err_code; /* 30 last device driver error code */
2227 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2228 ushort adv_err_addr; /* 32 last uc error address */
2229 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2230 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2231 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2232 ushort reserved36; /* 36 reserved */
2233 ushort reserved37; /* 37 reserved */
2234 ushort reserved38; /* 38 reserved */
2235 ushort reserved39; /* 39 reserved */
2236 ushort reserved40; /* 40 reserved */
2237 ushort reserved41; /* 41 reserved */
2238 ushort reserved42; /* 42 reserved */
2239 ushort reserved43; /* 43 reserved */
2240 ushort reserved44; /* 44 reserved */
2241 ushort reserved45; /* 45 reserved */
2242 ushort reserved46; /* 46 reserved */
2243 ushort reserved47; /* 47 reserved */
2244 ushort reserved48; /* 48 reserved */
2245 ushort reserved49; /* 49 reserved */
2246 ushort reserved50; /* 50 reserved */
2247 ushort reserved51; /* 51 reserved */
2248 ushort reserved52; /* 52 reserved */
2249 ushort reserved53; /* 53 reserved */
2250 ushort reserved54; /* 54 reserved */
2251 ushort reserved55; /* 55 reserved */
2252 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2253 ushort cisprt_msw; /* 57 CIS PTR MSW */
2254 ushort subsysvid; /* 58 SubSystem Vendor ID */
2255 ushort subsysid; /* 59 SubSystem ID */
2256 ushort reserved60; /* 60 reserved */
2257 ushort reserved61; /* 61 reserved */
2258 ushort reserved62; /* 62 reserved */
2259 ushort reserved63; /* 63 reserved */
2260 } ADVEEP_38C0800_CONFIG;
2262 typedef struct adveep_38C1600_config {
2263 /* Word Offset, Description */
2265 ushort cfg_lsw; /* 00 power up initialization */
2266 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
2267 /* clear - Func. 0 INTA, Func. 1 INTB */
2268 /* bit 13 set - Load CIS */
2269 /* bit 14 set - BIOS Enable */
2270 /* bit 15 set - Big Endian Mode */
2271 ushort cfg_msw; /* 01 unused */
2272 ushort disc_enable; /* 02 disconnect enable */
2273 ushort wdtr_able; /* 03 Wide DTR able */
2274 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2275 ushort start_motor; /* 05 send start up motor */
2276 ushort tagqng_able; /* 06 tag queuing able */
2277 ushort bios_scan; /* 07 BIOS device control */
2278 ushort scam_tolerant; /* 08 no scam */
2280 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2281 uchar bios_boot_delay; /* power up wait */
2283 uchar scsi_reset_delay; /* 10 reset delay */
2284 uchar bios_id_lun; /* first boot device scsi id & lun */
2285 /* high nibble is lun */
2286 /* low nibble is scsi id */
2288 uchar termination_se; /* 11 0 - automatic */
2289 /* 1 - low off / high off */
2290 /* 2 - low off / high on */
2291 /* 3 - low on / high on */
2292 /* There is no low on / high off */
2294 uchar termination_lvd; /* 11 0 - automatic */
2295 /* 1 - low off / high off */
2296 /* 2 - low off / high on */
2297 /* 3 - low on / high on */
2298 /* There is no low on / high off */
2300 ushort bios_ctrl; /* 12 BIOS control bits */
2301 /* bit 0 BIOS don't act as initiator. */
2302 /* bit 1 BIOS > 1 GB support */
2303 /* bit 2 BIOS > 2 Disk Support */
2304 /* bit 3 BIOS don't support removables */
2305 /* bit 4 BIOS support bootable CD */
2306 /* bit 5 BIOS scan enabled */
2307 /* bit 6 BIOS support multiple LUNs */
2308 /* bit 7 BIOS display of message */
2309 /* bit 8 SCAM disabled */
2310 /* bit 9 Reset SCSI bus during init. */
2311 /* bit 10 Basic Integrity Checking disabled */
2312 /* bit 11 No verbose initialization. */
2313 /* bit 12 SCSI parity enabled */
2314 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
2315 /* bit 14 */
2316 /* bit 15 */
2317 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2318 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2319 uchar max_host_qng; /* 15 maximum host queueing */
2320 uchar max_dvc_qng; /* maximum per device queuing */
2321 ushort dvc_cntl; /* 16 control bit for driver */
2322 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2323 ushort serial_number_word1; /* 18 Board serial number word 1 */
2324 ushort serial_number_word2; /* 19 Board serial number word 2 */
2325 ushort serial_number_word3; /* 20 Board serial number word 3 */
2326 ushort check_sum; /* 21 EEP check sum */
2327 uchar oem_name[16]; /* 22 OEM name */
2328 ushort dvc_err_code; /* 30 last device driver error code */
2329 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2330 ushort adv_err_addr; /* 32 last uc error address */
2331 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2332 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2333 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2334 ushort reserved36; /* 36 reserved */
2335 ushort reserved37; /* 37 reserved */
2336 ushort reserved38; /* 38 reserved */
2337 ushort reserved39; /* 39 reserved */
2338 ushort reserved40; /* 40 reserved */
2339 ushort reserved41; /* 41 reserved */
2340 ushort reserved42; /* 42 reserved */
2341 ushort reserved43; /* 43 reserved */
2342 ushort reserved44; /* 44 reserved */
2343 ushort reserved45; /* 45 reserved */
2344 ushort reserved46; /* 46 reserved */
2345 ushort reserved47; /* 47 reserved */
2346 ushort reserved48; /* 48 reserved */
2347 ushort reserved49; /* 49 reserved */
2348 ushort reserved50; /* 50 reserved */
2349 ushort reserved51; /* 51 reserved */
2350 ushort reserved52; /* 52 reserved */
2351 ushort reserved53; /* 53 reserved */
2352 ushort reserved54; /* 54 reserved */
2353 ushort reserved55; /* 55 reserved */
2354 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2355 ushort cisprt_msw; /* 57 CIS PTR MSW */
2356 ushort subsysvid; /* 58 SubSystem Vendor ID */
2357 ushort subsysid; /* 59 SubSystem ID */
2358 ushort reserved60; /* 60 reserved */
2359 ushort reserved61; /* 61 reserved */
2360 ushort reserved62; /* 62 reserved */
2361 ushort reserved63; /* 63 reserved */
2362 } ADVEEP_38C1600_CONFIG;
2365 * EEPROM Commands
2367 #define ASC_EEP_CMD_DONE 0x0200
2368 #define ASC_EEP_CMD_DONE_ERR 0x0001
2370 /* cfg_word */
2371 #define EEP_CFG_WORD_BIG_ENDIAN 0x8000
2373 /* bios_ctrl */
2374 #define BIOS_CTRL_BIOS 0x0001
2375 #define BIOS_CTRL_EXTENDED_XLAT 0x0002
2376 #define BIOS_CTRL_GT_2_DISK 0x0004
2377 #define BIOS_CTRL_BIOS_REMOVABLE 0x0008
2378 #define BIOS_CTRL_BOOTABLE_CD 0x0010
2379 #define BIOS_CTRL_MULTIPLE_LUN 0x0040
2380 #define BIOS_CTRL_DISPLAY_MSG 0x0080
2381 #define BIOS_CTRL_NO_SCAM 0x0100
2382 #define BIOS_CTRL_RESET_SCSI_BUS 0x0200
2383 #define BIOS_CTRL_INIT_VERBOSE 0x0800
2384 #define BIOS_CTRL_SCSI_PARITY 0x1000
2385 #define BIOS_CTRL_AIPP_DIS 0x2000
2387 #define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
2388 #define ADV_3550_IOLEN 0x40 /* I/O Port Range in bytes */
2390 #define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2391 #define ADV_38C0800_IOLEN 0x100 /* I/O Port Range in bytes */
2394 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
2395 * a special 16K Adv Library and Microcode version. After the issue is
2396 * resolved, should restore 32K support.
2398 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
2400 #define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2401 #define ADV_38C1600_IOLEN 0x100 /* I/O Port Range 256 bytes */
2402 #define ADV_38C1600_MEMLEN 0x1000 /* Memory Range 4KB bytes */
2405 * Byte I/O register address from base of 'iop_base'.
2407 #define IOPB_INTR_STATUS_REG 0x00
2408 #define IOPB_CHIP_ID_1 0x01
2409 #define IOPB_INTR_ENABLES 0x02
2410 #define IOPB_CHIP_TYPE_REV 0x03
2411 #define IOPB_RES_ADDR_4 0x04
2412 #define IOPB_RES_ADDR_5 0x05
2413 #define IOPB_RAM_DATA 0x06
2414 #define IOPB_RES_ADDR_7 0x07
2415 #define IOPB_FLAG_REG 0x08
2416 #define IOPB_RES_ADDR_9 0x09
2417 #define IOPB_RISC_CSR 0x0A
2418 #define IOPB_RES_ADDR_B 0x0B
2419 #define IOPB_RES_ADDR_C 0x0C
2420 #define IOPB_RES_ADDR_D 0x0D
2421 #define IOPB_SOFT_OVER_WR 0x0E
2422 #define IOPB_RES_ADDR_F 0x0F
2423 #define IOPB_MEM_CFG 0x10
2424 #define IOPB_RES_ADDR_11 0x11
2425 #define IOPB_GPIO_DATA 0x12
2426 #define IOPB_RES_ADDR_13 0x13
2427 #define IOPB_FLASH_PAGE 0x14
2428 #define IOPB_RES_ADDR_15 0x15
2429 #define IOPB_GPIO_CNTL 0x16
2430 #define IOPB_RES_ADDR_17 0x17
2431 #define IOPB_FLASH_DATA 0x18
2432 #define IOPB_RES_ADDR_19 0x19
2433 #define IOPB_RES_ADDR_1A 0x1A
2434 #define IOPB_RES_ADDR_1B 0x1B
2435 #define IOPB_RES_ADDR_1C 0x1C
2436 #define IOPB_RES_ADDR_1D 0x1D
2437 #define IOPB_RES_ADDR_1E 0x1E
2438 #define IOPB_RES_ADDR_1F 0x1F
2439 #define IOPB_DMA_CFG0 0x20
2440 #define IOPB_DMA_CFG1 0x21
2441 #define IOPB_TICKLE 0x22
2442 #define IOPB_DMA_REG_WR 0x23
2443 #define IOPB_SDMA_STATUS 0x24
2444 #define IOPB_SCSI_BYTE_CNT 0x25
2445 #define IOPB_HOST_BYTE_CNT 0x26
2446 #define IOPB_BYTE_LEFT_TO_XFER 0x27
2447 #define IOPB_BYTE_TO_XFER_0 0x28
2448 #define IOPB_BYTE_TO_XFER_1 0x29
2449 #define IOPB_BYTE_TO_XFER_2 0x2A
2450 #define IOPB_BYTE_TO_XFER_3 0x2B
2451 #define IOPB_ACC_GRP 0x2C
2452 #define IOPB_RES_ADDR_2D 0x2D
2453 #define IOPB_DEV_ID 0x2E
2454 #define IOPB_RES_ADDR_2F 0x2F
2455 #define IOPB_SCSI_DATA 0x30
2456 #define IOPB_RES_ADDR_31 0x31
2457 #define IOPB_RES_ADDR_32 0x32
2458 #define IOPB_SCSI_DATA_HSHK 0x33
2459 #define IOPB_SCSI_CTRL 0x34
2460 #define IOPB_RES_ADDR_35 0x35
2461 #define IOPB_RES_ADDR_36 0x36
2462 #define IOPB_RES_ADDR_37 0x37
2463 #define IOPB_RAM_BIST 0x38
2464 #define IOPB_PLL_TEST 0x39
2465 #define IOPB_PCI_INT_CFG 0x3A
2466 #define IOPB_RES_ADDR_3B 0x3B
2467 #define IOPB_RFIFO_CNT 0x3C
2468 #define IOPB_RES_ADDR_3D 0x3D
2469 #define IOPB_RES_ADDR_3E 0x3E
2470 #define IOPB_RES_ADDR_3F 0x3F
2473 * Word I/O register address from base of 'iop_base'.
2475 #define IOPW_CHIP_ID_0 0x00 /* CID0 */
2476 #define IOPW_CTRL_REG 0x02 /* CC */
2477 #define IOPW_RAM_ADDR 0x04 /* LA */
2478 #define IOPW_RAM_DATA 0x06 /* LD */
2479 #define IOPW_RES_ADDR_08 0x08
2480 #define IOPW_RISC_CSR 0x0A /* CSR */
2481 #define IOPW_SCSI_CFG0 0x0C /* CFG0 */
2482 #define IOPW_SCSI_CFG1 0x0E /* CFG1 */
2483 #define IOPW_RES_ADDR_10 0x10
2484 #define IOPW_SEL_MASK 0x12 /* SM */
2485 #define IOPW_RES_ADDR_14 0x14
2486 #define IOPW_FLASH_ADDR 0x16 /* FA */
2487 #define IOPW_RES_ADDR_18 0x18
2488 #define IOPW_EE_CMD 0x1A /* EC */
2489 #define IOPW_EE_DATA 0x1C /* ED */
2490 #define IOPW_SFIFO_CNT 0x1E /* SFC */
2491 #define IOPW_RES_ADDR_20 0x20
2492 #define IOPW_Q_BASE 0x22 /* QB */
2493 #define IOPW_QP 0x24 /* QP */
2494 #define IOPW_IX 0x26 /* IX */
2495 #define IOPW_SP 0x28 /* SP */
2496 #define IOPW_PC 0x2A /* PC */
2497 #define IOPW_RES_ADDR_2C 0x2C
2498 #define IOPW_RES_ADDR_2E 0x2E
2499 #define IOPW_SCSI_DATA 0x30 /* SD */
2500 #define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
2501 #define IOPW_SCSI_CTRL 0x34 /* SC */
2502 #define IOPW_HSHK_CFG 0x36 /* HCFG */
2503 #define IOPW_SXFR_STATUS 0x36 /* SXS */
2504 #define IOPW_SXFR_CNTL 0x38 /* SXL */
2505 #define IOPW_SXFR_CNTH 0x3A /* SXH */
2506 #define IOPW_RES_ADDR_3C 0x3C
2507 #define IOPW_RFIFO_DATA 0x3E /* RFD */
2510 * Doubleword I/O register address from base of 'iop_base'.
2512 #define IOPDW_RES_ADDR_0 0x00
2513 #define IOPDW_RAM_DATA 0x04
2514 #define IOPDW_RES_ADDR_8 0x08
2515 #define IOPDW_RES_ADDR_C 0x0C
2516 #define IOPDW_RES_ADDR_10 0x10
2517 #define IOPDW_COMMA 0x14
2518 #define IOPDW_COMMB 0x18
2519 #define IOPDW_RES_ADDR_1C 0x1C
2520 #define IOPDW_SDMA_ADDR0 0x20
2521 #define IOPDW_SDMA_ADDR1 0x24
2522 #define IOPDW_SDMA_COUNT 0x28
2523 #define IOPDW_SDMA_ERROR 0x2C
2524 #define IOPDW_RDMA_ADDR0 0x30
2525 #define IOPDW_RDMA_ADDR1 0x34
2526 #define IOPDW_RDMA_COUNT 0x38
2527 #define IOPDW_RDMA_ERROR 0x3C
2529 #define ADV_CHIP_ID_BYTE 0x25
2530 #define ADV_CHIP_ID_WORD 0x04C1
2532 #define ADV_SC_SCSI_BUS_RESET 0x2000
2534 #define ADV_INTR_ENABLE_HOST_INTR 0x01
2535 #define ADV_INTR_ENABLE_SEL_INTR 0x02
2536 #define ADV_INTR_ENABLE_DPR_INTR 0x04
2537 #define ADV_INTR_ENABLE_RTA_INTR 0x08
2538 #define ADV_INTR_ENABLE_RMA_INTR 0x10
2539 #define ADV_INTR_ENABLE_RST_INTR 0x20
2540 #define ADV_INTR_ENABLE_DPE_INTR 0x40
2541 #define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
2543 #define ADV_INTR_STATUS_INTRA 0x01
2544 #define ADV_INTR_STATUS_INTRB 0x02
2545 #define ADV_INTR_STATUS_INTRC 0x04
2547 #define ADV_RISC_CSR_STOP (0x0000)
2548 #define ADV_RISC_TEST_COND (0x2000)
2549 #define ADV_RISC_CSR_RUN (0x4000)
2550 #define ADV_RISC_CSR_SINGLE_STEP (0x8000)
2552 #define ADV_CTRL_REG_HOST_INTR 0x0100
2553 #define ADV_CTRL_REG_SEL_INTR 0x0200
2554 #define ADV_CTRL_REG_DPR_INTR 0x0400
2555 #define ADV_CTRL_REG_RTA_INTR 0x0800
2556 #define ADV_CTRL_REG_RMA_INTR 0x1000
2557 #define ADV_CTRL_REG_RES_BIT14 0x2000
2558 #define ADV_CTRL_REG_DPE_INTR 0x4000
2559 #define ADV_CTRL_REG_POWER_DONE 0x8000
2560 #define ADV_CTRL_REG_ANY_INTR 0xFF00
2562 #define ADV_CTRL_REG_CMD_RESET 0x00C6
2563 #define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
2564 #define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
2565 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
2566 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
2568 #define ADV_TICKLE_NOP 0x00
2569 #define ADV_TICKLE_A 0x01
2570 #define ADV_TICKLE_B 0x02
2571 #define ADV_TICKLE_C 0x03
2573 #define ADV_SCSI_CTRL_RSTOUT 0x2000
2575 #define AdvIsIntPending(port) \
2576 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2579 * SCSI_CFG0 Register bit definitions
2581 #define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
2582 #define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
2583 #define EVEN_PARITY 0x1000 /* Select Even Parity */
2584 #define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2585 #define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
2586 #define PRIM_MODE 0x0100 /* Primitive SCSI mode */
2587 #define SCAM_EN 0x0080 /* Enable SCAM selection */
2588 #define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2589 #define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2590 #define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
2591 #define OUR_ID 0x000F /* SCSI ID */
2594 * SCSI_CFG1 Register bit definitions
2596 #define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
2597 #define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2598 #define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
2599 #define FILTER_SEL 0x0C00 /* Filter Period Selection */
2600 #define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
2601 #define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
2602 #define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
2603 #define ACTIVE_DBL 0x0200 /* Disable Active Negation */
2604 #define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
2605 #define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
2606 #define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
2607 #define TERM_CTL 0x0030 /* External SCSI Termination Bits */
2608 #define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
2609 #define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
2610 #define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
2613 * Addendum for ASC-38C0800 Chip
2615 * The ASC-38C1600 Chip uses the same definitions except that the
2616 * bus mode override bits [12:10] have been moved to byte register
2617 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
2618 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
2619 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
2620 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
2621 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
2623 #define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
2624 #define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
2625 #define HVD 0x1000 /* HVD Device Detect */
2626 #define LVD 0x0800 /* LVD Device Detect */
2627 #define SE 0x0400 /* SE Device Detect */
2628 #define TERM_LVD 0x00C0 /* LVD Termination Bits */
2629 #define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
2630 #define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
2631 #define TERM_SE 0x0030 /* SE Termination Bits */
2632 #define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
2633 #define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
2634 #define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
2635 #define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
2636 #define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
2637 #define C_DET_SE 0x0003 /* SE Cable Detect Bits */
2638 #define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
2639 #define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
2641 #define CABLE_ILLEGAL_A 0x7
2642 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
2644 #define CABLE_ILLEGAL_B 0xB
2645 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
2648 * MEM_CFG Register bit definitions
2650 #define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
2651 #define FAST_EE_CLK 0x20 /* Diagnostic Bit */
2652 #define RAM_SZ 0x1C /* Specify size of RAM to RISC */
2653 #define RAM_SZ_2KB 0x00 /* 2 KB */
2654 #define RAM_SZ_4KB 0x04 /* 4 KB */
2655 #define RAM_SZ_8KB 0x08 /* 8 KB */
2656 #define RAM_SZ_16KB 0x0C /* 16 KB */
2657 #define RAM_SZ_32KB 0x10 /* 32 KB */
2658 #define RAM_SZ_64KB 0x14 /* 64 KB */
2661 * DMA_CFG0 Register bit definitions
2663 * This register is only accessible to the host.
2665 #define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
2666 #define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
2667 #define FIFO_THRESH_16B 0x00 /* 16 bytes */
2668 #define FIFO_THRESH_32B 0x20 /* 32 bytes */
2669 #define FIFO_THRESH_48B 0x30 /* 48 bytes */
2670 #define FIFO_THRESH_64B 0x40 /* 64 bytes */
2671 #define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
2672 #define FIFO_THRESH_96B 0x60 /* 96 bytes */
2673 #define FIFO_THRESH_112B 0x70 /* 112 bytes */
2674 #define START_CTL 0x0C /* DMA start conditions */
2675 #define START_CTL_TH 0x00 /* Wait threshold level (default) */
2676 #define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
2677 #define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
2678 #define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
2679 #define READ_CMD 0x03 /* Memory Read Method */
2680 #define READ_CMD_MR 0x00 /* Memory Read */
2681 #define READ_CMD_MRL 0x02 /* Memory Read Long */
2682 #define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
2685 * ASC-38C0800 RAM BIST Register bit definitions
2687 #define RAM_TEST_MODE 0x80
2688 #define PRE_TEST_MODE 0x40
2689 #define NORMAL_MODE 0x00
2690 #define RAM_TEST_DONE 0x10
2691 #define RAM_TEST_STATUS 0x0F
2692 #define RAM_TEST_HOST_ERROR 0x08
2693 #define RAM_TEST_INTRAM_ERROR 0x04
2694 #define RAM_TEST_RISC_ERROR 0x02
2695 #define RAM_TEST_SCSI_ERROR 0x01
2696 #define RAM_TEST_SUCCESS 0x00
2697 #define PRE_TEST_VALUE 0x05
2698 #define NORMAL_VALUE 0x00
2701 * ASC38C1600 Definitions
2703 * IOPB_PCI_INT_CFG Bit Field Definitions
2706 #define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
2709 * Bit 1 can be set to change the interrupt for the Function to operate in
2710 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
2711 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
2712 * mode, otherwise the operating mode is undefined.
2714 #define TOTEMPOLE 0x02
2717 * Bit 0 can be used to change the Int Pin for the Function. The value is
2718 * 0 by default for both Functions with Function 0 using INT A and Function
2719 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
2720 * INT A is used.
2722 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
2723 * value specified in the PCI Configuration Space.
2725 #define INTAB 0x01
2727 /* a_advlib.h */
2730 * Adv Library Status Definitions
2732 #define ADV_TRUE 1
2733 #define ADV_FALSE 0
2734 #define ADV_NOERROR 1
2735 #define ADV_SUCCESS 1
2736 #define ADV_BUSY 0
2737 #define ADV_ERROR (-1)
2740 * ADV_DVC_VAR 'warn_code' values
2742 #define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
2743 #define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
2744 #define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
2745 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */
2746 #define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
2748 #define ADV_MAX_TID 15 /* max. target identifier */
2749 #define ADV_MAX_LUN 7 /* max. logical unit number */
2752 * Error code values are set in ADV_DVC_VAR 'err_code'.
2754 #define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */
2755 #define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
2756 #define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */
2757 #define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
2758 #define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */
2759 #define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
2760 #define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */
2761 #define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
2762 #define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
2763 #define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */
2764 #define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */
2765 #define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */
2766 #define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */
2767 #define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */
2770 * Fixed locations of microcode operating variables.
2772 #define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
2773 #define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
2774 #define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
2775 #define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
2776 #define ASC_MC_VERSION_NUM 0x003A /* microcode number */
2777 #define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
2778 #define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
2779 #define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
2780 #define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
2781 #define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
2782 #define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
2783 #define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
2784 #define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
2785 #define ASC_MC_CHIP_TYPE 0x009A
2786 #define ASC_MC_INTRB_CODE 0x009B
2787 #define ASC_MC_WDTR_ABLE 0x009C
2788 #define ASC_MC_SDTR_ABLE 0x009E
2789 #define ASC_MC_TAGQNG_ABLE 0x00A0
2790 #define ASC_MC_DISC_ENABLE 0x00A2
2791 #define ASC_MC_IDLE_CMD_STATUS 0x00A4
2792 #define ASC_MC_IDLE_CMD 0x00A6
2793 #define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
2794 #define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
2795 #define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
2796 #define ASC_MC_DEFAULT_MEM_CFG 0x00B0
2797 #define ASC_MC_DEFAULT_SEL_MASK 0x00B2
2798 #define ASC_MC_SDTR_DONE 0x00B6
2799 #define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
2800 #define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
2801 #define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
2802 #define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
2803 #define ASC_MC_WDTR_DONE 0x0124
2804 #define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
2805 #define ASC_MC_ICQ 0x0160
2806 #define ASC_MC_IRQ 0x0164
2807 #define ASC_MC_PPR_ABLE 0x017A
2810 * BIOS LRAM variable absolute offsets.
2812 #define BIOS_CODESEG 0x54
2813 #define BIOS_CODELEN 0x56
2814 #define BIOS_SIGNATURE 0x58
2815 #define BIOS_VERSION 0x5A
2818 * Microcode Control Flags
2820 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2821 * and handled by the microcode.
2823 #define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
2824 #define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
2827 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2829 #define HSHK_CFG_WIDE_XFR 0x8000
2830 #define HSHK_CFG_RATE 0x0F00
2831 #define HSHK_CFG_OFFSET 0x001F
2833 #define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
2834 #define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
2835 #define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
2836 #define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
2838 #define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2839 #define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
2840 #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2841 #define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
2842 #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2844 #define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
2845 #define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
2846 #define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
2847 #define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
2848 #define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
2850 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
2851 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
2853 #define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
2854 #define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
2857 * All fields here are accessed by the board microcode and need to be
2858 * little-endian.
2860 typedef struct adv_carr_t {
2861 ADV_VADDR carr_va; /* Carrier Virtual Address */
2862 ADV_PADDR carr_pa; /* Carrier Physical Address */
2863 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
2865 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
2867 * next_vpa [3:1] Reserved Bits
2868 * next_vpa [0] Done Flag set in Response Queue.
2870 ADV_VADDR next_vpa;
2871 } ADV_CARR_T;
2874 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2876 #define ASC_NEXT_VPA_MASK 0xFFFFFFF0
2878 #define ASC_RQ_DONE 0x00000001
2879 #define ASC_RQ_GOOD 0x00000002
2880 #define ASC_CQ_STOPPER 0x00000000
2882 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2884 #define ADV_CARRIER_NUM_PAGE_CROSSING \
2885 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2886 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2888 #define ADV_CARRIER_BUFSIZE \
2889 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2892 * ASC_SCSI_REQ_Q 'a_flag' definitions
2894 * The Adv Library should limit use to the lower nibble (4 bits) of
2895 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2897 #define ADV_POLL_REQUEST 0x01 /* poll for request completion */
2898 #define ADV_SCSIQ_DONE 0x02 /* request done */
2899 #define ADV_DONT_RETRY 0x08 /* don't do retry */
2901 #define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
2902 #define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
2903 #define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
2906 * Adapter temporary configuration structure
2908 * This structure can be discarded after initialization. Don't add
2909 * fields here needed after initialization.
2911 * Field naming convention:
2913 * *_enable indicates the field enables or disables a feature. The
2914 * value of the field is never reset.
2916 typedef struct adv_dvc_cfg {
2917 ushort disc_enable; /* enable disconnection */
2918 uchar chip_version; /* chip version */
2919 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2920 ushort lib_version; /* Adv Library version number */
2921 ushort control_flag; /* Microcode Control Flag */
2922 ushort mcode_date; /* Microcode date */
2923 ushort mcode_version; /* Microcode version */
2924 ushort pci_slot_info; /* high byte device/function number */
2925 /* bits 7-3 device num., bits 2-0 function num. */
2926 /* low byte bus num. */
2927 ushort serial1; /* EEPROM serial number word 1 */
2928 ushort serial2; /* EEPROM serial number word 2 */
2929 ushort serial3; /* EEPROM serial number word 3 */
2930 struct device *dev; /* pointer to the pci dev structure for this board */
2931 } ADV_DVC_CFG;
2933 struct adv_dvc_var;
2934 struct adv_scsi_req_q;
2936 typedef void (*ADV_ISR_CALLBACK)
2937 (struct adv_dvc_var *, struct adv_scsi_req_q *);
2939 typedef void (*ADV_ASYNC_CALLBACK)
2940 (struct adv_dvc_var *, uchar);
2943 * Adapter operation variable structure.
2945 * One structure is required per host adapter.
2947 * Field naming convention:
2949 * *_able indicates both whether a feature should be enabled or disabled
2950 * and whether a device isi capable of the feature. At initialization
2951 * this field may be set, but later if a device is found to be incapable
2952 * of the feature, the field is cleared.
2954 typedef struct adv_dvc_var {
2955 AdvPortAddr iop_base; /* I/O port address */
2956 ushort err_code; /* fatal error code */
2957 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
2958 ADV_ISR_CALLBACK isr_callback;
2959 ADV_ASYNC_CALLBACK async_callback;
2960 ushort wdtr_able; /* try WDTR for a device */
2961 ushort sdtr_able; /* try SDTR for a device */
2962 ushort ultra_able; /* try SDTR Ultra speed for a device */
2963 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
2964 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
2965 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
2966 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
2967 ushort tagqng_able; /* try tagged queuing with a device */
2968 ushort ppr_able; /* PPR message capable per TID bitmask. */
2969 uchar max_dvc_qng; /* maximum number of tagged commands per device */
2970 ushort start_motor; /* start motor command allowed */
2971 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
2972 uchar chip_no; /* should be assigned by caller */
2973 uchar max_host_qng; /* maximum number of Q'ed command allowed */
2974 uchar irq_no; /* IRQ number */
2975 ushort no_scam; /* scam_tolerant of EEPROM */
2976 struct asc_board *drv_ptr; /* driver pointer to private structure */
2977 uchar chip_scsi_id; /* chip SCSI target ID */
2978 uchar chip_type;
2979 uchar bist_err_code;
2980 ADV_CARR_T *carrier_buf;
2981 ADV_CARR_T *carr_freelist; /* Carrier free list. */
2982 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
2983 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
2984 ushort carr_pending_cnt; /* Count of pending carriers. */
2986 * Note: The following fields will not be used after initialization. The
2987 * driver may discard the buffer after initialization is done.
2989 ADV_DVC_CFG *cfg; /* temporary configuration structure */
2990 } ADV_DVC_VAR;
2992 #define NO_OF_SG_PER_BLOCK 15
2994 typedef struct asc_sg_block {
2995 uchar reserved1;
2996 uchar reserved2;
2997 uchar reserved3;
2998 uchar sg_cnt; /* Valid entries in block. */
2999 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
3000 struct {
3001 ADV_PADDR sg_addr; /* SG element address. */
3002 ADV_DCNT sg_count; /* SG element count. */
3003 } sg_list[NO_OF_SG_PER_BLOCK];
3004 } ADV_SG_BLOCK;
3007 * ADV_SCSI_REQ_Q - microcode request structure
3009 * All fields in this structure up to byte 60 are used by the microcode.
3010 * The microcode makes assumptions about the size and ordering of fields
3011 * in this structure. Do not change the structure definition here without
3012 * coordinating the change with the microcode.
3014 * All fields accessed by microcode must be maintained in little_endian
3015 * order.
3017 typedef struct adv_scsi_req_q {
3018 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
3019 uchar target_cmd;
3020 uchar target_id; /* Device target identifier. */
3021 uchar target_lun; /* Device target logical unit number. */
3022 ADV_PADDR data_addr; /* Data buffer physical address. */
3023 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
3024 ADV_PADDR sense_addr;
3025 ADV_PADDR carr_pa;
3026 uchar mflag;
3027 uchar sense_len;
3028 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
3029 uchar scsi_cntl;
3030 uchar done_status; /* Completion status. */
3031 uchar scsi_status; /* SCSI status byte. */
3032 uchar host_status; /* Ucode host status. */
3033 uchar sg_working_ix;
3034 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
3035 ADV_PADDR sg_real_addr; /* SG list physical address. */
3036 ADV_PADDR scsiq_rptr;
3037 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
3038 ADV_VADDR scsiq_ptr;
3039 ADV_VADDR carr_va;
3041 * End of microcode structure - 60 bytes. The rest of the structure
3042 * is used by the Adv Library and ignored by the microcode.
3044 ADV_VADDR srb_ptr;
3045 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
3046 char *vdata_addr; /* Data buffer virtual address. */
3047 uchar a_flag;
3048 uchar pad[2]; /* Pad out to a word boundary. */
3049 } ADV_SCSI_REQ_Q;
3052 * Microcode idle loop commands
3054 #define IDLE_CMD_COMPLETED 0
3055 #define IDLE_CMD_STOP_CHIP 0x0001
3056 #define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
3057 #define IDLE_CMD_SEND_INT 0x0004
3058 #define IDLE_CMD_ABORT 0x0008
3059 #define IDLE_CMD_DEVICE_RESET 0x0010
3060 #define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
3061 #define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
3062 #define IDLE_CMD_SCSIREQ 0x0080
3064 #define IDLE_CMD_STATUS_SUCCESS 0x0001
3065 #define IDLE_CMD_STATUS_FAILURE 0x0002
3068 * AdvSendIdleCmd() flag definitions.
3070 #define ADV_NOWAIT 0x01
3073 * Wait loop time out values.
3075 #define SCSI_WAIT_10_SEC 10UL /* 10 seconds */
3076 #define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
3077 #define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
3078 #define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */
3079 #define SCSI_MAX_RETRY 10 /* retry count */
3081 #define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
3082 #define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
3083 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
3084 #define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
3086 #define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
3089 * Device drivers must define the following functions.
3091 static inline ulong DvcEnterCritical(void);
3092 static inline void DvcLeaveCritical(ulong);
3093 static void DvcSleepMilliSecond(ADV_DCNT);
3094 static uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
3095 static void DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
3096 static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
3097 uchar *, ASC_SDCNT *, int);
3098 static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
3101 * Adv Library functions available to drivers.
3103 static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3104 static int AdvISR(ADV_DVC_VAR *);
3105 static int AdvInitGetConfig(ADV_DVC_VAR *);
3106 static int AdvInitAsc3550Driver(ADV_DVC_VAR *);
3107 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
3108 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
3109 static int AdvResetChipAndSB(ADV_DVC_VAR *);
3110 static int AdvResetSB(ADV_DVC_VAR *asc_dvc);
3113 * Internal Adv Library functions.
3115 static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
3116 static void AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3117 static int AdvInitFrom3550EEP(ADV_DVC_VAR *);
3118 static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
3119 static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
3120 static ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3121 static void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3122 static ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3123 static void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3124 static ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3125 static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3126 static void AdvWaitEEPCmd(AdvPortAddr);
3127 static ushort AdvReadEEPWord(AdvPortAddr, int);
3130 * PCI Bus Definitions
3132 #define AscPCICmdRegBits_BusMastering 0x0007
3133 #define AscPCICmdRegBits_ParErrRespCtrl 0x0040
3135 /* Read byte from a register. */
3136 #define AdvReadByteRegister(iop_base, reg_off) \
3137 (ADV_MEM_READB((iop_base) + (reg_off)))
3139 /* Write byte to a register. */
3140 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
3141 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3143 /* Read word (2 bytes) from a register. */
3144 #define AdvReadWordRegister(iop_base, reg_off) \
3145 (ADV_MEM_READW((iop_base) + (reg_off)))
3147 /* Write word (2 bytes) to a register. */
3148 #define AdvWriteWordRegister(iop_base, reg_off, word) \
3149 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
3151 /* Write dword (4 bytes) to a register. */
3152 #define AdvWriteDWordRegister(iop_base, reg_off, dword) \
3153 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
3155 /* Read byte from LRAM. */
3156 #define AdvReadByteLram(iop_base, addr, byte) \
3157 do { \
3158 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3159 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3160 } while (0)
3162 /* Write byte to LRAM. */
3163 #define AdvWriteByteLram(iop_base, addr, byte) \
3164 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3165 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3167 /* Read word (2 bytes) from LRAM. */
3168 #define AdvReadWordLram(iop_base, addr, word) \
3169 do { \
3170 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3171 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3172 } while (0)
3174 /* Write word (2 bytes) to LRAM. */
3175 #define AdvWriteWordLram(iop_base, addr, word) \
3176 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3177 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3179 /* Write little-endian double word (4 bytes) to LRAM */
3180 /* Because of unspecified C language ordering don't use auto-increment. */
3181 #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
3182 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3183 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3184 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3185 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3186 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3187 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3189 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
3190 #define AdvReadWordAutoIncLram(iop_base) \
3191 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3193 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
3194 #define AdvWriteWordAutoIncLram(iop_base, word) \
3195 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3198 * Define macro to check for Condor signature.
3200 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3201 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3203 #define AdvFindSignature(iop_base) \
3204 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3205 ADV_CHIP_ID_BYTE) && \
3206 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3207 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
3210 * Define macro to Return the version number of the chip at 'iop_base'.
3212 * The second parameter 'bus_type' is currently unused.
3214 #define AdvGetChipVersion(iop_base, bus_type) \
3215 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3218 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3219 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3221 * If the request has not yet been sent to the device it will simply be
3222 * aborted from RISC memory. If the request is disconnected it will be
3223 * aborted on reselection by sending an Abort Message to the target ID.
3225 * Return value:
3226 * ADV_TRUE(1) - Queue was successfully aborted.
3227 * ADV_FALSE(0) - Queue was not found on the active queue list.
3229 #define AdvAbortQueue(asc_dvc, scsiq) \
3230 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3231 (ADV_DCNT) (scsiq))
3234 * Send a Bus Device Reset Message to the specified target ID.
3236 * All outstanding commands will be purged if sending the
3237 * Bus Device Reset Message is successful.
3239 * Return Value:
3240 * ADV_TRUE(1) - All requests on the target are purged.
3241 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3242 * are not purged.
3244 #define AdvResetDevice(asc_dvc, target_id) \
3245 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3246 (ADV_DCNT) (target_id))
3249 * SCSI Wide Type definition.
3251 #define ADV_SCSI_BIT_ID_TYPE ushort
3254 * AdvInitScsiTarget() 'cntl_flag' options.
3256 #define ADV_SCAN_LUN 0x01
3257 #define ADV_CAPINFO_NOLUN 0x02
3260 * Convert target id to target id bit mask.
3262 #define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
3265 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3268 #define QD_NO_STATUS 0x00 /* Request not completed yet. */
3269 #define QD_NO_ERROR 0x01
3270 #define QD_ABORTED_BY_HOST 0x02
3271 #define QD_WITH_ERROR 0x04
3273 #define QHSTA_NO_ERROR 0x00
3274 #define QHSTA_M_SEL_TIMEOUT 0x11
3275 #define QHSTA_M_DATA_OVER_RUN 0x12
3276 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3277 #define QHSTA_M_QUEUE_ABORTED 0x15
3278 #define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
3279 #define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
3280 #define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
3281 #define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
3282 #define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
3283 #define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
3284 #define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
3285 /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
3286 #define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
3287 #define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
3288 #define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
3289 #define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
3290 #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
3291 #define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
3292 #define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
3293 #define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
3294 #define QHSTA_M_WTM_TIMEOUT 0x41
3295 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
3296 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
3297 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
3298 #define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
3299 #define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
3300 #define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
3303 * Default EEPROM Configuration structure defined in a_init.c.
3305 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
3306 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
3307 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
3310 * DvcGetPhyAddr() flag arguments
3312 #define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
3313 #define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
3314 #define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
3315 #define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
3316 #define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
3317 #define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
3319 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
3320 #define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
3321 #define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
3322 #define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
3325 * Total contiguous memory needed for driver SG blocks.
3327 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3328 * number of scatter-gather elements the driver supports in a
3329 * single request.
3332 #define ADV_SG_LIST_MAX_BYTE_SIZE \
3333 (sizeof(ADV_SG_BLOCK) * \
3334 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3337 * Inquiry data structure and bitfield macros
3339 * Using bitfields to access the subchar data isn't portable across
3340 * endianness, so instead mask and shift. Only quantities of more
3341 * than 1 bit are shifted, since the others are just tested for true
3342 * or false.
3345 #define ADV_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f)
3346 #define ADV_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5)
3347 #define ADV_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f)
3348 #define ADV_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80)
3349 #define ADV_INQ_ANSI_VER(inq) ((inq)->ver & 0x07)
3350 #define ADV_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3)
3351 #define ADV_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6)
3352 #define ADV_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f)
3353 #define ADV_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40)
3354 #define ADV_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80)
3355 #define ADV_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01)
3356 #define ADV_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02)
3357 #define ADV_INQ_LINK_CMD(inq) ((inq)->flags & 0x08)
3358 #define ADV_INQ_SYNC(inq) ((inq)->flags & 0x10)
3359 #define ADV_INQ_WIDE16(inq) ((inq)->flags & 0x20)
3360 #define ADV_INQ_WIDE32(inq) ((inq)->flags & 0x40)
3361 #define ADV_INQ_REL_ADDR(inq) ((inq)->flags & 0x80)
3362 #define ADV_INQ_INFO_UNIT(inq) ((inq)->info & 0x01)
3363 #define ADV_INQ_QUICK_ARB(inq) ((inq)->info & 0x02)
3364 #define ADV_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2)
3366 typedef struct {
3367 uchar periph; /* peripheral device type [0:4] */
3368 /* peripheral qualifier [5:7] */
3369 uchar devtype; /* device type modifier (for SCSI I) [0:6] */
3370 /* RMB - removable medium bit [7] */
3371 uchar ver; /* ANSI approved version [0:2] */
3372 /* ECMA version [3:5] */
3373 /* ISO version [6:7] */
3374 uchar byte3; /* response data format [0:3] */
3375 /* 0 SCSI 1 */
3376 /* 1 CCS */
3377 /* 2 SCSI-2 */
3378 /* 3-F reserved */
3379 /* reserved [4:5] */
3380 /* terminate I/O process bit (see 5.6.22) [6] */
3381 /* asynch. event notification (processor) [7] */
3382 uchar add_len; /* additional length */
3383 uchar res1; /* reserved */
3384 uchar res2; /* reserved */
3385 uchar flags; /* soft reset implemented [0] */
3386 /* command queuing [1] */
3387 /* reserved [2] */
3388 /* linked command for this logical unit [3] */
3389 /* synchronous data transfer [4] */
3390 /* wide bus 16 bit data transfer [5] */
3391 /* wide bus 32 bit data transfer [6] */
3392 /* relative addressing mode [7] */
3393 uchar vendor_id[8]; /* vendor identification */
3394 uchar product_id[16]; /* product identification */
3395 uchar product_rev_level[4]; /* product revision level */
3396 uchar vendor_specific[20]; /* vendor specific */
3397 uchar info; /* information unit supported [0] */
3398 /* quick arbitrate supported [1] */
3399 /* clocking field [2:3] */
3400 /* reserved [4:7] */
3401 uchar res3; /* reserved */
3402 } ADV_SCSI_INQUIRY; /* 58 bytes */
3405 * --- Driver Constants and Macros
3408 #define ASC_NUM_BOARD_SUPPORTED 16
3409 #define ASC_NUM_IOPORT_PROBE 4
3410 #define ASC_NUM_BUS 2
3412 /* Reference Scsi_Host hostdata */
3413 #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3415 /* asc_board_t flags */
3416 #define ASC_HOST_IN_RESET 0x01
3417 #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
3418 #define ASC_SELECT_QUEUE_DEPTHS 0x08
3420 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3421 #define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD)
3423 #define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
3425 #define ASC_INFO_SIZE 128 /* advansys_info() line size */
3427 #ifdef CONFIG_PROC_FS
3428 /* /proc/scsi/advansys/[0...] related definitions */
3429 #define ASC_PRTBUF_SIZE 2048
3430 #define ASC_PRTLINE_SIZE 160
3432 #define ASC_PRT_NEXT() \
3433 if (cp) { \
3434 totlen += len; \
3435 leftlen -= len; \
3436 if (leftlen == 0) { \
3437 return totlen; \
3439 cp += len; \
3441 #endif /* CONFIG_PROC_FS */
3443 /* Asc Library return codes */
3444 #define ASC_TRUE 1
3445 #define ASC_FALSE 0
3446 #define ASC_NOERROR 1
3447 #define ASC_BUSY 0
3448 #define ASC_ERROR (-1)
3450 /* struct scsi_cmnd function return codes */
3451 #define STATUS_BYTE(byte) (byte)
3452 #define MSG_BYTE(byte) ((byte) << 8)
3453 #define HOST_BYTE(byte) ((byte) << 16)
3454 #define DRIVER_BYTE(byte) ((byte) << 24)
3457 * The following definitions and macros are OS independent interfaces to
3458 * the queue functions:
3459 * REQ - SCSI request structure
3460 * REQP - pointer to SCSI request structure
3461 * REQPTID(reqp) - reqp's target id
3462 * REQPNEXT(reqp) - reqp's next pointer
3463 * REQPNEXTP(reqp) - pointer to reqp's next pointer
3464 * REQPTIME(reqp) - reqp's time stamp value
3465 * REQTIMESTAMP() - system time stamp value
3467 typedef struct scsi_cmnd REQ, *REQP;
3468 #define REQPNEXT(reqp) ((REQP) ((reqp)->host_scribble))
3469 #define REQPNEXTP(reqp) ((REQP *) &((reqp)->host_scribble))
3470 #define REQPTID(reqp) ((reqp)->device->id)
3471 #define REQPTIME(reqp) ((reqp)->SCp.this_residual)
3472 #define REQTIMESTAMP() (jiffies)
3474 #define REQTIMESTAT(function, ascq, reqp, tid) \
3477 * If the request time stamp is less than the system time stamp, then \
3478 * maybe the system time stamp wrapped. Set the request time to zero.\
3479 */ \
3480 if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3481 REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3482 } else { \
3483 /* Indicate an error occurred with the assertion. */ \
3484 ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3485 REQPTIME(reqp) = 0; \
3487 /* Handle first minimum time case without external initialization. */ \
3488 if (((ascq)->q_tot_cnt[tid] == 1) || \
3489 (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3490 (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3491 ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3492 (function), (tid), (ascq)->q_min_tim[tid]); \
3494 if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3495 (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3496 ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3497 (function), tid, (ascq)->q_max_tim[tid]); \
3499 (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3500 /* Reset the time stamp field. */ \
3501 REQPTIME(reqp) = 0; \
3504 /* asc_enqueue() flags */
3505 #define ASC_FRONT 1
3506 #define ASC_BACK 2
3508 /* asc_dequeue_list() argument */
3509 #define ASC_TID_ALL (-1)
3511 /* Return non-zero, if the queue is empty. */
3512 #define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0)
3514 #ifndef ADVANSYS_STATS
3515 #define ASC_STATS(shost, counter)
3516 #define ASC_STATS_ADD(shost, counter, count)
3517 #else /* ADVANSYS_STATS */
3518 #define ASC_STATS(shost, counter) \
3519 (ASC_BOARDP(shost)->asc_stats.counter++)
3521 #define ASC_STATS_ADD(shost, counter, count) \
3522 (ASC_BOARDP(shost)->asc_stats.counter += (count))
3523 #endif /* ADVANSYS_STATS */
3525 #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3527 /* If the result wraps when calculating tenths, return 0. */
3528 #define ASC_TENTHS(num, den) \
3529 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3530 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3533 * Display a message to the console.
3535 #define ASC_PRINT(s) \
3537 printk("advansys: "); \
3538 printk(s); \
3541 #define ASC_PRINT1(s, a1) \
3543 printk("advansys: "); \
3544 printk((s), (a1)); \
3547 #define ASC_PRINT2(s, a1, a2) \
3549 printk("advansys: "); \
3550 printk((s), (a1), (a2)); \
3553 #define ASC_PRINT3(s, a1, a2, a3) \
3555 printk("advansys: "); \
3556 printk((s), (a1), (a2), (a3)); \
3559 #define ASC_PRINT4(s, a1, a2, a3, a4) \
3561 printk("advansys: "); \
3562 printk((s), (a1), (a2), (a3), (a4)); \
3565 #ifndef ADVANSYS_DEBUG
3567 #define ASC_DBG(lvl, s)
3568 #define ASC_DBG1(lvl, s, a1)
3569 #define ASC_DBG2(lvl, s, a1, a2)
3570 #define ASC_DBG3(lvl, s, a1, a2, a3)
3571 #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3572 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3573 #define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3574 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3575 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3576 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3577 #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3578 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
3579 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
3580 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
3581 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3583 #else /* ADVANSYS_DEBUG */
3586 * Debugging Message Levels:
3587 * 0: Errors Only
3588 * 1: High-Level Tracing
3589 * 2-N: Verbose Tracing
3592 #define ASC_DBG(lvl, s) \
3594 if (asc_dbglvl >= (lvl)) { \
3595 printk(s); \
3599 #define ASC_DBG1(lvl, s, a1) \
3601 if (asc_dbglvl >= (lvl)) { \
3602 printk((s), (a1)); \
3606 #define ASC_DBG2(lvl, s, a1, a2) \
3608 if (asc_dbglvl >= (lvl)) { \
3609 printk((s), (a1), (a2)); \
3613 #define ASC_DBG3(lvl, s, a1, a2, a3) \
3615 if (asc_dbglvl >= (lvl)) { \
3616 printk((s), (a1), (a2), (a3)); \
3620 #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3622 if (asc_dbglvl >= (lvl)) { \
3623 printk((s), (a1), (a2), (a3), (a4)); \
3627 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3629 if (asc_dbglvl >= (lvl)) { \
3630 asc_prt_scsi_host(s); \
3634 #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3636 if (asc_dbglvl >= (lvl)) { \
3637 asc_prt_scsi_cmnd(s); \
3641 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3643 if (asc_dbglvl >= (lvl)) { \
3644 asc_prt_asc_scsi_q(scsiqp); \
3648 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3650 if (asc_dbglvl >= (lvl)) { \
3651 asc_prt_asc_qdone_info(qdone); \
3655 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3657 if (asc_dbglvl >= (lvl)) { \
3658 asc_prt_adv_scsi_req_q(scsiqp); \
3662 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3664 if (asc_dbglvl >= (lvl)) { \
3665 asc_prt_hex((name), (start), (length)); \
3669 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3670 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3672 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3673 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3675 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3676 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3677 #endif /* ADVANSYS_DEBUG */
3679 #ifndef ADVANSYS_ASSERT
3680 #define ASC_ASSERT(a)
3681 #else /* ADVANSYS_ASSERT */
3683 #define ASC_ASSERT(a) \
3685 if (!(a)) { \
3686 printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3687 __FILE__, __LINE__); \
3691 #endif /* ADVANSYS_ASSERT */
3694 * --- Driver Structures
3697 #ifdef ADVANSYS_STATS
3699 /* Per board statistics structure */
3700 struct asc_stats {
3701 /* Driver Entrypoint Statistics */
3702 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
3703 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
3704 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
3705 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
3706 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
3707 ADV_DCNT done; /* # calls to request's scsi_done function */
3708 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
3709 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
3710 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
3711 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3712 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
3713 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
3714 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
3715 ADV_DCNT exe_unknown; /* # unknown returns. */
3716 /* Data Transfer Statistics */
3717 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
3718 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
3719 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
3720 ADV_DCNT sg_elem; /* # scatter-gather elements */
3721 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
3723 #endif /* ADVANSYS_STATS */
3726 * Request queuing structure
3728 typedef struct asc_queue {
3729 ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */
3730 REQP q_first[ADV_MAX_TID + 1]; /* first queued request */
3731 REQP q_last[ADV_MAX_TID + 1]; /* last queued request */
3732 #ifdef ADVANSYS_STATS
3733 short q_cur_cnt[ADV_MAX_TID + 1]; /* current queue count */
3734 short q_max_cnt[ADV_MAX_TID + 1]; /* maximum queue count */
3735 ADV_DCNT q_tot_cnt[ADV_MAX_TID + 1]; /* total enqueue count */
3736 ADV_DCNT q_tot_tim[ADV_MAX_TID + 1]; /* total time queued */
3737 ushort q_max_tim[ADV_MAX_TID + 1]; /* maximum time queued */
3738 ushort q_min_tim[ADV_MAX_TID + 1]; /* minimum time queued */
3739 #endif /* ADVANSYS_STATS */
3740 } asc_queue_t;
3743 * Adv Library Request Structures
3745 * The following two structures are used to process Wide Board requests.
3747 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
3748 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
3749 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
3750 * Mid-Level SCSI request structure.
3752 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
3753 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
3754 * up to 255 scatter-gather elements may be used per request or
3755 * ADV_SCSI_REQ_Q.
3757 * Both structures must be 32 byte aligned.
3759 typedef struct adv_sgblk {
3760 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
3761 uchar align[32]; /* Sgblock structure padding. */
3762 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
3763 } adv_sgblk_t;
3765 typedef struct adv_req {
3766 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
3767 uchar align[32]; /* Request structure padding. */
3768 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
3769 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
3770 struct adv_req *next_reqp; /* Next Request Structure. */
3771 } adv_req_t;
3774 * Structure allocated for each board.
3776 * This structure is allocated by scsi_host_alloc() at the end
3777 * of the 'Scsi_Host' structure starting at the 'hostdata'
3778 * field. It is guaranteed to be allocated from DMA-able memory.
3780 typedef struct asc_board {
3781 int id; /* Board Id */
3782 uint flags; /* Board flags */
3783 union {
3784 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
3785 ADV_DVC_VAR adv_dvc_var; /* Wide board */
3786 } dvc_var;
3787 union {
3788 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
3789 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
3790 } dvc_cfg;
3791 ushort asc_n_io_port; /* Number I/O ports. */
3792 asc_queue_t active; /* Active command queue */
3793 asc_queue_t waiting; /* Waiting command queue */
3794 asc_queue_t done; /* Done command queue */
3795 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
3796 struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */
3797 ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
3798 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
3799 ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
3800 union {
3801 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
3802 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
3803 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
3804 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
3805 } eep_config;
3806 ulong last_reset; /* Saved last reset time */
3807 spinlock_t lock; /* Board spinlock */
3808 /* /proc/scsi/advansys/[0...] */
3809 char *prtbuf; /* /proc print buffer */
3810 #ifdef ADVANSYS_STATS
3811 struct asc_stats asc_stats; /* Board statistics */
3812 #endif /* ADVANSYS_STATS */
3814 * The following fields are used only for Narrow Boards.
3816 /* The following three structures must be in DMA-able memory. */
3817 ASC_SCSI_REQ_Q scsireqq;
3818 ASC_CAP_INFO cap_info;
3819 ASC_SCSI_INQUIRY inquiry;
3820 uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */
3822 * The following fields are used only for Wide Boards.
3824 void __iomem *ioremap_addr; /* I/O Memory remap address. */
3825 ushort ioport; /* I/O Port address. */
3826 ADV_CARR_T *carrp; /* ADV_CARR_T memory block. */
3827 adv_req_t *orig_reqp; /* adv_req_t memory block. */
3828 adv_req_t *adv_reqp; /* Request structures. */
3829 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
3830 ushort bios_signature; /* BIOS Signature. */
3831 ushort bios_version; /* BIOS Version. */
3832 ushort bios_codeseg; /* BIOS Code Segment. */
3833 ushort bios_codelen; /* BIOS Code Segment Length. */
3834 } asc_board_t;
3836 /* Number of boards detected in system. */
3837 static int asc_board_count;
3839 /* Number of boards detected by advansys_detect */
3840 static int asc_legacy_count;
3841 static struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { NULL };
3843 /* Overrun buffer used by all narrow boards. */
3844 static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
3847 * Global structures required to issue a command.
3849 static ASC_SCSI_Q asc_scsi_q = { {0} };
3850 static ASC_SG_HEAD asc_sg_head = { 0 };
3852 /* List of bus types probed in advansys_detect. */
3853 static ushort asc_bus[ASC_NUM_BUS] __initdata = {
3854 ASC_IS_ISA,
3855 ASC_IS_VL,
3858 static int asc_iopflag = ASC_FALSE;
3859 static int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
3861 #ifdef ADVANSYS_DEBUG
3862 static char *asc_bus_name[ASC_NUM_BUS] = {
3863 "ASC_IS_ISA",
3864 "ASC_IS_VL",
3867 static int asc_dbglvl = 3;
3868 #endif /* ADVANSYS_DEBUG */
3870 /* Declaration for Asc Library internal data referenced by driver. */
3871 static PortAddr _asc_def_iop_base[];
3874 * --- Driver Function Prototypes
3876 * advansys.h contains function prototypes for functions global to Linux.
3879 static int advansys_slave_configure(struct scsi_device *);
3880 static void asc_scsi_done_list(struct scsi_cmnd *);
3881 static int asc_execute_scsi_cmnd(struct scsi_cmnd *);
3882 static int asc_build_req(asc_board_t *, struct scsi_cmnd *);
3883 static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
3884 static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
3885 static void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
3886 static void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3887 static void adv_async_callback(ADV_DVC_VAR *, uchar);
3888 static void asc_enqueue(asc_queue_t *, REQP, int);
3889 static REQP asc_dequeue(asc_queue_t *, int);
3890 static REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
3891 static int asc_rmqueue(asc_queue_t *, REQP);
3892 static void asc_execute_queue(asc_queue_t *);
3893 #ifdef CONFIG_PROC_FS
3894 static int asc_proc_copy(off_t, off_t, char *, int, char *, int);
3895 static int asc_prt_board_devices(struct Scsi_Host *, char *, int);
3896 static int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
3897 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
3898 static int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
3899 static int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
3900 static int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
3901 static int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
3902 static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
3903 static int asc_prt_line(char *, int, char *fmt, ...);
3904 #endif /* CONFIG_PROC_FS */
3906 /* Declaration for Asc Library internal functions referenced by driver. */
3907 static int AscFindSignature(PortAddr);
3908 static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
3910 /* Statistics function prototypes. */
3911 #ifdef ADVANSYS_STATS
3912 #ifdef CONFIG_PROC_FS
3913 static int asc_prt_board_stats(struct Scsi_Host *, char *, int);
3914 static int asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
3915 #endif /* CONFIG_PROC_FS */
3916 #endif /* ADVANSYS_STATS */
3918 /* Debug function prototypes. */
3919 #ifdef ADVANSYS_DEBUG
3920 static void asc_prt_scsi_host(struct Scsi_Host *);
3921 static void asc_prt_scsi_cmnd(struct scsi_cmnd *);
3922 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
3923 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
3924 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
3925 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
3926 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
3927 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
3928 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
3929 static void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
3930 static void asc_prt_hex(char *f, uchar *, int);
3931 #endif /* ADVANSYS_DEBUG */
3933 #ifdef CONFIG_PROC_FS
3935 * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
3937 * *buffer: I/O buffer
3938 * **start: if inout == FALSE pointer into buffer where user read should start
3939 * offset: current offset into a /proc/scsi/advansys/[0...] file
3940 * length: length of buffer
3941 * hostno: Scsi_Host host_no
3942 * inout: TRUE - user is writing; FALSE - user is reading
3944 * Return the number of bytes read from or written to a
3945 * /proc/scsi/advansys/[0...] file.
3947 * Note: This function uses the per board buffer 'prtbuf' which is
3948 * allocated when the board is initialized in advansys_detect(). The
3949 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
3950 * used to write to the buffer. The way asc_proc_copy() is written
3951 * if 'prtbuf' is too small it will not be overwritten. Instead the
3952 * user just won't get all the available statistics.
3954 static int
3955 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
3956 off_t offset, int length, int inout)
3958 asc_board_t *boardp;
3959 char *cp;
3960 int cplen;
3961 int cnt;
3962 int totcnt;
3963 int leftlen;
3964 char *curbuf;
3965 off_t advoffset;
3966 #ifdef ADVANSYS_STATS
3967 int tgt_id;
3968 #endif /* ADVANSYS_STATS */
3970 ASC_DBG(1, "advansys_proc_info: begin\n");
3973 * User write not supported.
3975 if (inout == TRUE) {
3976 return (-ENOSYS);
3980 * User read of /proc/scsi/advansys/[0...] file.
3983 boardp = ASC_BOARDP(shost);
3985 /* Copy read data starting at the beginning of the buffer. */
3986 *start = buffer;
3987 curbuf = buffer;
3988 advoffset = 0;
3989 totcnt = 0;
3990 leftlen = length;
3993 * Get board configuration information.
3995 * advansys_info() returns the board string from its own static buffer.
3997 cp = (char *)advansys_info(shost);
3998 strcat(cp, "\n");
3999 cplen = strlen(cp);
4000 /* Copy board information. */
4001 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4002 totcnt += cnt;
4003 leftlen -= cnt;
4004 if (leftlen == 0) {
4005 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4006 return totcnt;
4008 advoffset += cplen;
4009 curbuf += cnt;
4012 * Display Wide Board BIOS Information.
4014 if (ASC_WIDE_BOARD(boardp)) {
4015 cp = boardp->prtbuf;
4016 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
4017 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4018 cnt =
4019 asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
4020 cplen);
4021 totcnt += cnt;
4022 leftlen -= cnt;
4023 if (leftlen == 0) {
4024 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4025 return totcnt;
4027 advoffset += cplen;
4028 curbuf += cnt;
4032 * Display driver information for each device attached to the board.
4034 cp = boardp->prtbuf;
4035 cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
4036 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4037 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4038 totcnt += cnt;
4039 leftlen -= cnt;
4040 if (leftlen == 0) {
4041 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4042 return totcnt;
4044 advoffset += cplen;
4045 curbuf += cnt;
4048 * Display EEPROM configuration for the board.
4050 cp = boardp->prtbuf;
4051 if (ASC_NARROW_BOARD(boardp)) {
4052 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
4053 } else {
4054 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
4056 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4057 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4058 totcnt += cnt;
4059 leftlen -= cnt;
4060 if (leftlen == 0) {
4061 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4062 return totcnt;
4064 advoffset += cplen;
4065 curbuf += cnt;
4068 * Display driver configuration and information for the board.
4070 cp = boardp->prtbuf;
4071 cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
4072 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4073 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4074 totcnt += cnt;
4075 leftlen -= cnt;
4076 if (leftlen == 0) {
4077 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4078 return totcnt;
4080 advoffset += cplen;
4081 curbuf += cnt;
4083 #ifdef ADVANSYS_STATS
4085 * Display driver statistics for the board.
4087 cp = boardp->prtbuf;
4088 cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
4089 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4090 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4091 totcnt += cnt;
4092 leftlen -= cnt;
4093 if (leftlen == 0) {
4094 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4095 return totcnt;
4097 advoffset += cplen;
4098 curbuf += cnt;
4101 * Display driver statistics for each target.
4103 for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
4104 cp = boardp->prtbuf;
4105 cplen = asc_prt_target_stats(shost, tgt_id, cp,
4106 ASC_PRTBUF_SIZE);
4107 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4108 cnt =
4109 asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
4110 cplen);
4111 totcnt += cnt;
4112 leftlen -= cnt;
4113 if (leftlen == 0) {
4114 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4115 return totcnt;
4117 advoffset += cplen;
4118 curbuf += cnt;
4120 #endif /* ADVANSYS_STATS */
4123 * Display Asc Library dynamic configuration information
4124 * for the board.
4126 cp = boardp->prtbuf;
4127 if (ASC_NARROW_BOARD(boardp)) {
4128 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
4129 } else {
4130 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
4132 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4133 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4134 totcnt += cnt;
4135 leftlen -= cnt;
4136 if (leftlen == 0) {
4137 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4138 return totcnt;
4140 advoffset += cplen;
4141 curbuf += cnt;
4143 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4145 return totcnt;
4147 #endif /* CONFIG_PROC_FS */
4150 * advansys_info()
4152 * Return suitable for printing on the console with the argument
4153 * adapter's configuration information.
4155 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
4156 * otherwise the static 'info' array will be overrun.
4158 static const char *advansys_info(struct Scsi_Host *shost)
4160 static char info[ASC_INFO_SIZE];
4161 asc_board_t *boardp;
4162 ASC_DVC_VAR *asc_dvc_varp;
4163 ADV_DVC_VAR *adv_dvc_varp;
4164 char *busname;
4165 int iolen;
4166 char *widename = NULL;
4168 boardp = ASC_BOARDP(shost);
4169 if (ASC_NARROW_BOARD(boardp)) {
4170 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4171 ASC_DBG(1, "advansys_info: begin\n");
4172 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
4173 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
4174 ASC_IS_ISAPNP) {
4175 busname = "ISA PnP";
4176 } else {
4177 busname = "ISA";
4179 /* Don't reference 'shost->n_io_port'; It may be truncated. */
4180 sprintf(info,
4181 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
4182 ASC_VERSION, busname,
4183 (ulong)shost->io_port,
4184 (ulong)shost->io_port + boardp->asc_n_io_port -
4185 1, shost->irq, shost->dma_channel);
4186 } else {
4187 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
4188 busname = "VL";
4189 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
4190 busname = "EISA";
4191 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
4192 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
4193 == ASC_IS_PCI_ULTRA) {
4194 busname = "PCI Ultra";
4195 } else {
4196 busname = "PCI";
4198 } else {
4199 busname = "?";
4200 ASC_PRINT2
4201 ("advansys_info: board %d: unknown bus type %d\n",
4202 boardp->id, asc_dvc_varp->bus_type);
4204 /* Don't reference 'shost->n_io_port'; It may be truncated. */
4205 sprintf(info,
4206 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
4207 ASC_VERSION, busname,
4208 (ulong)shost->io_port,
4209 (ulong)shost->io_port + boardp->asc_n_io_port -
4210 1, shost->irq);
4212 } else {
4214 * Wide Adapter Information
4216 * Memory-mapped I/O is used instead of I/O space to access
4217 * the adapter, but display the I/O Port range. The Memory
4218 * I/O address is displayed through the driver /proc file.
4220 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4221 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4222 iolen = ADV_3550_IOLEN;
4223 widename = "Ultra-Wide";
4224 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4225 iolen = ADV_38C0800_IOLEN;
4226 widename = "Ultra2-Wide";
4227 } else {
4228 iolen = ADV_38C1600_IOLEN;
4229 widename = "Ultra3-Wide";
4231 sprintf(info,
4232 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
4233 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
4234 (ulong)adv_dvc_varp->iop_base + iolen - 1, shost->irq);
4236 ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
4237 ASC_DBG(1, "advansys_info: end\n");
4238 return info;
4242 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
4244 * This function always returns 0. Command return status is saved
4245 * in the 'scp' result field.
4247 static int
4248 advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *))
4250 struct Scsi_Host *shost;
4251 asc_board_t *boardp;
4252 ulong flags;
4253 struct scsi_cmnd *done_scp;
4255 shost = scp->device->host;
4256 boardp = ASC_BOARDP(shost);
4257 ASC_STATS(shost, queuecommand);
4259 /* host_lock taken by mid-level prior to call but need to protect */
4260 /* against own ISR */
4261 spin_lock_irqsave(&boardp->lock, flags);
4264 * Block new commands while handling a reset or abort request.
4266 if (boardp->flags & ASC_HOST_IN_RESET) {
4267 ASC_DBG1(1,
4268 "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
4269 (ulong)scp);
4270 scp->result = HOST_BYTE(DID_RESET);
4273 * Add blocked requests to the board's 'done' queue. The queued
4274 * requests will be completed at the end of the abort or reset
4275 * handling.
4277 asc_enqueue(&boardp->done, scp, ASC_BACK);
4278 spin_unlock_irqrestore(&boardp->lock, flags);
4279 return 0;
4283 * Attempt to execute any waiting commands for the board.
4285 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4286 ASC_DBG(1,
4287 "advansys_queuecommand: before asc_execute_queue() waiting\n");
4288 asc_execute_queue(&boardp->waiting);
4292 * Save the function pointer to Linux mid-level 'done' function
4293 * and attempt to execute the command.
4295 * If ASC_NOERROR is returned the request has been added to the
4296 * board's 'active' queue and will be completed by the interrupt
4297 * handler.
4299 * If ASC_BUSY is returned add the request to the board's per
4300 * target waiting list. This is the first time the request has
4301 * been tried. Add it to the back of the waiting list. It will be
4302 * retried later.
4304 * If an error occurred, the request will have been placed on the
4305 * board's 'done' queue and must be completed before returning.
4307 scp->scsi_done = done;
4308 switch (asc_execute_scsi_cmnd(scp)) {
4309 case ASC_NOERROR:
4310 break;
4311 case ASC_BUSY:
4312 asc_enqueue(&boardp->waiting, scp, ASC_BACK);
4313 break;
4314 case ASC_ERROR:
4315 default:
4316 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
4317 /* Interrupts could be enabled here. */
4318 asc_scsi_done_list(done_scp);
4319 break;
4321 spin_unlock_irqrestore(&boardp->lock, flags);
4323 return 0;
4327 * advansys_reset()
4329 * Reset the bus associated with the command 'scp'.
4331 * This function runs its own thread. Interrupts must be blocked but
4332 * sleeping is allowed and no locking other than for host structures is
4333 * required. Returns SUCCESS or FAILED.
4335 static int advansys_reset(struct scsi_cmnd *scp)
4337 struct Scsi_Host *shost;
4338 asc_board_t *boardp;
4339 ASC_DVC_VAR *asc_dvc_varp;
4340 ADV_DVC_VAR *adv_dvc_varp;
4341 ulong flags;
4342 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4343 struct scsi_cmnd *tscp, *new_last_scp;
4344 int status;
4345 int ret = SUCCESS;
4347 ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp);
4349 #ifdef ADVANSYS_STATS
4350 if (scp->device->host != NULL) {
4351 ASC_STATS(scp->device->host, reset);
4353 #endif /* ADVANSYS_STATS */
4355 if ((shost = scp->device->host) == NULL) {
4356 scp->result = HOST_BYTE(DID_ERROR);
4357 return FAILED;
4360 boardp = ASC_BOARDP(shost);
4362 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
4363 boardp->id);
4365 * Check for re-entrancy.
4367 spin_lock_irqsave(&boardp->lock, flags);
4368 if (boardp->flags & ASC_HOST_IN_RESET) {
4369 spin_unlock_irqrestore(&boardp->lock, flags);
4370 return FAILED;
4372 boardp->flags |= ASC_HOST_IN_RESET;
4373 spin_unlock_irqrestore(&boardp->lock, flags);
4375 if (ASC_NARROW_BOARD(boardp)) {
4377 * Narrow Board
4379 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4382 * Reset the chip and SCSI bus.
4384 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
4385 status = AscInitAsc1000Driver(asc_dvc_varp);
4387 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
4388 if (asc_dvc_varp->err_code) {
4389 ASC_PRINT2
4390 ("advansys_reset: board %d: SCSI bus reset error: 0x%x\n",
4391 boardp->id, asc_dvc_varp->err_code);
4392 ret = FAILED;
4393 } else if (status) {
4394 ASC_PRINT2
4395 ("advansys_reset: board %d: SCSI bus reset warning: 0x%x\n",
4396 boardp->id, status);
4397 } else {
4398 ASC_PRINT1
4399 ("advansys_reset: board %d: SCSI bus reset successful.\n",
4400 boardp->id);
4403 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
4404 spin_lock_irqsave(&boardp->lock, flags);
4406 } else {
4408 * Wide Board
4410 * If the suggest reset bus flags are set, then reset the bus.
4411 * Otherwise only reset the device.
4413 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4416 * Reset the target's SCSI bus.
4418 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
4419 switch (AdvResetChipAndSB(adv_dvc_varp)) {
4420 case ASC_TRUE:
4421 ASC_PRINT1
4422 ("advansys_reset: board %d: SCSI bus reset successful.\n",
4423 boardp->id);
4424 break;
4425 case ASC_FALSE:
4426 default:
4427 ASC_PRINT1
4428 ("advansys_reset: board %d: SCSI bus reset error.\n",
4429 boardp->id);
4430 ret = FAILED;
4431 break;
4433 spin_lock_irqsave(&boardp->lock, flags);
4434 (void)AdvISR(adv_dvc_varp);
4436 /* Board lock is held. */
4439 * Dequeue all board 'done' requests. A pointer to the last request
4440 * is returned in 'last_scp'.
4442 done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
4445 * Dequeue all board 'active' requests for all devices and set
4446 * the request status to DID_RESET. A pointer to the last request
4447 * is returned in 'last_scp'.
4449 if (done_scp == NULL) {
4450 done_scp =
4451 asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL);
4452 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4453 tscp->result = HOST_BYTE(DID_RESET);
4455 } else {
4456 /* Append to 'done_scp' at the end with 'last_scp'. */
4457 ASC_ASSERT(last_scp != NULL);
4458 last_scp->host_scribble =
4459 (unsigned char *)asc_dequeue_list(&boardp->active,
4460 &new_last_scp,
4461 ASC_TID_ALL);
4462 if (new_last_scp != NULL) {
4463 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4464 for (tscp = REQPNEXT(last_scp); tscp;
4465 tscp = REQPNEXT(tscp)) {
4466 tscp->result = HOST_BYTE(DID_RESET);
4468 last_scp = new_last_scp;
4473 * Dequeue all 'waiting' requests and set the request status
4474 * to DID_RESET.
4476 if (done_scp == NULL) {
4477 done_scp =
4478 asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL);
4479 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4480 tscp->result = HOST_BYTE(DID_RESET);
4482 } else {
4483 /* Append to 'done_scp' at the end with 'last_scp'. */
4484 ASC_ASSERT(last_scp != NULL);
4485 last_scp->host_scribble =
4486 (unsigned char *)asc_dequeue_list(&boardp->waiting,
4487 &new_last_scp,
4488 ASC_TID_ALL);
4489 if (new_last_scp != NULL) {
4490 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4491 for (tscp = REQPNEXT(last_scp); tscp;
4492 tscp = REQPNEXT(tscp)) {
4493 tscp->result = HOST_BYTE(DID_RESET);
4495 last_scp = new_last_scp;
4499 /* Save the time of the most recently completed reset. */
4500 boardp->last_reset = jiffies;
4502 /* Clear reset flag. */
4503 boardp->flags &= ~ASC_HOST_IN_RESET;
4504 spin_unlock_irqrestore(&boardp->lock, flags);
4507 * Complete all the 'done_scp' requests.
4509 if (done_scp != NULL) {
4510 asc_scsi_done_list(done_scp);
4513 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
4515 return ret;
4519 * advansys_biosparam()
4521 * Translate disk drive geometry if the "BIOS greater than 1 GB"
4522 * support is enabled for a drive.
4524 * ip (information pointer) is an int array with the following definition:
4525 * ip[0]: heads
4526 * ip[1]: sectors
4527 * ip[2]: cylinders
4529 static int
4530 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
4531 sector_t capacity, int ip[])
4533 asc_board_t *boardp;
4535 ASC_DBG(1, "advansys_biosparam: begin\n");
4536 ASC_STATS(sdev->host, biosparam);
4537 boardp = ASC_BOARDP(sdev->host);
4538 if (ASC_NARROW_BOARD(boardp)) {
4539 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
4540 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
4541 ip[0] = 255;
4542 ip[1] = 63;
4543 } else {
4544 ip[0] = 64;
4545 ip[1] = 32;
4547 } else {
4548 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
4549 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
4550 ip[0] = 255;
4551 ip[1] = 63;
4552 } else {
4553 ip[0] = 64;
4554 ip[1] = 32;
4557 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
4558 ASC_DBG(1, "advansys_biosparam: end\n");
4559 return 0;
4562 static struct scsi_host_template advansys_template = {
4563 .proc_name = "advansys",
4564 #ifdef CONFIG_PROC_FS
4565 .proc_info = advansys_proc_info,
4566 #endif
4567 .name = "advansys",
4568 .info = advansys_info,
4569 .queuecommand = advansys_queuecommand,
4570 .eh_bus_reset_handler = advansys_reset,
4571 .bios_param = advansys_biosparam,
4572 .slave_configure = advansys_slave_configure,
4574 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
4575 * must be set. The flag will be cleared in advansys_board_found
4576 * for non-ISA adapters.
4578 .unchecked_isa_dma = 1,
4580 * All adapters controlled by this driver are capable of large
4581 * scatter-gather lists. According to the mid-level SCSI documentation
4582 * this obviates any performance gain provided by setting
4583 * 'use_clustering'. But empirically while CPU utilization is increased
4584 * by enabling clustering, I/O throughput increases as well.
4586 .use_clustering = ENABLE_CLUSTERING,
4590 * --- Miscellaneous Driver Functions
4594 * First-level interrupt handler.
4596 * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
4597 * all boards are currently checked for interrupts on each interrupt, 'dev_id'
4598 * is not referenced. 'dev_id' could be used to identify an interrupt passed
4599 * to the AdvanSys driver which is for a device sharing an interrupt with
4600 * an AdvanSys adapter.
4602 static irqreturn_t advansys_interrupt(int irq, void *dev_id)
4604 unsigned long flags;
4605 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4606 struct scsi_cmnd *new_last_scp;
4607 struct Scsi_Host *shost = dev_id;
4608 asc_board_t *boardp = ASC_BOARDP(shost);
4609 irqreturn_t result = IRQ_NONE;
4611 ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp);
4612 spin_lock_irqsave(&boardp->lock, flags);
4613 if (ASC_NARROW_BOARD(boardp)) {
4615 * Narrow Board
4617 if (AscIsIntPending(shost->io_port)) {
4618 result = IRQ_HANDLED;
4619 ASC_STATS(shost, interrupt);
4620 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
4621 AscISR(&boardp->dvc_var.asc_dvc_var);
4623 } else {
4625 * Wide Board
4627 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
4628 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
4629 result = IRQ_HANDLED;
4630 ASC_STATS(shost, interrupt);
4635 * Start waiting requests and create a list of completed requests.
4637 * If a reset request is being performed for the board, the reset
4638 * handler will complete pending requests after it has completed.
4640 if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
4641 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%p, "
4642 "last_scp 0x%p\n", done_scp, last_scp);
4644 /* Start any waiting commands for the board. */
4645 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4646 ASC_DBG(1, "advansys_interrupt: before "
4647 "asc_execute_queue()\n");
4648 asc_execute_queue(&boardp->waiting);
4652 * Add to the list of requests that must be completed.
4654 * 'done_scp' will always be NULL on the first iteration of
4655 * this loop. 'last_scp' is set at the same time as 'done_scp'.
4657 if (done_scp == NULL) {
4658 done_scp = asc_dequeue_list(&boardp->done,
4659 &last_scp, ASC_TID_ALL);
4660 } else {
4661 ASC_ASSERT(last_scp != NULL);
4662 last_scp->host_scribble =
4663 (unsigned char *)asc_dequeue_list(&boardp->
4664 done,
4665 &new_last_scp,
4666 ASC_TID_ALL);
4667 if (new_last_scp != NULL) {
4668 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4669 last_scp = new_last_scp;
4673 spin_unlock_irqrestore(&boardp->lock, flags);
4676 * If interrupts were enabled on entry, then they
4677 * are now enabled here.
4679 * Complete all requests on the done list.
4682 asc_scsi_done_list(done_scp);
4684 ASC_DBG(1, "advansys_interrupt: end\n");
4685 return result;
4689 * Set the number of commands to queue per device for the
4690 * specified host adapter.
4692 static int advansys_slave_configure(struct scsi_device *device)
4694 asc_board_t *boardp;
4696 boardp = ASC_BOARDP(device->host);
4697 boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
4699 * Save a pointer to the device and set its initial/maximum
4700 * queue depth. Only save the pointer for a lun0 dev though.
4702 if (device->lun == 0)
4703 boardp->device[device->id] = device;
4704 if (device->tagged_supported) {
4705 if (ASC_NARROW_BOARD(boardp)) {
4706 scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
4707 boardp->dvc_var.asc_dvc_var.
4708 max_dvc_qng[device->id]);
4709 } else {
4710 scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
4711 boardp->dvc_var.adv_dvc_var.
4712 max_dvc_qng);
4714 } else {
4715 scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun);
4717 ASC_DBG4(1,
4718 "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n",
4719 (ulong)device, (ulong)boardp, device->id, device->queue_depth);
4720 return 0;
4724 * Complete all requests on the singly linked list pointed
4725 * to by 'scp'.
4727 * Interrupts can be enabled on entry.
4729 static void asc_scsi_done_list(struct scsi_cmnd *scp)
4731 struct scsi_cmnd *tscp;
4733 ASC_DBG(2, "asc_scsi_done_list: begin\n");
4734 while (scp != NULL) {
4735 asc_board_t *boardp;
4736 struct device *dev;
4738 ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp);
4739 tscp = REQPNEXT(scp);
4740 scp->host_scribble = NULL;
4742 boardp = ASC_BOARDP(scp->device->host);
4744 if (ASC_NARROW_BOARD(boardp))
4745 dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
4746 else
4747 dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
4749 if (scp->use_sg)
4750 dma_unmap_sg(dev,
4751 (struct scatterlist *)scp->request_buffer,
4752 scp->use_sg, scp->sc_data_direction);
4753 else if (scp->request_bufflen)
4754 dma_unmap_single(dev, scp->SCp.dma_handle,
4755 scp->request_bufflen,
4756 scp->sc_data_direction);
4758 ASC_STATS(scp->device->host, done);
4759 ASC_ASSERT(scp->scsi_done != NULL);
4761 scp->scsi_done(scp);
4763 scp = tscp;
4765 ASC_DBG(2, "asc_scsi_done_list: done\n");
4766 return;
4770 * Execute a single 'Scsi_Cmnd'.
4772 * The function 'done' is called when the request has been completed.
4774 * Scsi_Cmnd:
4776 * host - board controlling device
4777 * device - device to send command
4778 * target - target of device
4779 * lun - lun of device
4780 * cmd_len - length of SCSI CDB
4781 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
4782 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
4784 * if (use_sg == 0) {
4785 * request_buffer - buffer address for request
4786 * request_bufflen - length of request buffer
4787 * } else {
4788 * request_buffer - pointer to scatterlist structure
4791 * sense_buffer - sense command buffer
4793 * result (4 bytes of an int):
4794 * Byte Meaning
4795 * 0 SCSI Status Byte Code
4796 * 1 SCSI One Byte Message Code
4797 * 2 Host Error Code
4798 * 3 Mid-Level Error Code
4800 * host driver fields:
4801 * SCp - Scsi_Pointer used for command processing status
4802 * scsi_done - used to save caller's done function
4803 * host_scribble - used for pointer to another struct scsi_cmnd
4805 * If this function returns ASC_NOERROR the request has been enqueued
4806 * on the board's 'active' queue and will be completed from the
4807 * interrupt handler.
4809 * If this function returns ASC_NOERROR the request has been enqueued
4810 * on the board's 'done' queue and must be completed by the caller.
4812 * If ASC_BUSY is returned the request will be enqueued by the
4813 * caller on the target's waiting queue and re-tried later.
4815 static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
4817 asc_board_t *boardp;
4818 ASC_DVC_VAR *asc_dvc_varp;
4819 ADV_DVC_VAR *adv_dvc_varp;
4820 ADV_SCSI_REQ_Q *adv_scsiqp;
4821 struct scsi_device *device;
4822 int ret;
4824 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
4825 (ulong)scp, (ulong)scp->scsi_done);
4827 boardp = ASC_BOARDP(scp->device->host);
4828 device = boardp->device[scp->device->id];
4830 if (ASC_NARROW_BOARD(boardp)) {
4832 * Build and execute Narrow Board request.
4835 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4838 * Build Asc Library request structure using the
4839 * global structures 'asc_scsi_req' and 'asc_sg_head'.
4841 * If an error is returned, then the request has been
4842 * queued on the board done queue. It will be completed
4843 * by the caller.
4845 * asc_build_req() can not return ASC_BUSY.
4847 if (asc_build_req(boardp, scp) == ASC_ERROR) {
4848 ASC_STATS(scp->device->host, build_error);
4849 return ASC_ERROR;
4853 * Execute the command. If there is no error, add the command
4854 * to the active queue.
4856 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
4857 case ASC_NOERROR:
4858 ASC_STATS(scp->device->host, exe_noerror);
4860 * Increment monotonically increasing per device successful
4861 * request counter. Wrapping doesn't matter.
4863 boardp->reqcnt[scp->device->id]++;
4864 asc_enqueue(&boardp->active, scp, ASC_BACK);
4865 ASC_DBG(1,
4866 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
4867 break;
4868 case ASC_BUSY:
4870 * Caller will enqueue request on the target's waiting queue
4871 * and retry later.
4873 ASC_STATS(scp->device->host, exe_busy);
4874 break;
4875 case ASC_ERROR:
4876 ASC_PRINT2
4877 ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4878 boardp->id, asc_dvc_varp->err_code);
4879 ASC_STATS(scp->device->host, exe_error);
4880 scp->result = HOST_BYTE(DID_ERROR);
4881 asc_enqueue(&boardp->done, scp, ASC_BACK);
4882 break;
4883 default:
4884 ASC_PRINT2
4885 ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
4886 boardp->id, asc_dvc_varp->err_code);
4887 ASC_STATS(scp->device->host, exe_unknown);
4888 scp->result = HOST_BYTE(DID_ERROR);
4889 asc_enqueue(&boardp->done, scp, ASC_BACK);
4890 break;
4892 } else {
4894 * Build and execute Wide Board request.
4896 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4899 * Build and get a pointer to an Adv Library request structure.
4901 * If the request is successfully built then send it below,
4902 * otherwise return with an error.
4904 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
4905 case ASC_NOERROR:
4906 ASC_DBG(3,
4907 "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
4908 break;
4909 case ASC_BUSY:
4910 ASC_DBG(1,
4911 "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
4913 * If busy is returned the request has not been enqueued.
4914 * It will be enqueued by the caller on the target's waiting
4915 * queue and retried later.
4917 * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg'
4918 * count wide board busy conditions. They are updated in
4919 * adv_build_req and adv_get_sglist, respectively.
4921 return ASC_BUSY;
4922 case ASC_ERROR:
4924 * If an error is returned, then the request has been
4925 * queued on the board done queue. It will be completed
4926 * by the caller.
4928 default:
4929 ASC_DBG(1,
4930 "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
4931 ASC_STATS(scp->device->host, build_error);
4932 return ASC_ERROR;
4936 * Execute the command. If there is no error, add the command
4937 * to the active queue.
4939 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
4940 case ASC_NOERROR:
4941 ASC_STATS(scp->device->host, exe_noerror);
4943 * Increment monotonically increasing per device successful
4944 * request counter. Wrapping doesn't matter.
4946 boardp->reqcnt[scp->device->id]++;
4947 asc_enqueue(&boardp->active, scp, ASC_BACK);
4948 ASC_DBG(1,
4949 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
4950 break;
4951 case ASC_BUSY:
4953 * Caller will enqueue request on the target's waiting queue
4954 * and retry later.
4956 ASC_STATS(scp->device->host, exe_busy);
4957 break;
4958 case ASC_ERROR:
4959 ASC_PRINT2
4960 ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4961 boardp->id, adv_dvc_varp->err_code);
4962 ASC_STATS(scp->device->host, exe_error);
4963 scp->result = HOST_BYTE(DID_ERROR);
4964 asc_enqueue(&boardp->done, scp, ASC_BACK);
4965 break;
4966 default:
4967 ASC_PRINT2
4968 ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
4969 boardp->id, adv_dvc_varp->err_code);
4970 ASC_STATS(scp->device->host, exe_unknown);
4971 scp->result = HOST_BYTE(DID_ERROR);
4972 asc_enqueue(&boardp->done, scp, ASC_BACK);
4973 break;
4977 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
4978 return ret;
4982 * Build a request structure for the Asc Library (Narrow Board).
4984 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
4985 * used to build the request.
4987 * If an error occurs, then queue the request on the board done
4988 * queue and return ASC_ERROR.
4990 static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
4992 struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
4995 * Mutually exclusive access is required to 'asc_scsi_q' and
4996 * 'asc_sg_head' until after the request is started.
4998 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
5001 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
5003 asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
5006 * Build the ASC_SCSI_Q request.
5008 * For narrow boards a CDB length maximum of 12 bytes
5009 * is supported.
5011 if (scp->cmd_len > ASC_MAX_CDB_LEN) {
5012 ASC_PRINT3
5013 ("asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN %d\n",
5014 boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN);
5015 scp->result = HOST_BYTE(DID_ERROR);
5016 asc_enqueue(&boardp->done, scp, ASC_BACK);
5017 return ASC_ERROR;
5019 asc_scsi_q.cdbptr = &scp->cmnd[0];
5020 asc_scsi_q.q2.cdb_len = scp->cmd_len;
5021 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
5022 asc_scsi_q.q1.target_lun = scp->device->lun;
5023 asc_scsi_q.q2.target_ix =
5024 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
5025 asc_scsi_q.q1.sense_addr =
5026 cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
5027 asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
5030 * If there are any outstanding requests for the current target,
5031 * then every 255th request send an ORDERED request. This heuristic
5032 * tries to retain the benefit of request sorting while preventing
5033 * request starvation. 255 is the max number of tags or pending commands
5034 * a device may have outstanding.
5036 * The request count is incremented below for every successfully
5037 * started request.
5040 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
5041 (boardp->reqcnt[scp->device->id] % 255) == 0) {
5042 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
5043 } else {
5044 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
5048 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
5049 * buffer command.
5051 if (scp->use_sg == 0) {
5053 * CDB request of single contiguous buffer.
5055 ASC_STATS(scp->device->host, cont_cnt);
5056 scp->SCp.dma_handle = scp->request_bufflen ?
5057 dma_map_single(dev, scp->request_buffer,
5058 scp->request_bufflen,
5059 scp->sc_data_direction) : 0;
5060 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
5061 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
5062 ASC_STATS_ADD(scp->device->host, cont_xfer,
5063 ASC_CEILING(scp->request_bufflen, 512));
5064 asc_scsi_q.q1.sg_queue_cnt = 0;
5065 asc_scsi_q.sg_head = NULL;
5066 } else {
5068 * CDB scatter-gather request list.
5070 int sgcnt;
5071 int use_sg;
5072 struct scatterlist *slp;
5074 slp = (struct scatterlist *)scp->request_buffer;
5075 use_sg =
5076 dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
5078 if (use_sg > scp->device->host->sg_tablesize) {
5079 ASC_PRINT3
5080 ("asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
5081 boardp->id, use_sg,
5082 scp->device->host->sg_tablesize);
5083 dma_unmap_sg(dev, slp, scp->use_sg,
5084 scp->sc_data_direction);
5085 scp->result = HOST_BYTE(DID_ERROR);
5086 asc_enqueue(&boardp->done, scp, ASC_BACK);
5087 return ASC_ERROR;
5090 ASC_STATS(scp->device->host, sg_cnt);
5093 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
5094 * structure to point to it.
5096 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
5098 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
5099 asc_scsi_q.sg_head = &asc_sg_head;
5100 asc_scsi_q.q1.data_cnt = 0;
5101 asc_scsi_q.q1.data_addr = 0;
5102 /* This is a byte value, otherwise it would need to be swapped. */
5103 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
5104 ASC_STATS_ADD(scp->device->host, sg_elem,
5105 asc_sg_head.entry_cnt);
5108 * Convert scatter-gather list into ASC_SG_HEAD list.
5110 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
5111 asc_sg_head.sg_list[sgcnt].addr =
5112 cpu_to_le32(sg_dma_address(slp));
5113 asc_sg_head.sg_list[sgcnt].bytes =
5114 cpu_to_le32(sg_dma_len(slp));
5115 ASC_STATS_ADD(scp->device->host, sg_xfer,
5116 ASC_CEILING(sg_dma_len(slp), 512));
5120 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
5121 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
5123 return ASC_NOERROR;
5127 * Build a request structure for the Adv Library (Wide Board).
5129 * If an adv_req_t can not be allocated to issue the request,
5130 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
5132 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
5133 * microcode for DMA addresses or math operations are byte swapped
5134 * to little-endian order.
5136 static int
5137 adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
5138 ADV_SCSI_REQ_Q **adv_scsiqpp)
5140 adv_req_t *reqp;
5141 ADV_SCSI_REQ_Q *scsiqp;
5142 int i;
5143 int ret;
5144 struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
5147 * Allocate an adv_req_t structure from the board to execute
5148 * the command.
5150 if (boardp->adv_reqp == NULL) {
5151 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
5152 ASC_STATS(scp->device->host, adv_build_noreq);
5153 return ASC_BUSY;
5154 } else {
5155 reqp = boardp->adv_reqp;
5156 boardp->adv_reqp = reqp->next_reqp;
5157 reqp->next_reqp = NULL;
5161 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
5163 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5166 * Initialize the structure.
5168 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
5171 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
5173 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
5176 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
5178 reqp->cmndp = scp;
5181 * Build the ADV_SCSI_REQ_Q request.
5185 * Set CDB length and copy it to the request structure.
5186 * For wide boards a CDB length maximum of 16 bytes
5187 * is supported.
5189 if (scp->cmd_len > ADV_MAX_CDB_LEN) {
5190 ASC_PRINT3
5191 ("adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n",
5192 boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
5193 scp->result = HOST_BYTE(DID_ERROR);
5194 asc_enqueue(&boardp->done, scp, ASC_BACK);
5195 return ASC_ERROR;
5197 scsiqp->cdb_len = scp->cmd_len;
5198 /* Copy first 12 CDB bytes to cdb[]. */
5199 for (i = 0; i < scp->cmd_len && i < 12; i++) {
5200 scsiqp->cdb[i] = scp->cmnd[i];
5202 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
5203 for (; i < scp->cmd_len; i++) {
5204 scsiqp->cdb16[i - 12] = scp->cmnd[i];
5207 scsiqp->target_id = scp->device->id;
5208 scsiqp->target_lun = scp->device->lun;
5210 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
5211 scsiqp->sense_len = sizeof(scp->sense_buffer);
5214 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
5215 * buffer command.
5218 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
5219 scsiqp->vdata_addr = scp->request_buffer;
5220 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
5222 if (scp->use_sg == 0) {
5224 * CDB request of single contiguous buffer.
5226 reqp->sgblkp = NULL;
5227 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
5228 if (scp->request_bufflen) {
5229 scsiqp->vdata_addr = scp->request_buffer;
5230 scp->SCp.dma_handle =
5231 dma_map_single(dev, scp->request_buffer,
5232 scp->request_bufflen,
5233 scp->sc_data_direction);
5234 } else {
5235 scsiqp->vdata_addr = NULL;
5236 scp->SCp.dma_handle = 0;
5238 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
5239 scsiqp->sg_list_ptr = NULL;
5240 scsiqp->sg_real_addr = 0;
5241 ASC_STATS(scp->device->host, cont_cnt);
5242 ASC_STATS_ADD(scp->device->host, cont_xfer,
5243 ASC_CEILING(scp->request_bufflen, 512));
5244 } else {
5246 * CDB scatter-gather request list.
5248 struct scatterlist *slp;
5249 int use_sg;
5251 slp = (struct scatterlist *)scp->request_buffer;
5252 use_sg =
5253 dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
5255 if (use_sg > ADV_MAX_SG_LIST) {
5256 ASC_PRINT3
5257 ("adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
5258 boardp->id, use_sg,
5259 scp->device->host->sg_tablesize);
5260 dma_unmap_sg(dev, slp, scp->use_sg,
5261 scp->sc_data_direction);
5262 scp->result = HOST_BYTE(DID_ERROR);
5263 asc_enqueue(&boardp->done, scp, ASC_BACK);
5266 * Free the 'adv_req_t' structure by adding it back to the
5267 * board free list.
5269 reqp->next_reqp = boardp->adv_reqp;
5270 boardp->adv_reqp = reqp;
5272 return ASC_ERROR;
5275 if ((ret =
5276 adv_get_sglist(boardp, reqp, scp,
5277 use_sg)) != ADV_SUCCESS) {
5279 * Free the adv_req_t structure by adding it back to the
5280 * board free list.
5282 reqp->next_reqp = boardp->adv_reqp;
5283 boardp->adv_reqp = reqp;
5285 return ret;
5288 ASC_STATS(scp->device->host, sg_cnt);
5289 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
5292 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5293 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
5295 *adv_scsiqpp = scsiqp;
5297 return ASC_NOERROR;
5301 * Build scatter-gather list for Adv Library (Wide Board).
5303 * Additional ADV_SG_BLOCK structures will need to be allocated
5304 * if the total number of scatter-gather elements exceeds
5305 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
5306 * assumed to be physically contiguous.
5308 * Return:
5309 * ADV_SUCCESS(1) - SG List successfully created
5310 * ADV_ERROR(-1) - SG List creation failed
5312 static int
5313 adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
5314 int use_sg)
5316 adv_sgblk_t *sgblkp;
5317 ADV_SCSI_REQ_Q *scsiqp;
5318 struct scatterlist *slp;
5319 int sg_elem_cnt;
5320 ADV_SG_BLOCK *sg_block, *prev_sg_block;
5321 ADV_PADDR sg_block_paddr;
5322 int i;
5324 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5325 slp = (struct scatterlist *)scp->request_buffer;
5326 sg_elem_cnt = use_sg;
5327 prev_sg_block = NULL;
5328 reqp->sgblkp = NULL;
5330 do {
5332 * Allocate a 'adv_sgblk_t' structure from the board free
5333 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
5334 * (15) scatter-gather elements.
5336 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
5337 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
5338 ASC_STATS(scp->device->host, adv_build_nosg);
5341 * Allocation failed. Free 'adv_sgblk_t' structures already
5342 * allocated for the request.
5344 while ((sgblkp = reqp->sgblkp) != NULL) {
5345 /* Remove 'sgblkp' from the request list. */
5346 reqp->sgblkp = sgblkp->next_sgblkp;
5348 /* Add 'sgblkp' to the board free list. */
5349 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5350 boardp->adv_sgblkp = sgblkp;
5352 return ASC_BUSY;
5353 } else {
5354 /* Complete 'adv_sgblk_t' board allocation. */
5355 boardp->adv_sgblkp = sgblkp->next_sgblkp;
5356 sgblkp->next_sgblkp = NULL;
5359 * Get 8 byte aligned virtual and physical addresses for
5360 * the allocated ADV_SG_BLOCK structure.
5362 sg_block =
5363 (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
5364 sg_block_paddr = virt_to_bus(sg_block);
5367 * Check if this is the first 'adv_sgblk_t' for the request.
5369 if (reqp->sgblkp == NULL) {
5370 /* Request's first scatter-gather block. */
5371 reqp->sgblkp = sgblkp;
5374 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
5375 * address pointers.
5377 scsiqp->sg_list_ptr = sg_block;
5378 scsiqp->sg_real_addr =
5379 cpu_to_le32(sg_block_paddr);
5380 } else {
5381 /* Request's second or later scatter-gather block. */
5382 sgblkp->next_sgblkp = reqp->sgblkp;
5383 reqp->sgblkp = sgblkp;
5386 * Point the previous ADV_SG_BLOCK structure to
5387 * the newly allocated ADV_SG_BLOCK structure.
5389 ASC_ASSERT(prev_sg_block != NULL);
5390 prev_sg_block->sg_ptr =
5391 cpu_to_le32(sg_block_paddr);
5395 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
5396 sg_block->sg_list[i].sg_addr =
5397 cpu_to_le32(sg_dma_address(slp));
5398 sg_block->sg_list[i].sg_count =
5399 cpu_to_le32(sg_dma_len(slp));
5400 ASC_STATS_ADD(scp->device->host, sg_xfer,
5401 ASC_CEILING(sg_dma_len(slp), 512));
5403 if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */
5404 sg_block->sg_cnt = i + 1;
5405 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
5406 return ADV_SUCCESS;
5408 slp++;
5410 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
5411 prev_sg_block = sg_block;
5413 while (1);
5414 /* NOTREACHED */
5418 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
5420 * Interrupt callback function for the Narrow SCSI Asc Library.
5422 static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
5424 asc_board_t *boardp;
5425 struct scsi_cmnd *scp;
5426 struct Scsi_Host *shost;
5428 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
5429 (ulong)asc_dvc_varp, (ulong)qdonep);
5430 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
5433 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5434 * command that has been completed.
5436 scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
5437 ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp);
5439 if (scp == NULL) {
5440 ASC_PRINT("asc_isr_callback: scp is NULL\n");
5441 return;
5443 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5445 shost = scp->device->host;
5446 ASC_STATS(shost, callback);
5447 ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
5450 * If the request isn't found on the active queue, it may
5451 * have been removed to handle a reset request.
5452 * Display a message and return.
5454 boardp = ASC_BOARDP(shost);
5455 ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
5456 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5457 ASC_PRINT2
5458 ("asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
5459 boardp->id, (ulong)scp);
5460 return;
5464 * 'qdonep' contains the command's ending status.
5466 switch (qdonep->d3.done_stat) {
5467 case QD_NO_ERROR:
5468 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
5469 scp->result = 0;
5472 * If an INQUIRY command completed successfully, then call
5473 * the AscInquiryHandling() function to set-up the device.
5475 if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 &&
5476 (scp->request_bufflen - qdonep->remain_bytes) >= 8) {
5477 AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7,
5478 (ASC_SCSI_INQUIRY *)scp->
5479 request_buffer);
5483 * Check for an underrun condition.
5485 * If there was no error and an underrun condition, then
5486 * then return the number of underrun bytes.
5488 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
5489 qdonep->remain_bytes <= scp->request_bufflen) {
5490 ASC_DBG1(1,
5491 "asc_isr_callback: underrun condition %u bytes\n",
5492 (unsigned)qdonep->remain_bytes);
5493 scp->resid = qdonep->remain_bytes;
5495 break;
5497 case QD_WITH_ERROR:
5498 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
5499 switch (qdonep->d3.host_stat) {
5500 case QHSTA_NO_ERROR:
5501 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
5502 ASC_DBG(2,
5503 "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5504 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5505 sizeof(scp->sense_buffer));
5507 * Note: The 'status_byte()' macro used by target drivers
5508 * defined in scsi.h shifts the status byte returned by
5509 * host drivers right by 1 bit. This is why target drivers
5510 * also use right shifted status byte definitions. For
5511 * instance target drivers use CHECK_CONDITION, defined to
5512 * 0x1, instead of the SCSI defined check condition value
5513 * of 0x2. Host drivers are supposed to return the status
5514 * byte as it is defined by SCSI.
5516 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5517 STATUS_BYTE(qdonep->d3.scsi_stat);
5518 } else {
5519 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
5521 break;
5523 default:
5524 /* QHSTA error occurred */
5525 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
5526 qdonep->d3.host_stat);
5527 scp->result = HOST_BYTE(DID_BAD_TARGET);
5528 break;
5530 break;
5532 case QD_ABORTED_BY_HOST:
5533 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
5534 scp->result =
5535 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
5536 scsi_msg) |
5537 STATUS_BYTE(qdonep->d3.scsi_stat);
5538 break;
5540 default:
5541 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n",
5542 qdonep->d3.done_stat);
5543 scp->result =
5544 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
5545 scsi_msg) |
5546 STATUS_BYTE(qdonep->d3.scsi_stat);
5547 break;
5551 * If the 'init_tidmask' bit isn't already set for the target and the
5552 * current request finished normally, then set the bit for the target
5553 * to indicate that a device is present.
5555 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5556 qdonep->d3.done_stat == QD_NO_ERROR &&
5557 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
5558 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5562 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5563 * function, add the command to the end of the board's done queue.
5564 * The done function for the command will be called from
5565 * advansys_interrupt().
5567 asc_enqueue(&boardp->done, scp, ASC_BACK);
5569 return;
5573 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
5575 * Callback function for the Wide SCSI Adv Library.
5577 static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
5579 asc_board_t *boardp;
5580 adv_req_t *reqp;
5581 adv_sgblk_t *sgblkp;
5582 struct scsi_cmnd *scp;
5583 struct Scsi_Host *shost;
5584 ADV_DCNT resid_cnt;
5586 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
5587 (ulong)adv_dvc_varp, (ulong)scsiqp);
5588 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5591 * Get the adv_req_t structure for the command that has been
5592 * completed. The adv_req_t structure actually contains the
5593 * completed ADV_SCSI_REQ_Q structure.
5595 reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
5596 ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp);
5597 if (reqp == NULL) {
5598 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
5599 return;
5603 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5604 * command that has been completed.
5606 * Note: The adv_req_t request structure and adv_sgblk_t structure,
5607 * if any, are dropped, because a board structure pointer can not be
5608 * determined.
5610 scp = reqp->cmndp;
5611 ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp);
5612 if (scp == NULL) {
5613 ASC_PRINT
5614 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
5615 return;
5617 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5619 shost = scp->device->host;
5620 ASC_STATS(shost, callback);
5621 ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
5624 * If the request isn't found on the active queue, it may have been
5625 * removed to handle a reset request. Display a message and return.
5627 * Note: Because the structure may still be in use don't attempt
5628 * to free the adv_req_t and adv_sgblk_t, if any, structures.
5630 boardp = ASC_BOARDP(shost);
5631 ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
5632 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5633 ASC_PRINT2
5634 ("adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
5635 boardp->id, (ulong)scp);
5636 return;
5640 * 'done_status' contains the command's ending status.
5642 switch (scsiqp->done_status) {
5643 case QD_NO_ERROR:
5644 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
5645 scp->result = 0;
5648 * Check for an underrun condition.
5650 * If there was no error and an underrun condition, then
5651 * then return the number of underrun bytes.
5653 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
5654 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
5655 resid_cnt <= scp->request_bufflen) {
5656 ASC_DBG1(1,
5657 "adv_isr_callback: underrun condition %lu bytes\n",
5658 (ulong)resid_cnt);
5659 scp->resid = resid_cnt;
5661 break;
5663 case QD_WITH_ERROR:
5664 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
5665 switch (scsiqp->host_status) {
5666 case QHSTA_NO_ERROR:
5667 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
5668 ASC_DBG(2,
5669 "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5670 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5671 sizeof(scp->sense_buffer));
5673 * Note: The 'status_byte()' macro used by target drivers
5674 * defined in scsi.h shifts the status byte returned by
5675 * host drivers right by 1 bit. This is why target drivers
5676 * also use right shifted status byte definitions. For
5677 * instance target drivers use CHECK_CONDITION, defined to
5678 * 0x1, instead of the SCSI defined check condition value
5679 * of 0x2. Host drivers are supposed to return the status
5680 * byte as it is defined by SCSI.
5682 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5683 STATUS_BYTE(scsiqp->scsi_status);
5684 } else {
5685 scp->result = STATUS_BYTE(scsiqp->scsi_status);
5687 break;
5689 default:
5690 /* Some other QHSTA error occurred. */
5691 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
5692 scsiqp->host_status);
5693 scp->result = HOST_BYTE(DID_BAD_TARGET);
5694 break;
5696 break;
5698 case QD_ABORTED_BY_HOST:
5699 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
5700 scp->result =
5701 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
5702 break;
5704 default:
5705 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n",
5706 scsiqp->done_status);
5707 scp->result =
5708 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
5709 break;
5713 * If the 'init_tidmask' bit isn't already set for the target and the
5714 * current request finished normally, then set the bit for the target
5715 * to indicate that a device is present.
5717 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5718 scsiqp->done_status == QD_NO_ERROR &&
5719 scsiqp->host_status == QHSTA_NO_ERROR) {
5720 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5724 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5725 * function, add the command to the end of the board's done queue.
5726 * The done function for the command will be called from
5727 * advansys_interrupt().
5729 asc_enqueue(&boardp->done, scp, ASC_BACK);
5732 * Free all 'adv_sgblk_t' structures allocated for the request.
5734 while ((sgblkp = reqp->sgblkp) != NULL) {
5735 /* Remove 'sgblkp' from the request list. */
5736 reqp->sgblkp = sgblkp->next_sgblkp;
5738 /* Add 'sgblkp' to the board free list. */
5739 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5740 boardp->adv_sgblkp = sgblkp;
5744 * Free the adv_req_t structure used with the command by adding
5745 * it back to the board free list.
5747 reqp->next_reqp = boardp->adv_reqp;
5748 boardp->adv_reqp = reqp;
5750 ASC_DBG(1, "adv_isr_callback: done\n");
5752 return;
5756 * adv_async_callback() - Adv Library asynchronous event callback function.
5758 static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
5760 switch (code) {
5761 case ADV_ASYNC_SCSI_BUS_RESET_DET:
5763 * The firmware detected a SCSI Bus reset.
5765 ASC_DBG(0,
5766 "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
5767 break;
5769 case ADV_ASYNC_RDMA_FAILURE:
5771 * Handle RDMA failure by resetting the SCSI Bus and
5772 * possibly the chip if it is unresponsive. Log the error
5773 * with a unique code.
5775 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
5776 AdvResetChipAndSB(adv_dvc_varp);
5777 break;
5779 case ADV_HOST_SCSI_BUS_RESET:
5781 * Host generated SCSI bus reset occurred.
5783 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
5784 break;
5786 default:
5787 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
5788 break;
5793 * Add a 'REQP' to the end of specified queue. Set 'tidmask'
5794 * to indicate a command is queued for the device.
5796 * 'flag' may be either ASC_FRONT or ASC_BACK.
5798 * 'REQPNEXT(reqp)' returns reqp's next pointer.
5800 static void asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
5802 int tid;
5804 ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
5805 (ulong)ascq, (ulong)reqp, flag);
5806 ASC_ASSERT(reqp != NULL);
5807 ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
5808 tid = REQPTID(reqp);
5809 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5810 if (flag == ASC_FRONT) {
5811 reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
5812 ascq->q_first[tid] = reqp;
5813 /* If the queue was empty, set the last pointer. */
5814 if (ascq->q_last[tid] == NULL) {
5815 ascq->q_last[tid] = reqp;
5817 } else { /* ASC_BACK */
5818 if (ascq->q_last[tid] != NULL) {
5819 ascq->q_last[tid]->host_scribble =
5820 (unsigned char *)reqp;
5822 ascq->q_last[tid] = reqp;
5823 reqp->host_scribble = NULL;
5824 /* If the queue was empty, set the first pointer. */
5825 if (ascq->q_first[tid] == NULL) {
5826 ascq->q_first[tid] = reqp;
5829 /* The queue has at least one entry, set its bit. */
5830 ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
5831 #ifdef ADVANSYS_STATS
5832 /* Maintain request queue statistics. */
5833 ascq->q_tot_cnt[tid]++;
5834 ascq->q_cur_cnt[tid]++;
5835 if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
5836 ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
5837 ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
5838 tid, ascq->q_max_cnt[tid]);
5840 REQPTIME(reqp) = REQTIMESTAMP();
5841 #endif /* ADVANSYS_STATS */
5842 ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong)reqp);
5843 return;
5847 * Return first queued 'REQP' on the specified queue for
5848 * the specified target device. Clear the 'tidmask' bit for
5849 * the device if no more commands are left queued for it.
5851 * 'REQPNEXT(reqp)' returns reqp's next pointer.
5853 static REQP asc_dequeue(asc_queue_t *ascq, int tid)
5855 REQP reqp;
5857 ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5858 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5859 if ((reqp = ascq->q_first[tid]) != NULL) {
5860 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
5861 ascq->q_first[tid] = REQPNEXT(reqp);
5862 /* If the queue is empty, clear its bit and the last pointer. */
5863 if (ascq->q_first[tid] == NULL) {
5864 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5865 ASC_ASSERT(ascq->q_last[tid] == reqp);
5866 ascq->q_last[tid] = NULL;
5868 #ifdef ADVANSYS_STATS
5869 /* Maintain request queue statistics. */
5870 ascq->q_cur_cnt[tid]--;
5871 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
5872 REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
5873 #endif /* ADVANSYS_STATS */
5875 ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong)reqp);
5876 return reqp;
5880 * Return a pointer to a singly linked list of all the requests queued
5881 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
5883 * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
5884 * the last request returned in the singly linked list.
5886 * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
5887 * then all queued requests are concatenated into one list and
5888 * returned.
5890 * Note: If 'lastpp' is used to append a new list to the end of
5891 * an old list, only change the old list last pointer if '*lastpp'
5892 * (or the function return value) is not NULL, i.e. use a temporary
5893 * variable for 'lastpp' and check its value after the function return
5894 * before assigning it to the list last pointer.
5896 * Unfortunately collecting queuing time statistics adds overhead to
5897 * the function that isn't inherent to the function's algorithm.
5899 static REQP asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
5901 REQP firstp, lastp;
5902 int i;
5904 ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5905 ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
5908 * If 'tid' is not ASC_TID_ALL, return requests only for
5909 * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
5910 * requests for all tids.
5912 if (tid != ASC_TID_ALL) {
5913 /* Return all requests for the specified 'tid'. */
5914 if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
5915 /* List is empty; Set first and last return pointers to NULL. */
5916 firstp = lastp = NULL;
5917 } else {
5918 firstp = ascq->q_first[tid];
5919 lastp = ascq->q_last[tid];
5920 ascq->q_first[tid] = ascq->q_last[tid] = NULL;
5921 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5922 #ifdef ADVANSYS_STATS
5924 REQP reqp;
5925 ascq->q_cur_cnt[tid] = 0;
5926 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
5927 REQTIMESTAT("asc_dequeue_list", ascq,
5928 reqp, tid);
5931 #endif /* ADVANSYS_STATS */
5933 } else {
5934 /* Return all requests for all tids. */
5935 firstp = lastp = NULL;
5936 for (i = 0; i <= ADV_MAX_TID; i++) {
5937 if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
5938 if (firstp == NULL) {
5939 firstp = ascq->q_first[i];
5940 lastp = ascq->q_last[i];
5941 } else {
5942 ASC_ASSERT(lastp != NULL);
5943 lastp->host_scribble =
5944 (unsigned char *)ascq->q_first[i];
5945 lastp = ascq->q_last[i];
5947 ascq->q_first[i] = ascq->q_last[i] = NULL;
5948 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
5949 #ifdef ADVANSYS_STATS
5950 ascq->q_cur_cnt[i] = 0;
5951 #endif /* ADVANSYS_STATS */
5954 #ifdef ADVANSYS_STATS
5956 REQP reqp;
5957 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
5958 REQTIMESTAT("asc_dequeue_list", ascq, reqp,
5959 reqp->device->id);
5962 #endif /* ADVANSYS_STATS */
5964 if (lastpp) {
5965 *lastpp = lastp;
5967 ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong)firstp);
5968 return firstp;
5972 * Remove the specified 'REQP' from the specified queue for
5973 * the specified target device. Clear the 'tidmask' bit for the
5974 * device if no more commands are left queued for it.
5976 * 'REQPNEXT(reqp)' returns reqp's the next pointer.
5978 * Return ASC_TRUE if the command was found and removed,
5979 * otherwise return ASC_FALSE.
5981 static int asc_rmqueue(asc_queue_t *ascq, REQP reqp)
5983 REQP currp, prevp;
5984 int tid;
5985 int ret = ASC_FALSE;
5987 ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
5988 (ulong)ascq, (ulong)reqp);
5989 ASC_ASSERT(reqp != NULL);
5991 tid = REQPTID(reqp);
5992 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5995 * Handle the common case of 'reqp' being the first
5996 * entry on the queue.
5998 if (reqp == ascq->q_first[tid]) {
5999 ret = ASC_TRUE;
6000 ascq->q_first[tid] = REQPNEXT(reqp);
6001 /* If the queue is now empty, clear its bit and the last pointer. */
6002 if (ascq->q_first[tid] == NULL) {
6003 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
6004 ASC_ASSERT(ascq->q_last[tid] == reqp);
6005 ascq->q_last[tid] = NULL;
6007 } else if (ascq->q_first[tid] != NULL) {
6008 ASC_ASSERT(ascq->q_last[tid] != NULL);
6010 * Because the case of 'reqp' being the first entry has been
6011 * handled above and it is known the queue is not empty, if
6012 * 'reqp' is found on the queue it is guaranteed the queue will
6013 * not become empty and that 'q_first[tid]' will not be changed.
6015 * Set 'prevp' to the first entry, 'currp' to the second entry,
6016 * and search for 'reqp'.
6018 for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
6019 currp; prevp = currp, currp = REQPNEXT(currp)) {
6020 if (currp == reqp) {
6021 ret = ASC_TRUE;
6022 prevp->host_scribble =
6023 (unsigned char *)REQPNEXT(currp);
6024 reqp->host_scribble = NULL;
6025 if (ascq->q_last[tid] == reqp) {
6026 ascq->q_last[tid] = prevp;
6028 break;
6032 #ifdef ADVANSYS_STATS
6033 /* Maintain request queue statistics. */
6034 if (ret == ASC_TRUE) {
6035 ascq->q_cur_cnt[tid]--;
6036 REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
6038 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
6039 #endif /* ADVANSYS_STATS */
6040 ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong)reqp, ret);
6041 return ret;
6045 * Execute as many queued requests as possible for the specified queue.
6047 * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd.
6049 static void asc_execute_queue(asc_queue_t *ascq)
6051 ADV_SCSI_BIT_ID_TYPE scan_tidmask;
6052 REQP reqp;
6053 int i;
6055 ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong)ascq);
6057 * Execute queued commands for devices attached to
6058 * the current board in round-robin fashion.
6060 scan_tidmask = ascq->q_tidmask;
6061 do {
6062 for (i = 0; i <= ADV_MAX_TID; i++) {
6063 if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
6064 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
6065 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
6066 } else
6067 if (asc_execute_scsi_cmnd
6068 ((struct scsi_cmnd *)reqp)
6069 == ASC_BUSY) {
6070 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
6072 * The request returned ASC_BUSY. Enqueue at the front of
6073 * target's waiting list to maintain correct ordering.
6075 asc_enqueue(ascq, reqp, ASC_FRONT);
6079 } while (scan_tidmask);
6080 return;
6083 #ifdef CONFIG_PROC_FS
6085 * asc_prt_board_devices()
6087 * Print driver information for devices attached to the board.
6089 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6090 * cf. asc_prt_line().
6092 * Return the number of characters copied into 'cp'. No more than
6093 * 'cplen' characters will be copied to 'cp'.
6095 static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
6097 asc_board_t *boardp;
6098 int leftlen;
6099 int totlen;
6100 int len;
6101 int chip_scsi_id;
6102 int i;
6104 boardp = ASC_BOARDP(shost);
6105 leftlen = cplen;
6106 totlen = len = 0;
6108 len = asc_prt_line(cp, leftlen,
6109 "\nDevice Information for AdvanSys SCSI Host %d:\n",
6110 shost->host_no);
6111 ASC_PRT_NEXT();
6113 if (ASC_NARROW_BOARD(boardp)) {
6114 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6115 } else {
6116 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6119 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
6120 ASC_PRT_NEXT();
6121 for (i = 0; i <= ADV_MAX_TID; i++) {
6122 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
6123 len = asc_prt_line(cp, leftlen, " %X,", i);
6124 ASC_PRT_NEXT();
6127 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
6128 ASC_PRT_NEXT();
6130 return totlen;
6134 * Display Wide Board BIOS Information.
6136 static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
6138 asc_board_t *boardp;
6139 int leftlen;
6140 int totlen;
6141 int len;
6142 ushort major, minor, letter;
6144 boardp = ASC_BOARDP(shost);
6145 leftlen = cplen;
6146 totlen = len = 0;
6148 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
6149 ASC_PRT_NEXT();
6152 * If the BIOS saved a valid signature, then fill in
6153 * the BIOS code segment base address.
6155 if (boardp->bios_signature != 0x55AA) {
6156 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
6157 ASC_PRT_NEXT();
6158 len = asc_prt_line(cp, leftlen,
6159 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
6160 ASC_PRT_NEXT();
6161 len = asc_prt_line(cp, leftlen,
6162 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
6163 ASC_PRT_NEXT();
6164 } else {
6165 major = (boardp->bios_version >> 12) & 0xF;
6166 minor = (boardp->bios_version >> 8) & 0xF;
6167 letter = (boardp->bios_version & 0xFF);
6169 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
6170 major, minor,
6171 letter >= 26 ? '?' : letter + 'A');
6172 ASC_PRT_NEXT();
6175 * Current available ROM BIOS release is 3.1I for UW
6176 * and 3.2I for U2W. This code doesn't differentiate
6177 * UW and U2W boards.
6179 if (major < 3 || (major <= 3 && minor < 1) ||
6180 (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
6181 len = asc_prt_line(cp, leftlen,
6182 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
6183 ASC_PRT_NEXT();
6184 len = asc_prt_line(cp, leftlen,
6185 "ftp://ftp.connectcom.net/pub\n");
6186 ASC_PRT_NEXT();
6190 return totlen;
6194 * Add serial number to information bar if signature AAh
6195 * is found in at bit 15-9 (7 bits) of word 1.
6197 * Serial Number consists fo 12 alpha-numeric digits.
6199 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
6200 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
6201 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
6202 * 5 - Product revision (A-J) Word0: " "
6204 * Signature Word1: 15-9 (7 bits)
6205 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
6206 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
6208 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
6210 * Note 1: Only production cards will have a serial number.
6212 * Note 2: Signature is most significant 7 bits (0xFE).
6214 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
6216 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
6218 ushort w, num;
6220 if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
6221 return ASC_FALSE;
6222 } else {
6224 * First word - 6 digits.
6226 w = serialnum[0];
6228 /* Product type - 1st digit. */
6229 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
6230 /* Product type is P=Prototype */
6231 *cp += 0x8;
6233 cp++;
6235 /* Manufacturing location - 2nd digit. */
6236 *cp++ = 'A' + ((w & 0x1C00) >> 10);
6238 /* Product ID - 3rd, 4th digits. */
6239 num = w & 0x3FF;
6240 *cp++ = '0' + (num / 100);
6241 num %= 100;
6242 *cp++ = '0' + (num / 10);
6244 /* Product revision - 5th digit. */
6245 *cp++ = 'A' + (num % 10);
6248 * Second word
6250 w = serialnum[1];
6253 * Year - 6th digit.
6255 * If bit 15 of third word is set, then the
6256 * last digit of the year is greater than 7.
6258 if (serialnum[2] & 0x8000) {
6259 *cp++ = '8' + ((w & 0x1C0) >> 6);
6260 } else {
6261 *cp++ = '0' + ((w & 0x1C0) >> 6);
6264 /* Week of year - 7th, 8th digits. */
6265 num = w & 0x003F;
6266 *cp++ = '0' + num / 10;
6267 num %= 10;
6268 *cp++ = '0' + num;
6271 * Third word
6273 w = serialnum[2] & 0x7FFF;
6275 /* Serial number - 9th digit. */
6276 *cp++ = 'A' + (w / 1000);
6278 /* 10th, 11th, 12th digits. */
6279 num = w % 1000;
6280 *cp++ = '0' + num / 100;
6281 num %= 100;
6282 *cp++ = '0' + num / 10;
6283 num %= 10;
6284 *cp++ = '0' + num;
6286 *cp = '\0'; /* Null Terminate the string. */
6287 return ASC_TRUE;
6292 * asc_prt_asc_board_eeprom()
6294 * Print board EEPROM configuration.
6296 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6297 * cf. asc_prt_line().
6299 * Return the number of characters copied into 'cp'. No more than
6300 * 'cplen' characters will be copied to 'cp'.
6302 static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
6304 asc_board_t *boardp;
6305 ASC_DVC_VAR *asc_dvc_varp;
6306 int leftlen;
6307 int totlen;
6308 int len;
6309 ASCEEP_CONFIG *ep;
6310 int i;
6311 #ifdef CONFIG_ISA
6312 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
6313 #endif /* CONFIG_ISA */
6314 uchar serialstr[13];
6316 boardp = ASC_BOARDP(shost);
6317 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6318 ep = &boardp->eep_config.asc_eep;
6320 leftlen = cplen;
6321 totlen = len = 0;
6323 len = asc_prt_line(cp, leftlen,
6324 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6325 shost->host_no);
6326 ASC_PRT_NEXT();
6328 if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
6329 == ASC_TRUE) {
6330 len =
6331 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6332 serialstr);
6333 ASC_PRT_NEXT();
6334 } else {
6335 if (ep->adapter_info[5] == 0xBB) {
6336 len = asc_prt_line(cp, leftlen,
6337 " Default Settings Used for EEPROM-less Adapter.\n");
6338 ASC_PRT_NEXT();
6339 } else {
6340 len = asc_prt_line(cp, leftlen,
6341 " Serial Number Signature Not Present.\n");
6342 ASC_PRT_NEXT();
6346 len = asc_prt_line(cp, leftlen,
6347 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6348 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
6349 ep->max_tag_qng);
6350 ASC_PRT_NEXT();
6352 len = asc_prt_line(cp, leftlen,
6353 " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
6354 ASC_PRT_NEXT();
6356 len = asc_prt_line(cp, leftlen, " Target ID: ");
6357 ASC_PRT_NEXT();
6358 for (i = 0; i <= ASC_MAX_TID; i++) {
6359 len = asc_prt_line(cp, leftlen, " %d", i);
6360 ASC_PRT_NEXT();
6362 len = asc_prt_line(cp, leftlen, "\n");
6363 ASC_PRT_NEXT();
6365 len = asc_prt_line(cp, leftlen, " Disconnects: ");
6366 ASC_PRT_NEXT();
6367 for (i = 0; i <= ASC_MAX_TID; i++) {
6368 len = asc_prt_line(cp, leftlen, " %c",
6369 (ep->
6370 disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6371 'N');
6372 ASC_PRT_NEXT();
6374 len = asc_prt_line(cp, leftlen, "\n");
6375 ASC_PRT_NEXT();
6377 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
6378 ASC_PRT_NEXT();
6379 for (i = 0; i <= ASC_MAX_TID; i++) {
6380 len = asc_prt_line(cp, leftlen, " %c",
6381 (ep->
6382 use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6383 'N');
6384 ASC_PRT_NEXT();
6386 len = asc_prt_line(cp, leftlen, "\n");
6387 ASC_PRT_NEXT();
6389 len = asc_prt_line(cp, leftlen, " Start Motor: ");
6390 ASC_PRT_NEXT();
6391 for (i = 0; i <= ASC_MAX_TID; i++) {
6392 len = asc_prt_line(cp, leftlen, " %c",
6393 (ep->
6394 start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6395 'N');
6396 ASC_PRT_NEXT();
6398 len = asc_prt_line(cp, leftlen, "\n");
6399 ASC_PRT_NEXT();
6401 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6402 ASC_PRT_NEXT();
6403 for (i = 0; i <= ASC_MAX_TID; i++) {
6404 len = asc_prt_line(cp, leftlen, " %c",
6405 (ep->
6406 init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6407 'N');
6408 ASC_PRT_NEXT();
6410 len = asc_prt_line(cp, leftlen, "\n");
6411 ASC_PRT_NEXT();
6413 #ifdef CONFIG_ISA
6414 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
6415 len = asc_prt_line(cp, leftlen,
6416 " Host ISA DMA speed: %d MB/S\n",
6417 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
6418 ASC_PRT_NEXT();
6420 #endif /* CONFIG_ISA */
6422 return totlen;
6426 * asc_prt_adv_board_eeprom()
6428 * Print board EEPROM configuration.
6430 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6431 * cf. asc_prt_line().
6433 * Return the number of characters copied into 'cp'. No more than
6434 * 'cplen' characters will be copied to 'cp'.
6436 static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
6438 asc_board_t *boardp;
6439 ADV_DVC_VAR *adv_dvc_varp;
6440 int leftlen;
6441 int totlen;
6442 int len;
6443 int i;
6444 char *termstr;
6445 uchar serialstr[13];
6446 ADVEEP_3550_CONFIG *ep_3550 = NULL;
6447 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
6448 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
6449 ushort word;
6450 ushort *wordp;
6451 ushort sdtr_speed = 0;
6453 boardp = ASC_BOARDP(shost);
6454 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6455 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6456 ep_3550 = &boardp->eep_config.adv_3550_eep;
6457 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6458 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
6459 } else {
6460 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
6463 leftlen = cplen;
6464 totlen = len = 0;
6466 len = asc_prt_line(cp, leftlen,
6467 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6468 shost->host_no);
6469 ASC_PRT_NEXT();
6471 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6472 wordp = &ep_3550->serial_number_word1;
6473 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6474 wordp = &ep_38C0800->serial_number_word1;
6475 } else {
6476 wordp = &ep_38C1600->serial_number_word1;
6479 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
6480 len =
6481 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6482 serialstr);
6483 ASC_PRT_NEXT();
6484 } else {
6485 len = asc_prt_line(cp, leftlen,
6486 " Serial Number Signature Not Present.\n");
6487 ASC_PRT_NEXT();
6490 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6491 len = asc_prt_line(cp, leftlen,
6492 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6493 ep_3550->adapter_scsi_id,
6494 ep_3550->max_host_qng, ep_3550->max_dvc_qng);
6495 ASC_PRT_NEXT();
6496 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6497 len = asc_prt_line(cp, leftlen,
6498 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6499 ep_38C0800->adapter_scsi_id,
6500 ep_38C0800->max_host_qng,
6501 ep_38C0800->max_dvc_qng);
6502 ASC_PRT_NEXT();
6503 } else {
6504 len = asc_prt_line(cp, leftlen,
6505 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6506 ep_38C1600->adapter_scsi_id,
6507 ep_38C1600->max_host_qng,
6508 ep_38C1600->max_dvc_qng);
6509 ASC_PRT_NEXT();
6511 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6512 word = ep_3550->termination;
6513 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6514 word = ep_38C0800->termination_lvd;
6515 } else {
6516 word = ep_38C1600->termination_lvd;
6518 switch (word) {
6519 case 1:
6520 termstr = "Low Off/High Off";
6521 break;
6522 case 2:
6523 termstr = "Low Off/High On";
6524 break;
6525 case 3:
6526 termstr = "Low On/High On";
6527 break;
6528 default:
6529 case 0:
6530 termstr = "Automatic";
6531 break;
6534 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6535 len = asc_prt_line(cp, leftlen,
6536 " termination: %u (%s), bios_ctrl: 0x%x\n",
6537 ep_3550->termination, termstr,
6538 ep_3550->bios_ctrl);
6539 ASC_PRT_NEXT();
6540 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6541 len = asc_prt_line(cp, leftlen,
6542 " termination: %u (%s), bios_ctrl: 0x%x\n",
6543 ep_38C0800->termination_lvd, termstr,
6544 ep_38C0800->bios_ctrl);
6545 ASC_PRT_NEXT();
6546 } else {
6547 len = asc_prt_line(cp, leftlen,
6548 " termination: %u (%s), bios_ctrl: 0x%x\n",
6549 ep_38C1600->termination_lvd, termstr,
6550 ep_38C1600->bios_ctrl);
6551 ASC_PRT_NEXT();
6554 len = asc_prt_line(cp, leftlen, " Target ID: ");
6555 ASC_PRT_NEXT();
6556 for (i = 0; i <= ADV_MAX_TID; i++) {
6557 len = asc_prt_line(cp, leftlen, " %X", i);
6558 ASC_PRT_NEXT();
6560 len = asc_prt_line(cp, leftlen, "\n");
6561 ASC_PRT_NEXT();
6563 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6564 word = ep_3550->disc_enable;
6565 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6566 word = ep_38C0800->disc_enable;
6567 } else {
6568 word = ep_38C1600->disc_enable;
6570 len = asc_prt_line(cp, leftlen, " Disconnects: ");
6571 ASC_PRT_NEXT();
6572 for (i = 0; i <= ADV_MAX_TID; i++) {
6573 len = asc_prt_line(cp, leftlen, " %c",
6574 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6575 ASC_PRT_NEXT();
6577 len = asc_prt_line(cp, leftlen, "\n");
6578 ASC_PRT_NEXT();
6580 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6581 word = ep_3550->tagqng_able;
6582 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6583 word = ep_38C0800->tagqng_able;
6584 } else {
6585 word = ep_38C1600->tagqng_able;
6587 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
6588 ASC_PRT_NEXT();
6589 for (i = 0; i <= ADV_MAX_TID; i++) {
6590 len = asc_prt_line(cp, leftlen, " %c",
6591 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6592 ASC_PRT_NEXT();
6594 len = asc_prt_line(cp, leftlen, "\n");
6595 ASC_PRT_NEXT();
6597 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6598 word = ep_3550->start_motor;
6599 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6600 word = ep_38C0800->start_motor;
6601 } else {
6602 word = ep_38C1600->start_motor;
6604 len = asc_prt_line(cp, leftlen, " Start Motor: ");
6605 ASC_PRT_NEXT();
6606 for (i = 0; i <= ADV_MAX_TID; i++) {
6607 len = asc_prt_line(cp, leftlen, " %c",
6608 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6609 ASC_PRT_NEXT();
6611 len = asc_prt_line(cp, leftlen, "\n");
6612 ASC_PRT_NEXT();
6614 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6615 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6616 ASC_PRT_NEXT();
6617 for (i = 0; i <= ADV_MAX_TID; i++) {
6618 len = asc_prt_line(cp, leftlen, " %c",
6619 (ep_3550->
6620 sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
6621 'Y' : 'N');
6622 ASC_PRT_NEXT();
6624 len = asc_prt_line(cp, leftlen, "\n");
6625 ASC_PRT_NEXT();
6628 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6629 len = asc_prt_line(cp, leftlen, " Ultra Transfer: ");
6630 ASC_PRT_NEXT();
6631 for (i = 0; i <= ADV_MAX_TID; i++) {
6632 len = asc_prt_line(cp, leftlen, " %c",
6633 (ep_3550->
6634 ultra_able & ADV_TID_TO_TIDMASK(i))
6635 ? 'Y' : 'N');
6636 ASC_PRT_NEXT();
6638 len = asc_prt_line(cp, leftlen, "\n");
6639 ASC_PRT_NEXT();
6642 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6643 word = ep_3550->wdtr_able;
6644 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6645 word = ep_38C0800->wdtr_able;
6646 } else {
6647 word = ep_38C1600->wdtr_able;
6649 len = asc_prt_line(cp, leftlen, " Wide Transfer: ");
6650 ASC_PRT_NEXT();
6651 for (i = 0; i <= ADV_MAX_TID; i++) {
6652 len = asc_prt_line(cp, leftlen, " %c",
6653 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6654 ASC_PRT_NEXT();
6656 len = asc_prt_line(cp, leftlen, "\n");
6657 ASC_PRT_NEXT();
6659 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
6660 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
6661 len = asc_prt_line(cp, leftlen,
6662 " Synchronous Transfer Speed (Mhz):\n ");
6663 ASC_PRT_NEXT();
6664 for (i = 0; i <= ADV_MAX_TID; i++) {
6665 char *speed_str;
6667 if (i == 0) {
6668 sdtr_speed = adv_dvc_varp->sdtr_speed1;
6669 } else if (i == 4) {
6670 sdtr_speed = adv_dvc_varp->sdtr_speed2;
6671 } else if (i == 8) {
6672 sdtr_speed = adv_dvc_varp->sdtr_speed3;
6673 } else if (i == 12) {
6674 sdtr_speed = adv_dvc_varp->sdtr_speed4;
6676 switch (sdtr_speed & ADV_MAX_TID) {
6677 case 0:
6678 speed_str = "Off";
6679 break;
6680 case 1:
6681 speed_str = " 5";
6682 break;
6683 case 2:
6684 speed_str = " 10";
6685 break;
6686 case 3:
6687 speed_str = " 20";
6688 break;
6689 case 4:
6690 speed_str = " 40";
6691 break;
6692 case 5:
6693 speed_str = " 80";
6694 break;
6695 default:
6696 speed_str = "Unk";
6697 break;
6699 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
6700 ASC_PRT_NEXT();
6701 if (i == 7) {
6702 len = asc_prt_line(cp, leftlen, "\n ");
6703 ASC_PRT_NEXT();
6705 sdtr_speed >>= 4;
6707 len = asc_prt_line(cp, leftlen, "\n");
6708 ASC_PRT_NEXT();
6711 return totlen;
6715 * asc_prt_driver_conf()
6717 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6718 * cf. asc_prt_line().
6720 * Return the number of characters copied into 'cp'. No more than
6721 * 'cplen' characters will be copied to 'cp'.
6723 static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
6725 asc_board_t *boardp;
6726 int leftlen;
6727 int totlen;
6728 int len;
6729 int chip_scsi_id;
6731 boardp = ASC_BOARDP(shost);
6733 leftlen = cplen;
6734 totlen = len = 0;
6736 len = asc_prt_line(cp, leftlen,
6737 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
6738 shost->host_no);
6739 ASC_PRT_NEXT();
6741 len = asc_prt_line(cp, leftlen,
6742 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
6743 shost->host_busy, shost->last_reset, shost->max_id,
6744 shost->max_lun, shost->max_channel);
6745 ASC_PRT_NEXT();
6747 len = asc_prt_line(cp, leftlen,
6748 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
6749 shost->unique_id, shost->can_queue, shost->this_id,
6750 shost->sg_tablesize, shost->cmd_per_lun);
6751 ASC_PRT_NEXT();
6753 len = asc_prt_line(cp, leftlen,
6754 " unchecked_isa_dma %d, use_clustering %d\n",
6755 shost->unchecked_isa_dma, shost->use_clustering);
6756 ASC_PRT_NEXT();
6758 len = asc_prt_line(cp, leftlen,
6759 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
6760 boardp->flags, boardp->last_reset, jiffies,
6761 boardp->asc_n_io_port);
6762 ASC_PRT_NEXT();
6764 /* 'shost->n_io_port' may be truncated because it is only one byte. */
6765 len = asc_prt_line(cp, leftlen,
6766 " io_port 0x%x, n_io_port 0x%x\n",
6767 shost->io_port, shost->n_io_port);
6768 ASC_PRT_NEXT();
6770 if (ASC_NARROW_BOARD(boardp)) {
6771 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6772 } else {
6773 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6776 return totlen;
6780 * asc_prt_asc_board_info()
6782 * Print dynamic board configuration information.
6784 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6785 * cf. asc_prt_line().
6787 * Return the number of characters copied into 'cp'. No more than
6788 * 'cplen' characters will be copied to 'cp'.
6790 static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
6792 asc_board_t *boardp;
6793 int chip_scsi_id;
6794 int leftlen;
6795 int totlen;
6796 int len;
6797 ASC_DVC_VAR *v;
6798 ASC_DVC_CFG *c;
6799 int i;
6800 int renegotiate = 0;
6802 boardp = ASC_BOARDP(shost);
6803 v = &boardp->dvc_var.asc_dvc_var;
6804 c = &boardp->dvc_cfg.asc_dvc_cfg;
6805 chip_scsi_id = c->chip_scsi_id;
6807 leftlen = cplen;
6808 totlen = len = 0;
6810 len = asc_prt_line(cp, leftlen,
6811 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6812 shost->host_no);
6813 ASC_PRT_NEXT();
6815 len = asc_prt_line(cp, leftlen,
6816 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
6817 c->chip_version, c->lib_version, c->lib_serial_no,
6818 c->mcode_date);
6819 ASC_PRT_NEXT();
6821 len = asc_prt_line(cp, leftlen,
6822 " mcode_version 0x%x, err_code %u\n",
6823 c->mcode_version, v->err_code);
6824 ASC_PRT_NEXT();
6826 /* Current number of commands waiting for the host. */
6827 len = asc_prt_line(cp, leftlen,
6828 " Total Command Pending: %d\n", v->cur_total_qng);
6829 ASC_PRT_NEXT();
6831 len = asc_prt_line(cp, leftlen, " Command Queuing:");
6832 ASC_PRT_NEXT();
6833 for (i = 0; i <= ASC_MAX_TID; i++) {
6834 if ((chip_scsi_id == i) ||
6835 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6836 continue;
6838 len = asc_prt_line(cp, leftlen, " %X:%c",
6840 (v->
6841 use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
6842 'Y' : 'N');
6843 ASC_PRT_NEXT();
6845 len = asc_prt_line(cp, leftlen, "\n");
6846 ASC_PRT_NEXT();
6848 /* Current number of commands waiting for a device. */
6849 len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
6850 ASC_PRT_NEXT();
6851 for (i = 0; i <= ASC_MAX_TID; i++) {
6852 if ((chip_scsi_id == i) ||
6853 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6854 continue;
6856 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
6857 ASC_PRT_NEXT();
6859 len = asc_prt_line(cp, leftlen, "\n");
6860 ASC_PRT_NEXT();
6862 /* Current limit on number of commands that can be sent to a device. */
6863 len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
6864 ASC_PRT_NEXT();
6865 for (i = 0; i <= ASC_MAX_TID; i++) {
6866 if ((chip_scsi_id == i) ||
6867 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6868 continue;
6870 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
6871 ASC_PRT_NEXT();
6873 len = asc_prt_line(cp, leftlen, "\n");
6874 ASC_PRT_NEXT();
6876 /* Indicate whether the device has returned queue full status. */
6877 len = asc_prt_line(cp, leftlen, " Command Queue Full:");
6878 ASC_PRT_NEXT();
6879 for (i = 0; i <= ASC_MAX_TID; i++) {
6880 if ((chip_scsi_id == i) ||
6881 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6882 continue;
6884 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
6885 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
6886 i, boardp->queue_full_cnt[i]);
6887 } else {
6888 len = asc_prt_line(cp, leftlen, " %X:N", i);
6890 ASC_PRT_NEXT();
6892 len = asc_prt_line(cp, leftlen, "\n");
6893 ASC_PRT_NEXT();
6895 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6896 ASC_PRT_NEXT();
6897 for (i = 0; i <= ASC_MAX_TID; i++) {
6898 if ((chip_scsi_id == i) ||
6899 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6900 continue;
6902 len = asc_prt_line(cp, leftlen, " %X:%c",
6904 (v->
6905 sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6906 'N');
6907 ASC_PRT_NEXT();
6909 len = asc_prt_line(cp, leftlen, "\n");
6910 ASC_PRT_NEXT();
6912 for (i = 0; i <= ASC_MAX_TID; i++) {
6913 uchar syn_period_ix;
6915 if ((chip_scsi_id == i) ||
6916 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
6917 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
6918 continue;
6921 len = asc_prt_line(cp, leftlen, " %X:", i);
6922 ASC_PRT_NEXT();
6924 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
6925 len = asc_prt_line(cp, leftlen, " Asynchronous");
6926 ASC_PRT_NEXT();
6927 } else {
6928 syn_period_ix =
6929 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
6932 len = asc_prt_line(cp, leftlen,
6933 " Transfer Period Factor: %d (%d.%d Mhz),",
6934 v->sdtr_period_tbl[syn_period_ix],
6935 250 /
6936 v->sdtr_period_tbl[syn_period_ix],
6937 ASC_TENTHS(250,
6939 sdtr_period_tbl
6940 [syn_period_ix]));
6941 ASC_PRT_NEXT();
6943 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
6944 boardp->
6945 sdtr_data[i] & ASC_SYN_MAX_OFFSET);
6946 ASC_PRT_NEXT();
6949 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
6950 len = asc_prt_line(cp, leftlen, "*\n");
6951 renegotiate = 1;
6952 } else {
6953 len = asc_prt_line(cp, leftlen, "\n");
6955 ASC_PRT_NEXT();
6958 if (renegotiate) {
6959 len = asc_prt_line(cp, leftlen,
6960 " * = Re-negotiation pending before next command.\n");
6961 ASC_PRT_NEXT();
6964 return totlen;
6968 * asc_prt_adv_board_info()
6970 * Print dynamic board configuration information.
6972 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6973 * cf. asc_prt_line().
6975 * Return the number of characters copied into 'cp'. No more than
6976 * 'cplen' characters will be copied to 'cp'.
6978 static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
6980 asc_board_t *boardp;
6981 int leftlen;
6982 int totlen;
6983 int len;
6984 int i;
6985 ADV_DVC_VAR *v;
6986 ADV_DVC_CFG *c;
6987 AdvPortAddr iop_base;
6988 ushort chip_scsi_id;
6989 ushort lramword;
6990 uchar lrambyte;
6991 ushort tagqng_able;
6992 ushort sdtr_able, wdtr_able;
6993 ushort wdtr_done, sdtr_done;
6994 ushort period = 0;
6995 int renegotiate = 0;
6997 boardp = ASC_BOARDP(shost);
6998 v = &boardp->dvc_var.adv_dvc_var;
6999 c = &boardp->dvc_cfg.adv_dvc_cfg;
7000 iop_base = v->iop_base;
7001 chip_scsi_id = v->chip_scsi_id;
7003 leftlen = cplen;
7004 totlen = len = 0;
7006 len = asc_prt_line(cp, leftlen,
7007 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
7008 shost->host_no);
7009 ASC_PRT_NEXT();
7011 len = asc_prt_line(cp, leftlen,
7012 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
7013 v->iop_base,
7014 AdvReadWordRegister(iop_base,
7015 IOPW_SCSI_CFG1) & CABLE_DETECT,
7016 v->err_code);
7017 ASC_PRT_NEXT();
7019 len = asc_prt_line(cp, leftlen,
7020 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
7021 c->chip_version, c->lib_version, c->mcode_date,
7022 c->mcode_version);
7023 ASC_PRT_NEXT();
7025 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
7026 len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
7027 ASC_PRT_NEXT();
7028 for (i = 0; i <= ADV_MAX_TID; i++) {
7029 if ((chip_scsi_id == i) ||
7030 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7031 continue;
7034 len = asc_prt_line(cp, leftlen, " %X:%c",
7036 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7037 'N');
7038 ASC_PRT_NEXT();
7040 len = asc_prt_line(cp, leftlen, "\n");
7041 ASC_PRT_NEXT();
7043 len = asc_prt_line(cp, leftlen, " Queue Limit:");
7044 ASC_PRT_NEXT();
7045 for (i = 0; i <= ADV_MAX_TID; i++) {
7046 if ((chip_scsi_id == i) ||
7047 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7048 continue;
7051 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
7052 lrambyte);
7054 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
7055 ASC_PRT_NEXT();
7057 len = asc_prt_line(cp, leftlen, "\n");
7058 ASC_PRT_NEXT();
7060 len = asc_prt_line(cp, leftlen, " Command Pending:");
7061 ASC_PRT_NEXT();
7062 for (i = 0; i <= ADV_MAX_TID; i++) {
7063 if ((chip_scsi_id == i) ||
7064 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7065 continue;
7068 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
7069 lrambyte);
7071 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
7072 ASC_PRT_NEXT();
7074 len = asc_prt_line(cp, leftlen, "\n");
7075 ASC_PRT_NEXT();
7077 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7078 len = asc_prt_line(cp, leftlen, " Wide Enabled:");
7079 ASC_PRT_NEXT();
7080 for (i = 0; i <= ADV_MAX_TID; i++) {
7081 if ((chip_scsi_id == i) ||
7082 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7083 continue;
7086 len = asc_prt_line(cp, leftlen, " %X:%c",
7088 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7089 'N');
7090 ASC_PRT_NEXT();
7092 len = asc_prt_line(cp, leftlen, "\n");
7093 ASC_PRT_NEXT();
7095 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
7096 len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
7097 ASC_PRT_NEXT();
7098 for (i = 0; i <= ADV_MAX_TID; i++) {
7099 if ((chip_scsi_id == i) ||
7100 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7101 continue;
7104 AdvReadWordLram(iop_base,
7105 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7106 lramword);
7108 len = asc_prt_line(cp, leftlen, " %X:%d",
7109 i, (lramword & 0x8000) ? 16 : 8);
7110 ASC_PRT_NEXT();
7112 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
7113 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7114 len = asc_prt_line(cp, leftlen, "*");
7115 ASC_PRT_NEXT();
7116 renegotiate = 1;
7119 len = asc_prt_line(cp, leftlen, "\n");
7120 ASC_PRT_NEXT();
7122 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7123 len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
7124 ASC_PRT_NEXT();
7125 for (i = 0; i <= ADV_MAX_TID; i++) {
7126 if ((chip_scsi_id == i) ||
7127 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7128 continue;
7131 len = asc_prt_line(cp, leftlen, " %X:%c",
7133 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7134 'N');
7135 ASC_PRT_NEXT();
7137 len = asc_prt_line(cp, leftlen, "\n");
7138 ASC_PRT_NEXT();
7140 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
7141 for (i = 0; i <= ADV_MAX_TID; i++) {
7143 AdvReadWordLram(iop_base,
7144 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7145 lramword);
7146 lramword &= ~0x8000;
7148 if ((chip_scsi_id == i) ||
7149 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
7150 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
7151 continue;
7154 len = asc_prt_line(cp, leftlen, " %X:", i);
7155 ASC_PRT_NEXT();
7157 if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */
7158 len = asc_prt_line(cp, leftlen, " Asynchronous");
7159 ASC_PRT_NEXT();
7160 } else {
7161 len =
7162 asc_prt_line(cp, leftlen,
7163 " Transfer Period Factor: ");
7164 ASC_PRT_NEXT();
7166 if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */
7167 len =
7168 asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
7169 ASC_PRT_NEXT();
7170 } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */
7171 len =
7172 asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
7173 ASC_PRT_NEXT();
7174 } else { /* 20 Mhz or below. */
7176 period = (((lramword >> 8) * 25) + 50) / 4;
7178 if (period == 0) { /* Should never happen. */
7179 len =
7180 asc_prt_line(cp, leftlen,
7181 "%d (? Mhz), ");
7182 ASC_PRT_NEXT();
7183 } else {
7184 len = asc_prt_line(cp, leftlen,
7185 "%d (%d.%d Mhz),",
7186 period, 250 / period,
7187 ASC_TENTHS(250,
7188 period));
7189 ASC_PRT_NEXT();
7193 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
7194 lramword & 0x1F);
7195 ASC_PRT_NEXT();
7198 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7199 len = asc_prt_line(cp, leftlen, "*\n");
7200 renegotiate = 1;
7201 } else {
7202 len = asc_prt_line(cp, leftlen, "\n");
7204 ASC_PRT_NEXT();
7207 if (renegotiate) {
7208 len = asc_prt_line(cp, leftlen,
7209 " * = Re-negotiation pending before next command.\n");
7210 ASC_PRT_NEXT();
7213 return totlen;
7217 * asc_proc_copy()
7219 * Copy proc information to a read buffer taking into account the current
7220 * read offset in the file and the remaining space in the read buffer.
7222 static int
7223 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
7224 char *cp, int cplen)
7226 int cnt = 0;
7228 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
7229 (unsigned)offset, (unsigned)advoffset, cplen);
7230 if (offset <= advoffset) {
7231 /* Read offset below current offset, copy everything. */
7232 cnt = min(cplen, leftlen);
7233 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7234 (ulong)curbuf, (ulong)cp, cnt);
7235 memcpy(curbuf, cp, cnt);
7236 } else if (offset < advoffset + cplen) {
7237 /* Read offset within current range, partial copy. */
7238 cnt = (advoffset + cplen) - offset;
7239 cp = (cp + cplen) - cnt;
7240 cnt = min(cnt, leftlen);
7241 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7242 (ulong)curbuf, (ulong)cp, cnt);
7243 memcpy(curbuf, cp, cnt);
7245 return cnt;
7249 * asc_prt_line()
7251 * If 'cp' is NULL print to the console, otherwise print to a buffer.
7253 * Return 0 if printing to the console, otherwise return the number of
7254 * bytes written to the buffer.
7256 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
7257 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
7259 static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
7261 va_list args;
7262 int ret;
7263 char s[ASC_PRTLINE_SIZE];
7265 va_start(args, fmt);
7266 ret = vsprintf(s, fmt, args);
7267 ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
7268 if (buf == NULL) {
7269 (void)printk(s);
7270 ret = 0;
7271 } else {
7272 ret = min(buflen, ret);
7273 memcpy(buf, s, ret);
7275 va_end(args);
7276 return ret;
7278 #endif /* CONFIG_PROC_FS */
7281 * --- Functions Required by the Asc Library
7285 * Delay for 'n' milliseconds. Don't use the 'jiffies'
7286 * global variable which is incremented once every 5 ms
7287 * from a timer interrupt, because this function may be
7288 * called when interrupts are disabled.
7290 static void DvcSleepMilliSecond(ADV_DCNT n)
7292 ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong)n);
7293 mdelay(n);
7297 * Currently and inline noop but leave as a placeholder.
7298 * Leave DvcEnterCritical() as a noop placeholder.
7300 static inline ulong DvcEnterCritical(void)
7302 return 0;
7306 * Critical sections are all protected by the board spinlock.
7307 * Leave DvcLeaveCritical() as a noop placeholder.
7309 static inline void DvcLeaveCritical(ulong flags)
7311 return;
7315 * void
7316 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7318 * Calling/Exit State:
7319 * none
7321 * Description:
7322 * Output an ASC_SCSI_Q structure to the chip
7324 static void
7325 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7327 int i;
7329 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
7330 AscSetChipLramAddr(iop_base, s_addr);
7331 for (i = 0; i < 2 * words; i += 2) {
7332 if (i == 4 || i == 20) {
7333 continue;
7335 outpw(iop_base + IOP_RAM_DATA,
7336 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
7341 * void
7342 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7344 * Calling/Exit State:
7345 * none
7347 * Description:
7348 * Input an ASC_QDONE_INFO structure from the chip
7350 static void
7351 DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7353 int i;
7354 ushort word;
7356 AscSetChipLramAddr(iop_base, s_addr);
7357 for (i = 0; i < 2 * words; i += 2) {
7358 if (i == 10) {
7359 continue;
7361 word = inpw(iop_base + IOP_RAM_DATA);
7362 inbuf[i] = word & 0xff;
7363 inbuf[i + 1] = (word >> 8) & 0xff;
7365 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
7369 * Read a PCI configuration byte.
7371 static uchar __devinit DvcReadPCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset)
7373 #ifdef CONFIG_PCI
7374 uchar byte_data;
7375 pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
7376 return byte_data;
7377 #else /* !defined(CONFIG_PCI) */
7378 return 0;
7379 #endif /* !defined(CONFIG_PCI) */
7383 * Write a PCI configuration byte.
7385 static void __devinit
7386 DvcWritePCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset, uchar byte_data)
7388 #ifdef CONFIG_PCI
7389 pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
7390 #endif /* CONFIG_PCI */
7394 * Return the BIOS address of the adapter at the specified
7395 * I/O port and with the specified bus type.
7397 static ushort __devinit AscGetChipBiosAddress(PortAddr iop_base, ushort bus_type)
7399 ushort cfg_lsw;
7400 ushort bios_addr;
7403 * The PCI BIOS is re-located by the motherboard BIOS. Because
7404 * of this the driver can not determine where a PCI BIOS is
7405 * loaded and executes.
7407 if (bus_type & ASC_IS_PCI) {
7408 return (0);
7410 #ifdef CONFIG_ISA
7411 if ((bus_type & ASC_IS_EISA) != 0) {
7412 cfg_lsw = AscGetEisaChipCfg(iop_base);
7413 cfg_lsw &= 0x000F;
7414 bios_addr = (ushort)(ASC_BIOS_MIN_ADDR +
7415 (cfg_lsw * ASC_BIOS_BANK_SIZE));
7416 return (bios_addr);
7417 } /* if */
7418 #endif /* CONFIG_ISA */
7420 cfg_lsw = AscGetChipCfgLsw(iop_base);
7423 * ISA PnP uses the top bit as the 32K BIOS flag
7425 if (bus_type == ASC_IS_ISAPNP) {
7426 cfg_lsw &= 0x7FFF;
7428 /* if */
7429 bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
7430 ASC_BIOS_MIN_ADDR);
7431 return (bios_addr);
7435 * --- Functions Required by the Adv Library
7439 * DvcGetPhyAddr()
7441 * Return the physical address of 'vaddr' and set '*lenp' to the
7442 * number of physically contiguous bytes that follow 'vaddr'.
7443 * 'flag' indicates the type of structure whose physical address
7444 * is being translated.
7446 * Note: Because Linux currently doesn't page the kernel and all
7447 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
7449 ADV_PADDR
7450 DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
7451 uchar *vaddr, ADV_SDCNT *lenp, int flag)
7453 ADV_PADDR paddr;
7455 paddr = virt_to_bus(vaddr);
7457 ASC_DBG4(4,
7458 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
7459 (ulong)vaddr, (ulong)lenp, (ulong)*((ulong *)lenp),
7460 (ulong)paddr);
7462 return paddr;
7466 * Read a PCI configuration byte.
7468 static uchar __devinit DvcAdvReadPCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset)
7470 #ifdef CONFIG_PCI
7471 uchar byte_data;
7472 pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
7473 return byte_data;
7474 #else /* CONFIG_PCI */
7475 return 0;
7476 #endif /* CONFIG_PCI */
7480 * Write a PCI configuration byte.
7482 static void __devinit
7483 DvcAdvWritePCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset, uchar byte_data)
7485 #ifdef CONFIG_PCI
7486 pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
7487 #else /* CONFIG_PCI */
7488 return;
7489 #endif /* CONFIG_PCI */
7493 * --- Tracing and Debugging Functions
7496 #ifdef ADVANSYS_STATS
7497 #ifdef CONFIG_PROC_FS
7499 * asc_prt_board_stats()
7501 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7502 * cf. asc_prt_line().
7504 * Return the number of characters copied into 'cp'. No more than
7505 * 'cplen' characters will be copied to 'cp'.
7507 static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
7509 int leftlen;
7510 int totlen;
7511 int len;
7512 struct asc_stats *s;
7513 asc_board_t *boardp;
7515 leftlen = cplen;
7516 totlen = len = 0;
7518 boardp = ASC_BOARDP(shost);
7519 s = &boardp->asc_stats;
7521 len = asc_prt_line(cp, leftlen,
7522 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
7523 shost->host_no);
7524 ASC_PRT_NEXT();
7526 len = asc_prt_line(cp, leftlen,
7527 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
7528 s->queuecommand, s->reset, s->biosparam,
7529 s->interrupt);
7530 ASC_PRT_NEXT();
7532 len = asc_prt_line(cp, leftlen,
7533 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
7534 s->callback, s->done, s->build_error,
7535 s->adv_build_noreq, s->adv_build_nosg);
7536 ASC_PRT_NEXT();
7538 len = asc_prt_line(cp, leftlen,
7539 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
7540 s->exe_noerror, s->exe_busy, s->exe_error,
7541 s->exe_unknown);
7542 ASC_PRT_NEXT();
7545 * Display data transfer statistics.
7547 if (s->cont_cnt > 0) {
7548 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
7549 ASC_PRT_NEXT();
7551 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
7552 s->cont_xfer / 2,
7553 ASC_TENTHS(s->cont_xfer, 2));
7554 ASC_PRT_NEXT();
7556 /* Contiguous transfer average size */
7557 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
7558 (s->cont_xfer / 2) / s->cont_cnt,
7559 ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
7560 ASC_PRT_NEXT();
7563 if (s->sg_cnt > 0) {
7565 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
7566 s->sg_cnt, s->sg_elem);
7567 ASC_PRT_NEXT();
7569 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
7570 s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
7571 ASC_PRT_NEXT();
7573 /* Scatter gather transfer statistics */
7574 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
7575 s->sg_elem / s->sg_cnt,
7576 ASC_TENTHS(s->sg_elem, s->sg_cnt));
7577 ASC_PRT_NEXT();
7579 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
7580 (s->sg_xfer / 2) / s->sg_elem,
7581 ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
7582 ASC_PRT_NEXT();
7584 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
7585 (s->sg_xfer / 2) / s->sg_cnt,
7586 ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
7587 ASC_PRT_NEXT();
7591 * Display request queuing statistics.
7593 len = asc_prt_line(cp, leftlen,
7594 " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
7595 HZ);
7596 ASC_PRT_NEXT();
7598 return totlen;
7602 * asc_prt_target_stats()
7604 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7605 * cf. asc_prt_line().
7607 * This is separated from asc_prt_board_stats because a full set
7608 * of targets will overflow ASC_PRTBUF_SIZE.
7610 * Return the number of characters copied into 'cp'. No more than
7611 * 'cplen' characters will be copied to 'cp'.
7613 static int
7614 asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen)
7616 int leftlen;
7617 int totlen;
7618 int len;
7619 struct asc_stats *s;
7620 ushort chip_scsi_id;
7621 asc_board_t *boardp;
7622 asc_queue_t *active;
7623 asc_queue_t *waiting;
7625 leftlen = cplen;
7626 totlen = len = 0;
7628 boardp = ASC_BOARDP(shost);
7629 s = &boardp->asc_stats;
7631 active = &ASC_BOARDP(shost)->active;
7632 waiting = &ASC_BOARDP(shost)->waiting;
7634 if (ASC_NARROW_BOARD(boardp)) {
7635 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7636 } else {
7637 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7640 if ((chip_scsi_id == tgt_id) ||
7641 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
7642 return 0;
7645 do {
7646 if (active->q_tot_cnt[tgt_id] > 0
7647 || waiting->q_tot_cnt[tgt_id] > 0) {
7648 len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
7649 ASC_PRT_NEXT();
7651 len = asc_prt_line(cp, leftlen,
7652 " active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
7653 active->q_cur_cnt[tgt_id],
7654 active->q_max_cnt[tgt_id],
7655 active->q_tot_cnt[tgt_id],
7656 active->q_min_tim[tgt_id],
7657 active->q_max_tim[tgt_id],
7658 (active->q_tot_cnt[tgt_id] ==
7659 0) ? 0 : (active->
7660 q_tot_tim[tgt_id] /
7661 active->
7662 q_tot_cnt[tgt_id]),
7663 (active->q_tot_cnt[tgt_id] ==
7664 0) ? 0 : ASC_TENTHS(active->
7665 q_tot_tim
7666 [tgt_id],
7667 active->
7668 q_tot_cnt
7669 [tgt_id]));
7670 ASC_PRT_NEXT();
7672 len = asc_prt_line(cp, leftlen,
7673 " waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
7674 waiting->q_cur_cnt[tgt_id],
7675 waiting->q_max_cnt[tgt_id],
7676 waiting->q_tot_cnt[tgt_id],
7677 waiting->q_min_tim[tgt_id],
7678 waiting->q_max_tim[tgt_id],
7679 (waiting->q_tot_cnt[tgt_id] ==
7680 0) ? 0 : (waiting->
7681 q_tot_tim[tgt_id] /
7682 waiting->
7683 q_tot_cnt[tgt_id]),
7684 (waiting->q_tot_cnt[tgt_id] ==
7685 0) ? 0 : ASC_TENTHS(waiting->
7686 q_tot_tim
7687 [tgt_id],
7688 waiting->
7689 q_tot_cnt
7690 [tgt_id]));
7691 ASC_PRT_NEXT();
7693 } while (0);
7695 return totlen;
7697 #endif /* CONFIG_PROC_FS */
7698 #endif /* ADVANSYS_STATS */
7700 #ifdef ADVANSYS_DEBUG
7702 * asc_prt_scsi_host()
7704 static void asc_prt_scsi_host(struct Scsi_Host *s)
7706 asc_board_t *boardp;
7708 boardp = ASC_BOARDP(s);
7710 printk("Scsi_Host at addr 0x%lx\n", (ulong)s);
7711 printk(" host_busy %u, host_no %d, last_reset %d,\n",
7712 s->host_busy, s->host_no, (unsigned)s->last_reset);
7714 printk(" base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
7715 (ulong)s->base, (ulong)s->io_port, s->n_io_port, s->irq);
7717 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
7718 s->dma_channel, s->this_id, s->can_queue);
7720 printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
7721 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
7723 if (ASC_NARROW_BOARD(boardp)) {
7724 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
7725 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
7726 } else {
7727 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
7728 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
7733 * asc_prt_scsi_cmnd()
7735 static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
7737 printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s);
7739 printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
7740 (ulong)s->device->host, (ulong)s->device, s->device->id,
7741 s->device->lun, s->device->channel);
7743 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
7745 printk("sc_data_direction %u, resid %d\n",
7746 s->sc_data_direction, s->resid);
7748 printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len);
7750 printk(" serial_number 0x%x, retries %d, allowed %d\n",
7751 (unsigned)s->serial_number, s->retries, s->allowed);
7753 printk(" timeout_per_command %d\n", s->timeout_per_command);
7755 printk
7756 (" scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
7757 (ulong)s->scsi_done, (ulong)s->done, (ulong)s->host_scribble,
7758 s->result);
7760 printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
7764 * asc_prt_asc_dvc_var()
7766 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
7768 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
7770 printk
7771 (" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n",
7772 h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
7774 printk
7775 (" bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n",
7776 h->bus_type, (ulong)h->isr_callback, (ulong)h->exe_callback,
7777 (unsigned)h->init_sdtr);
7779 printk
7780 (" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n",
7781 (unsigned)h->sdtr_done, (unsigned)h->use_tagged_qng,
7782 (unsigned)h->unit_not_ready, (unsigned)h->chip_no);
7784 printk
7785 (" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n",
7786 (unsigned)h->queue_full_or_busy, (unsigned)h->start_motor,
7787 (unsigned)h->scsi_reset_wait);
7789 printk
7790 (" is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n",
7791 (unsigned)h->is_in_int, (unsigned)h->max_total_qng,
7792 (unsigned)h->cur_total_qng, (unsigned)h->in_critical_cnt);
7794 printk
7795 (" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n",
7796 (unsigned)h->last_q_shortage, (unsigned)h->init_state,
7797 (unsigned)h->no_scam, (unsigned)h->pci_fix_asyn_xfer);
7799 printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no);
7803 * asc_prt_asc_dvc_cfg()
7805 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
7807 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
7809 printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
7810 h->can_tagged_qng, h->cmd_qng_enabled);
7811 printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
7812 h->disc_enable, h->sdtr_enable);
7814 printk
7815 (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
7816 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
7817 h->chip_version);
7819 printk
7820 (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
7821 to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
7822 h->mcode_date);
7824 printk(" mcode_version %d, overrun_buf 0x%lx\n",
7825 h->mcode_version, (ulong)h->overrun_buf);
7829 * asc_prt_asc_scsi_q()
7831 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
7833 ASC_SG_HEAD *sgp;
7834 int i;
7836 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
7838 printk
7839 (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
7840 q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
7841 q->q2.tag_code);
7843 printk
7844 (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7845 (ulong)le32_to_cpu(q->q1.data_addr),
7846 (ulong)le32_to_cpu(q->q1.data_cnt),
7847 (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
7849 printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
7850 (ulong)q->cdbptr, q->q2.cdb_len,
7851 (ulong)q->sg_head, q->q1.sg_queue_cnt);
7853 if (q->sg_head) {
7854 sgp = q->sg_head;
7855 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
7856 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
7857 sgp->queue_cnt);
7858 for (i = 0; i < sgp->entry_cnt; i++) {
7859 printk(" [%u]: addr 0x%lx, bytes %lu\n",
7860 i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
7861 (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
7868 * asc_prt_asc_qdone_info()
7870 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
7872 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
7873 printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
7874 (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
7875 q->d2.tag_code);
7876 printk
7877 (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
7878 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
7882 * asc_prt_adv_dvc_var()
7884 * Display an ADV_DVC_VAR structure.
7886 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
7888 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
7890 printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
7891 (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
7893 printk(" isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
7894 (ulong)h->isr_callback, (unsigned)h->sdtr_able,
7895 (unsigned)h->wdtr_able);
7897 printk(" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
7898 (unsigned)h->start_motor,
7899 (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no);
7901 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
7902 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
7903 (ulong)h->carr_freelist);
7905 printk(" icq_sp 0x%lx, irq_sp 0x%lx\n",
7906 (ulong)h->icq_sp, (ulong)h->irq_sp);
7908 printk(" no_scam 0x%x, tagqng_able 0x%x\n",
7909 (unsigned)h->no_scam, (unsigned)h->tagqng_able);
7911 printk(" chip_scsi_id 0x%x, cfg 0x%lx\n",
7912 (unsigned)h->chip_scsi_id, (ulong)h->cfg);
7916 * asc_prt_adv_dvc_cfg()
7918 * Display an ADV_DVC_CFG structure.
7920 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
7922 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
7924 printk(" disc_enable 0x%x, termination 0x%x\n",
7925 h->disc_enable, h->termination);
7927 printk(" chip_version 0x%x, mcode_date 0x%x\n",
7928 h->chip_version, h->mcode_date);
7930 printk(" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
7931 h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
7933 printk(" control_flag 0x%x, pci_slot_info 0x%x\n",
7934 h->control_flag, h->pci_slot_info);
7938 * asc_prt_adv_scsi_req_q()
7940 * Display an ADV_SCSI_REQ_Q structure.
7942 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
7944 int sg_blk_cnt;
7945 struct asc_sg_block *sg_ptr;
7947 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
7949 printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
7950 q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
7952 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
7953 q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
7955 printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7956 (ulong)le32_to_cpu(q->data_cnt),
7957 (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
7959 printk
7960 (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
7961 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
7963 printk(" sg_working_ix 0x%x, target_cmd %u\n",
7964 q->sg_working_ix, q->target_cmd);
7966 printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
7967 (ulong)le32_to_cpu(q->scsiq_rptr),
7968 (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
7970 /* Display the request's ADV_SG_BLOCK structures. */
7971 if (q->sg_list_ptr != NULL) {
7972 sg_blk_cnt = 0;
7973 while (1) {
7975 * 'sg_ptr' is a physical address. Convert it to a virtual
7976 * address by indexing 'sg_blk_cnt' into the virtual address
7977 * array 'sg_list_ptr'.
7979 * XXX - Assumes all SG physical blocks are virtually contiguous.
7981 sg_ptr =
7982 &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
7983 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
7984 if (sg_ptr->sg_ptr == 0) {
7985 break;
7987 sg_blk_cnt++;
7993 * asc_prt_adv_sgblock()
7995 * Display an ADV_SG_BLOCK structure.
7997 static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
7999 int i;
8001 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
8002 (ulong)b, sgblockno);
8003 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
8004 b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
8005 ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
8006 if (b->sg_ptr != 0) {
8007 ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
8009 for (i = 0; i < b->sg_cnt; i++) {
8010 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
8011 i, (ulong)b->sg_list[i].sg_addr,
8012 (ulong)b->sg_list[i].sg_count);
8017 * asc_prt_hex()
8019 * Print hexadecimal output in 4 byte groupings 32 bytes
8020 * or 8 double-words per line.
8022 static void asc_prt_hex(char *f, uchar *s, int l)
8024 int i;
8025 int j;
8026 int k;
8027 int m;
8029 printk("%s: (%d bytes)\n", f, l);
8031 for (i = 0; i < l; i += 32) {
8033 /* Display a maximum of 8 double-words per line. */
8034 if ((k = (l - i) / 4) >= 8) {
8035 k = 8;
8036 m = 0;
8037 } else {
8038 m = (l - i) % 4;
8041 for (j = 0; j < k; j++) {
8042 printk(" %2.2X%2.2X%2.2X%2.2X",
8043 (unsigned)s[i + (j * 4)],
8044 (unsigned)s[i + (j * 4) + 1],
8045 (unsigned)s[i + (j * 4) + 2],
8046 (unsigned)s[i + (j * 4) + 3]);
8049 switch (m) {
8050 case 0:
8051 default:
8052 break;
8053 case 1:
8054 printk(" %2.2X", (unsigned)s[i + (j * 4)]);
8055 break;
8056 case 2:
8057 printk(" %2.2X%2.2X",
8058 (unsigned)s[i + (j * 4)],
8059 (unsigned)s[i + (j * 4) + 1]);
8060 break;
8061 case 3:
8062 printk(" %2.2X%2.2X%2.2X",
8063 (unsigned)s[i + (j * 4) + 1],
8064 (unsigned)s[i + (j * 4) + 2],
8065 (unsigned)s[i + (j * 4) + 3]);
8066 break;
8069 printk("\n");
8072 #endif /* ADVANSYS_DEBUG */
8075 * --- Asc Library Functions
8078 static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
8080 PortAddr eisa_cfg_iop;
8082 eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8083 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
8084 return (inpw(eisa_cfg_iop));
8087 static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
8089 ushort cfg_lsw;
8091 if (AscGetChipScsiID(iop_base) == new_host_id) {
8092 return (new_host_id);
8094 cfg_lsw = AscGetChipCfgLsw(iop_base);
8095 cfg_lsw &= 0xF8FF;
8096 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
8097 AscSetChipCfgLsw(iop_base, cfg_lsw);
8098 return (AscGetChipScsiID(iop_base));
8101 static uchar __devinit AscGetChipScsiCtrl(PortAddr iop_base)
8103 uchar sc;
8105 AscSetBank(iop_base, 1);
8106 sc = inp(iop_base + IOP_REG_SC);
8107 AscSetBank(iop_base, 0);
8108 return (sc);
8111 static uchar __devinit AscGetChipVersion(PortAddr iop_base, ushort bus_type)
8113 if ((bus_type & ASC_IS_EISA) != 0) {
8114 PortAddr eisa_iop;
8115 uchar revision;
8116 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8117 (PortAddr) ASC_EISA_REV_IOP_MASK;
8118 revision = inp(eisa_iop);
8119 return ((uchar)((ASC_CHIP_MIN_VER_EISA - 1) + revision));
8121 return (AscGetChipVerNo(iop_base));
8124 static ushort __devinit AscGetChipBusType(PortAddr iop_base)
8126 ushort chip_ver;
8128 chip_ver = AscGetChipVerNo(iop_base);
8129 if ((chip_ver >= ASC_CHIP_MIN_VER_VL)
8130 && (chip_ver <= ASC_CHIP_MAX_VER_VL)
8132 if (((iop_base & 0x0C30) == 0x0C30)
8133 || ((iop_base & 0x0C50) == 0x0C50)
8135 return (ASC_IS_EISA);
8137 return (ASC_IS_VL);
8139 if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
8140 (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
8141 if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
8142 return (ASC_IS_ISAPNP);
8144 return (ASC_IS_ISA);
8145 } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
8146 (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
8147 return (ASC_IS_PCI);
8149 return (0);
8152 static ASC_DCNT
8153 AscLoadMicroCode(PortAddr iop_base,
8154 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
8156 ASC_DCNT chksum;
8157 ushort mcode_word_size;
8158 ushort mcode_chksum;
8160 /* Write the microcode buffer starting at LRAM address 0. */
8161 mcode_word_size = (ushort)(mcode_size >> 1);
8162 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
8163 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
8165 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
8166 ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum);
8167 mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
8168 (ushort)ASC_CODE_SEC_BEG,
8169 (ushort)((mcode_size -
8170 s_addr - (ushort)
8171 ASC_CODE_SEC_BEG) /
8172 2));
8173 ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
8174 (ulong)mcode_chksum);
8175 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
8176 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
8177 return (chksum);
8180 static int AscFindSignature(PortAddr iop_base)
8182 ushort sig_word;
8184 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
8185 iop_base, AscGetChipSignatureByte(iop_base));
8186 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
8187 ASC_DBG2(1,
8188 "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
8189 iop_base, AscGetChipSignatureWord(iop_base));
8190 sig_word = AscGetChipSignatureWord(iop_base);
8191 if ((sig_word == (ushort)ASC_1000_ID0W) ||
8192 (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
8193 return (1);
8196 return (0);
8199 static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __initdata = {
8200 0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
8201 ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
8204 #ifdef CONFIG_ISA
8205 static uchar _isa_pnp_inited __initdata = 0;
8207 static PortAddr __init AscSearchIOPortAddr(PortAddr iop_beg, ushort bus_type)
8209 if (bus_type & ASC_IS_VL) {
8210 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
8211 if (AscGetChipVersion(iop_beg, bus_type) <=
8212 ASC_CHIP_MAX_VER_VL) {
8213 return (iop_beg);
8216 return (0);
8218 if (bus_type & ASC_IS_ISA) {
8219 if (_isa_pnp_inited == 0) {
8220 AscSetISAPNPWaitForKey();
8221 _isa_pnp_inited++;
8223 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
8224 if ((AscGetChipVersion(iop_beg, bus_type) &
8225 ASC_CHIP_VER_ISA_BIT) != 0) {
8226 return (iop_beg);
8229 return (0);
8231 return (0);
8234 static PortAddr __init AscSearchIOPortAddr11(PortAddr s_addr)
8236 int i;
8237 PortAddr iop_base;
8239 for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
8240 if (_asc_def_iop_base[i] > s_addr) {
8241 break;
8244 for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
8245 iop_base = _asc_def_iop_base[i];
8246 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
8247 ASC_DBG1(1,
8248 "AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n",
8249 iop_base);
8250 continue;
8252 ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n",
8253 iop_base);
8254 release_region(iop_base, ASC_IOADR_GAP);
8255 if (AscFindSignature(iop_base)) {
8256 return (iop_base);
8259 return (0);
8262 static void __init AscSetISAPNPWaitForKey(void)
8264 outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
8265 outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
8266 return;
8268 #endif /* CONFIG_ISA */
8270 static void __devinit AscToggleIRQAct(PortAddr iop_base)
8272 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
8273 AscSetChipStatus(iop_base, 0);
8274 return;
8277 static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
8279 ushort cfg_lsw;
8280 uchar chip_irq;
8282 if ((bus_type & ASC_IS_EISA) != 0) {
8283 cfg_lsw = AscGetEisaChipCfg(iop_base);
8284 chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10);
8285 if ((chip_irq == 13) || (chip_irq > 15)) {
8286 return (0);
8288 return (chip_irq);
8290 if ((bus_type & ASC_IS_VL) != 0) {
8291 cfg_lsw = AscGetChipCfgLsw(iop_base);
8292 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07));
8293 if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) {
8294 return (0);
8296 return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1)));
8298 cfg_lsw = AscGetChipCfgLsw(iop_base);
8299 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03));
8300 if (chip_irq == 3)
8301 chip_irq += (uchar)2;
8302 return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
8305 static uchar __devinit
8306 AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
8308 ushort cfg_lsw;
8310 if ((bus_type & ASC_IS_VL) != 0) {
8311 if (irq_no != 0) {
8312 if ((irq_no < ASC_MIN_IRQ_NO)
8313 || (irq_no > ASC_MAX_IRQ_NO)) {
8314 irq_no = 0;
8315 } else {
8316 irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1));
8319 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3);
8320 cfg_lsw |= (ushort)0x0010;
8321 AscSetChipCfgLsw(iop_base, cfg_lsw);
8322 AscToggleIRQAct(iop_base);
8323 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0);
8324 cfg_lsw |= (ushort)((irq_no & 0x07) << 2);
8325 AscSetChipCfgLsw(iop_base, cfg_lsw);
8326 AscToggleIRQAct(iop_base);
8327 return (AscGetChipIRQ(iop_base, bus_type));
8329 if ((bus_type & (ASC_IS_ISA)) != 0) {
8330 if (irq_no == 15)
8331 irq_no -= (uchar)2;
8332 irq_no -= (uchar)ASC_MIN_IRQ_NO;
8333 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3);
8334 cfg_lsw |= (ushort)((irq_no & 0x03) << 2);
8335 AscSetChipCfgLsw(iop_base, cfg_lsw);
8336 return (AscGetChipIRQ(iop_base, bus_type));
8338 return (0);
8341 #ifdef CONFIG_ISA
8342 static void __devinit AscEnableIsaDma(uchar dma_channel)
8344 if (dma_channel < 4) {
8345 outp(0x000B, (ushort)(0xC0 | dma_channel));
8346 outp(0x000A, dma_channel);
8347 } else if (dma_channel < 8) {
8348 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
8349 outp(0x00D4, (ushort)(dma_channel - 4));
8351 return;
8353 #endif /* CONFIG_ISA */
8355 static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
8357 EXT_MSG ext_msg;
8358 EXT_MSG out_msg;
8359 ushort halt_q_addr;
8360 int sdtr_accept;
8361 ushort int_halt_code;
8362 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8363 ASC_SCSI_BIT_ID_TYPE target_id;
8364 PortAddr iop_base;
8365 uchar tag_code;
8366 uchar q_status;
8367 uchar halt_qp;
8368 uchar sdtr_data;
8369 uchar target_ix;
8370 uchar q_cntl, tid_no;
8371 uchar cur_dvc_qng;
8372 uchar asyn_sdtr;
8373 uchar scsi_status;
8374 asc_board_t *boardp;
8376 ASC_ASSERT(asc_dvc->drv_ptr != NULL);
8377 boardp = asc_dvc->drv_ptr;
8379 iop_base = asc_dvc->iop_base;
8380 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
8382 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
8383 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
8384 target_ix = AscReadLramByte(iop_base,
8385 (ushort)(halt_q_addr +
8386 (ushort)ASC_SCSIQ_B_TARGET_IX));
8387 q_cntl =
8388 AscReadLramByte(iop_base,
8389 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8390 tid_no = ASC_TIX_TO_TID(target_ix);
8391 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
8392 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8393 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
8394 } else {
8395 asyn_sdtr = 0;
8397 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
8398 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8399 AscSetChipSDTR(iop_base, 0, tid_no);
8400 boardp->sdtr_data[tid_no] = 0;
8402 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8403 return (0);
8404 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
8405 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8406 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8407 boardp->sdtr_data[tid_no] = asyn_sdtr;
8409 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8410 return (0);
8411 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
8413 AscMemWordCopyPtrFromLram(iop_base,
8414 ASCV_MSGIN_BEG,
8415 (uchar *)&ext_msg,
8416 sizeof(EXT_MSG) >> 1);
8418 if (ext_msg.msg_type == MS_EXTEND &&
8419 ext_msg.msg_req == MS_SDTR_CODE &&
8420 ext_msg.msg_len == MS_SDTR_LEN) {
8421 sdtr_accept = TRUE;
8422 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
8424 sdtr_accept = FALSE;
8425 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
8427 if ((ext_msg.xfer_period <
8428 asc_dvc->sdtr_period_tbl[asc_dvc->
8429 host_init_sdtr_index])
8430 || (ext_msg.xfer_period >
8431 asc_dvc->sdtr_period_tbl[asc_dvc->
8432 max_sdtr_index])) {
8433 sdtr_accept = FALSE;
8434 ext_msg.xfer_period =
8435 asc_dvc->sdtr_period_tbl[asc_dvc->
8436 host_init_sdtr_index];
8438 if (sdtr_accept) {
8439 sdtr_data =
8440 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
8441 ext_msg.req_ack_offset);
8442 if ((sdtr_data == 0xFF)) {
8444 q_cntl |= QC_MSG_OUT;
8445 asc_dvc->init_sdtr &= ~target_id;
8446 asc_dvc->sdtr_done &= ~target_id;
8447 AscSetChipSDTR(iop_base, asyn_sdtr,
8448 tid_no);
8449 boardp->sdtr_data[tid_no] = asyn_sdtr;
8452 if (ext_msg.req_ack_offset == 0) {
8454 q_cntl &= ~QC_MSG_OUT;
8455 asc_dvc->init_sdtr &= ~target_id;
8456 asc_dvc->sdtr_done &= ~target_id;
8457 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8458 } else {
8459 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
8461 q_cntl &= ~QC_MSG_OUT;
8462 asc_dvc->sdtr_done |= target_id;
8463 asc_dvc->init_sdtr |= target_id;
8464 asc_dvc->pci_fix_asyn_xfer &=
8465 ~target_id;
8466 sdtr_data =
8467 AscCalSDTRData(asc_dvc,
8468 ext_msg.xfer_period,
8469 ext_msg.
8470 req_ack_offset);
8471 AscSetChipSDTR(iop_base, sdtr_data,
8472 tid_no);
8473 boardp->sdtr_data[tid_no] = sdtr_data;
8474 } else {
8476 q_cntl |= QC_MSG_OUT;
8477 AscMsgOutSDTR(asc_dvc,
8478 ext_msg.xfer_period,
8479 ext_msg.req_ack_offset);
8480 asc_dvc->pci_fix_asyn_xfer &=
8481 ~target_id;
8482 sdtr_data =
8483 AscCalSDTRData(asc_dvc,
8484 ext_msg.xfer_period,
8485 ext_msg.
8486 req_ack_offset);
8487 AscSetChipSDTR(iop_base, sdtr_data,
8488 tid_no);
8489 boardp->sdtr_data[tid_no] = sdtr_data;
8490 asc_dvc->sdtr_done |= target_id;
8491 asc_dvc->init_sdtr |= target_id;
8495 AscWriteLramByte(iop_base,
8496 (ushort)(halt_q_addr +
8497 (ushort)ASC_SCSIQ_B_CNTL),
8498 q_cntl);
8499 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8500 return (0);
8501 } else if (ext_msg.msg_type == MS_EXTEND &&
8502 ext_msg.msg_req == MS_WDTR_CODE &&
8503 ext_msg.msg_len == MS_WDTR_LEN) {
8505 ext_msg.wdtr_width = 0;
8506 AscMemWordCopyPtrToLram(iop_base,
8507 ASCV_MSGOUT_BEG,
8508 (uchar *)&ext_msg,
8509 sizeof(EXT_MSG) >> 1);
8510 q_cntl |= QC_MSG_OUT;
8511 AscWriteLramByte(iop_base,
8512 (ushort)(halt_q_addr +
8513 (ushort)ASC_SCSIQ_B_CNTL),
8514 q_cntl);
8515 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8516 return (0);
8517 } else {
8519 ext_msg.msg_type = MESSAGE_REJECT;
8520 AscMemWordCopyPtrToLram(iop_base,
8521 ASCV_MSGOUT_BEG,
8522 (uchar *)&ext_msg,
8523 sizeof(EXT_MSG) >> 1);
8524 q_cntl |= QC_MSG_OUT;
8525 AscWriteLramByte(iop_base,
8526 (ushort)(halt_q_addr +
8527 (ushort)ASC_SCSIQ_B_CNTL),
8528 q_cntl);
8529 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8530 return (0);
8532 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
8534 q_cntl |= QC_REQ_SENSE;
8536 if ((asc_dvc->init_sdtr & target_id) != 0) {
8538 asc_dvc->sdtr_done &= ~target_id;
8540 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8541 q_cntl |= QC_MSG_OUT;
8542 AscMsgOutSDTR(asc_dvc,
8543 asc_dvc->
8544 sdtr_period_tbl[(sdtr_data >> 4) &
8545 (uchar)(asc_dvc->
8546 max_sdtr_index -
8547 1)],
8548 (uchar)(sdtr_data & (uchar)
8549 ASC_SYN_MAX_OFFSET));
8552 AscWriteLramByte(iop_base,
8553 (ushort)(halt_q_addr +
8554 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8556 tag_code = AscReadLramByte(iop_base,
8557 (ushort)(halt_q_addr + (ushort)
8558 ASC_SCSIQ_B_TAG_CODE));
8559 tag_code &= 0xDC;
8560 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
8561 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
8564 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
8565 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
8568 AscWriteLramByte(iop_base,
8569 (ushort)(halt_q_addr +
8570 (ushort)ASC_SCSIQ_B_TAG_CODE),
8571 tag_code);
8573 q_status = AscReadLramByte(iop_base,
8574 (ushort)(halt_q_addr + (ushort)
8575 ASC_SCSIQ_B_STATUS));
8576 q_status |= (QS_READY | QS_BUSY);
8577 AscWriteLramByte(iop_base,
8578 (ushort)(halt_q_addr +
8579 (ushort)ASC_SCSIQ_B_STATUS),
8580 q_status);
8582 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
8583 scsi_busy &= ~target_id;
8584 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8586 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8587 return (0);
8588 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
8590 AscMemWordCopyPtrFromLram(iop_base,
8591 ASCV_MSGOUT_BEG,
8592 (uchar *)&out_msg,
8593 sizeof(EXT_MSG) >> 1);
8595 if ((out_msg.msg_type == MS_EXTEND) &&
8596 (out_msg.msg_len == MS_SDTR_LEN) &&
8597 (out_msg.msg_req == MS_SDTR_CODE)) {
8599 asc_dvc->init_sdtr &= ~target_id;
8600 asc_dvc->sdtr_done &= ~target_id;
8601 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8602 boardp->sdtr_data[tid_no] = asyn_sdtr;
8604 q_cntl &= ~QC_MSG_OUT;
8605 AscWriteLramByte(iop_base,
8606 (ushort)(halt_q_addr +
8607 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8608 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8609 return (0);
8610 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
8612 scsi_status = AscReadLramByte(iop_base,
8613 (ushort)((ushort)halt_q_addr +
8614 (ushort)
8615 ASC_SCSIQ_SCSI_STATUS));
8616 cur_dvc_qng =
8617 AscReadLramByte(iop_base,
8618 (ushort)((ushort)ASC_QADR_BEG +
8619 (ushort)target_ix));
8620 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
8622 scsi_busy = AscReadLramByte(iop_base,
8623 (ushort)ASCV_SCSIBUSY_B);
8624 scsi_busy |= target_id;
8625 AscWriteLramByte(iop_base,
8626 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8627 asc_dvc->queue_full_or_busy |= target_id;
8629 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
8630 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
8631 cur_dvc_qng -= 1;
8632 asc_dvc->max_dvc_qng[tid_no] =
8633 cur_dvc_qng;
8635 AscWriteLramByte(iop_base,
8636 (ushort)((ushort)
8637 ASCV_MAX_DVC_QNG_BEG
8638 + (ushort)
8639 tid_no),
8640 cur_dvc_qng);
8643 * Set the device queue depth to the number of
8644 * active requests when the QUEUE FULL condition
8645 * was encountered.
8647 boardp->queue_full |= target_id;
8648 boardp->queue_full_cnt[tid_no] =
8649 cur_dvc_qng;
8653 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8654 return (0);
8656 #if CC_VERY_LONG_SG_LIST
8657 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
8658 uchar q_no;
8659 ushort q_addr;
8660 uchar sg_wk_q_no;
8661 uchar first_sg_wk_q_no;
8662 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
8663 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
8664 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
8665 ushort sg_list_dwords;
8666 ushort sg_entry_cnt;
8667 uchar next_qp;
8668 int i;
8670 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
8671 if (q_no == ASC_QLINK_END) {
8672 return (0);
8675 q_addr = ASC_QNO_TO_QADDR(q_no);
8678 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
8679 * structure pointer using a macro provided by the driver.
8680 * The ASC_SCSI_REQ pointer provides a pointer to the
8681 * host ASC_SG_HEAD structure.
8683 /* Read request's SRB pointer. */
8684 scsiq = (ASC_SCSI_Q *)
8685 ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
8686 (ushort)
8687 (q_addr +
8688 ASC_SCSIQ_D_SRBPTR))));
8691 * Get request's first and working SG queue.
8693 sg_wk_q_no = AscReadLramByte(iop_base,
8694 (ushort)(q_addr +
8695 ASC_SCSIQ_B_SG_WK_QP));
8697 first_sg_wk_q_no = AscReadLramByte(iop_base,
8698 (ushort)(q_addr +
8699 ASC_SCSIQ_B_FIRST_SG_WK_QP));
8702 * Reset request's working SG queue back to the
8703 * first SG queue.
8705 AscWriteLramByte(iop_base,
8706 (ushort)(q_addr +
8707 (ushort)ASC_SCSIQ_B_SG_WK_QP),
8708 first_sg_wk_q_no);
8710 sg_head = scsiq->sg_head;
8713 * Set sg_entry_cnt to the number of SG elements
8714 * that will be completed on this interrupt.
8716 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
8717 * SG elements. The data_cnt and data_addr fields which
8718 * add 1 to the SG element capacity are not used when
8719 * restarting SG handling after a halt.
8721 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
8722 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
8725 * Keep track of remaining number of SG elements that will
8726 * need to be handled on the next interrupt.
8728 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
8729 } else {
8730 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
8731 scsiq->remain_sg_entry_cnt = 0;
8735 * Copy SG elements into the list of allocated SG queues.
8737 * Last index completed is saved in scsiq->next_sg_index.
8739 next_qp = first_sg_wk_q_no;
8740 q_addr = ASC_QNO_TO_QADDR(next_qp);
8741 scsi_sg_q.sg_head_qp = q_no;
8742 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
8743 for (i = 0; i < sg_head->queue_cnt; i++) {
8744 scsi_sg_q.seq_no = i + 1;
8745 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
8746 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
8747 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
8749 * After very first SG queue RISC FW uses next
8750 * SG queue first element then checks sg_list_cnt
8751 * against zero and then decrements, so set
8752 * sg_list_cnt 1 less than number of SG elements
8753 * in each SG queue.
8755 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
8756 scsi_sg_q.sg_cur_list_cnt =
8757 ASC_SG_LIST_PER_Q - 1;
8758 } else {
8760 * This is the last SG queue in the list of
8761 * allocated SG queues. If there are more
8762 * SG elements than will fit in the allocated
8763 * queues, then set the QCSG_SG_XFER_MORE flag.
8765 if (scsiq->remain_sg_entry_cnt != 0) {
8766 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
8767 } else {
8768 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
8770 /* equals sg_entry_cnt * 2 */
8771 sg_list_dwords = sg_entry_cnt << 1;
8772 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
8773 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
8774 sg_entry_cnt = 0;
8777 scsi_sg_q.q_no = next_qp;
8778 AscMemWordCopyPtrToLram(iop_base,
8779 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
8780 (uchar *)&scsi_sg_q,
8781 sizeof(ASC_SG_LIST_Q) >> 1);
8783 AscMemDWordCopyPtrToLram(iop_base,
8784 q_addr + ASC_SGQ_LIST_BEG,
8785 (uchar *)&sg_head->
8786 sg_list[scsiq->next_sg_index],
8787 sg_list_dwords);
8789 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
8792 * If the just completed SG queue contained the
8793 * last SG element, then no more SG queues need
8794 * to be written.
8796 if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
8797 break;
8800 next_qp = AscReadLramByte(iop_base,
8801 (ushort)(q_addr +
8802 ASC_SCSIQ_B_FWD));
8803 q_addr = ASC_QNO_TO_QADDR(next_qp);
8807 * Clear the halt condition so the RISC will be restarted
8808 * after the return.
8810 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8811 return (0);
8813 #endif /* CC_VERY_LONG_SG_LIST */
8814 return (0);
8817 static uchar
8818 _AscCopyLramScsiDoneQ(PortAddr iop_base,
8819 ushort q_addr,
8820 ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
8822 ushort _val;
8823 uchar sg_queue_cnt;
8825 DvcGetQinfo(iop_base,
8826 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
8827 (uchar *)scsiq,
8828 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
8830 _val = AscReadLramWord(iop_base,
8831 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
8832 scsiq->q_status = (uchar)_val;
8833 scsiq->q_no = (uchar)(_val >> 8);
8834 _val = AscReadLramWord(iop_base,
8835 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8836 scsiq->cntl = (uchar)_val;
8837 sg_queue_cnt = (uchar)(_val >> 8);
8838 _val = AscReadLramWord(iop_base,
8839 (ushort)(q_addr +
8840 (ushort)ASC_SCSIQ_B_SENSE_LEN));
8841 scsiq->sense_len = (uchar)_val;
8842 scsiq->extra_bytes = (uchar)(_val >> 8);
8845 * Read high word of remain bytes from alternate location.
8847 scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
8848 (ushort)(q_addr +
8849 (ushort)
8850 ASC_SCSIQ_W_ALT_DC1)))
8851 << 16);
8853 * Read low word of remain bytes from original location.
8855 scsiq->remain_bytes += AscReadLramWord(iop_base,
8856 (ushort)(q_addr + (ushort)
8857 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
8859 scsiq->remain_bytes &= max_dma_count;
8860 return (sg_queue_cnt);
8863 static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
8865 uchar next_qp;
8866 uchar n_q_used;
8867 uchar sg_list_qp;
8868 uchar sg_queue_cnt;
8869 uchar q_cnt;
8870 uchar done_q_tail;
8871 uchar tid_no;
8872 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8873 ASC_SCSI_BIT_ID_TYPE target_id;
8874 PortAddr iop_base;
8875 ushort q_addr;
8876 ushort sg_q_addr;
8877 uchar cur_target_qng;
8878 ASC_QDONE_INFO scsiq_buf;
8879 ASC_QDONE_INFO *scsiq;
8880 int false_overrun;
8881 ASC_ISR_CALLBACK asc_isr_callback;
8883 iop_base = asc_dvc->iop_base;
8884 asc_isr_callback = asc_dvc->isr_callback;
8885 n_q_used = 1;
8886 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
8887 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
8888 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
8889 next_qp = AscReadLramByte(iop_base,
8890 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
8891 if (next_qp != ASC_QLINK_END) {
8892 AscPutVarDoneQTail(iop_base, next_qp);
8893 q_addr = ASC_QNO_TO_QADDR(next_qp);
8894 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
8895 asc_dvc->max_dma_count);
8896 AscWriteLramByte(iop_base,
8897 (ushort)(q_addr +
8898 (ushort)ASC_SCSIQ_B_STATUS),
8899 (uchar)(scsiq->
8900 q_status & (uchar)~(QS_READY |
8901 QS_ABORTED)));
8902 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
8903 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
8904 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
8905 sg_q_addr = q_addr;
8906 sg_list_qp = next_qp;
8907 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
8908 sg_list_qp = AscReadLramByte(iop_base,
8909 (ushort)(sg_q_addr
8910 + (ushort)
8911 ASC_SCSIQ_B_FWD));
8912 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
8913 if (sg_list_qp == ASC_QLINK_END) {
8914 AscSetLibErrorCode(asc_dvc,
8915 ASCQ_ERR_SG_Q_LINKS);
8916 scsiq->d3.done_stat = QD_WITH_ERROR;
8917 scsiq->d3.host_stat =
8918 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
8919 goto FATAL_ERR_QDONE;
8921 AscWriteLramByte(iop_base,
8922 (ushort)(sg_q_addr + (ushort)
8923 ASC_SCSIQ_B_STATUS),
8924 QS_FREE);
8926 n_q_used = sg_queue_cnt + 1;
8927 AscPutVarDoneQTail(iop_base, sg_list_qp);
8929 if (asc_dvc->queue_full_or_busy & target_id) {
8930 cur_target_qng = AscReadLramByte(iop_base,
8931 (ushort)((ushort)
8932 ASC_QADR_BEG
8933 + (ushort)
8934 scsiq->d2.
8935 target_ix));
8936 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
8937 scsi_busy = AscReadLramByte(iop_base, (ushort)
8938 ASCV_SCSIBUSY_B);
8939 scsi_busy &= ~target_id;
8940 AscWriteLramByte(iop_base,
8941 (ushort)ASCV_SCSIBUSY_B,
8942 scsi_busy);
8943 asc_dvc->queue_full_or_busy &= ~target_id;
8946 if (asc_dvc->cur_total_qng >= n_q_used) {
8947 asc_dvc->cur_total_qng -= n_q_used;
8948 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
8949 asc_dvc->cur_dvc_qng[tid_no]--;
8951 } else {
8952 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
8953 scsiq->d3.done_stat = QD_WITH_ERROR;
8954 goto FATAL_ERR_QDONE;
8956 if ((scsiq->d2.srb_ptr == 0UL) ||
8957 ((scsiq->q_status & QS_ABORTED) != 0)) {
8958 return (0x11);
8959 } else if (scsiq->q_status == QS_DONE) {
8960 false_overrun = FALSE;
8961 if (scsiq->extra_bytes != 0) {
8962 scsiq->remain_bytes +=
8963 (ADV_DCNT)scsiq->extra_bytes;
8965 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
8966 if (scsiq->d3.host_stat ==
8967 QHSTA_M_DATA_OVER_RUN) {
8968 if ((scsiq->
8969 cntl & (QC_DATA_IN | QC_DATA_OUT))
8970 == 0) {
8971 scsiq->d3.done_stat =
8972 QD_NO_ERROR;
8973 scsiq->d3.host_stat =
8974 QHSTA_NO_ERROR;
8975 } else if (false_overrun) {
8976 scsiq->d3.done_stat =
8977 QD_NO_ERROR;
8978 scsiq->d3.host_stat =
8979 QHSTA_NO_ERROR;
8981 } else if (scsiq->d3.host_stat ==
8982 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
8983 AscStopChip(iop_base);
8984 AscSetChipControl(iop_base,
8985 (uchar)(CC_SCSI_RESET
8986 | CC_HALT));
8987 DvcDelayNanoSecond(asc_dvc, 60000);
8988 AscSetChipControl(iop_base, CC_HALT);
8989 AscSetChipStatus(iop_base,
8990 CIW_CLR_SCSI_RESET_INT);
8991 AscSetChipStatus(iop_base, 0);
8992 AscSetChipControl(iop_base, 0);
8995 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
8996 (*asc_isr_callback) (asc_dvc, scsiq);
8997 } else {
8998 if ((AscReadLramByte(iop_base,
8999 (ushort)(q_addr + (ushort)
9000 ASC_SCSIQ_CDB_BEG))
9001 == START_STOP)) {
9002 asc_dvc->unit_not_ready &= ~target_id;
9003 if (scsiq->d3.done_stat != QD_NO_ERROR) {
9004 asc_dvc->start_motor &=
9005 ~target_id;
9009 return (1);
9010 } else {
9011 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
9012 FATAL_ERR_QDONE:
9013 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
9014 (*asc_isr_callback) (asc_dvc, scsiq);
9016 return (0x80);
9019 return (0);
9022 static int AscISR(ASC_DVC_VAR *asc_dvc)
9024 ASC_CS_TYPE chipstat;
9025 PortAddr iop_base;
9026 ushort saved_ram_addr;
9027 uchar ctrl_reg;
9028 uchar saved_ctrl_reg;
9029 int int_pending;
9030 int status;
9031 uchar host_flag;
9033 iop_base = asc_dvc->iop_base;
9034 int_pending = FALSE;
9036 if (AscIsIntPending(iop_base) == 0) {
9037 return int_pending;
9040 if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
9041 || (asc_dvc->isr_callback == 0)
9043 return (ERR);
9045 if (asc_dvc->in_critical_cnt != 0) {
9046 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
9047 return (ERR);
9049 if (asc_dvc->is_in_int) {
9050 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
9051 return (ERR);
9053 asc_dvc->is_in_int = TRUE;
9054 ctrl_reg = AscGetChipControl(iop_base);
9055 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
9056 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
9057 chipstat = AscGetChipStatus(iop_base);
9058 if (chipstat & CSW_SCSI_RESET_LATCH) {
9059 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
9060 int i = 10;
9061 int_pending = TRUE;
9062 asc_dvc->sdtr_done = 0;
9063 saved_ctrl_reg &= (uchar)(~CC_HALT);
9064 while ((AscGetChipStatus(iop_base) &
9065 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
9066 DvcSleepMilliSecond(100);
9068 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
9069 AscSetChipControl(iop_base, CC_HALT);
9070 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
9071 AscSetChipStatus(iop_base, 0);
9072 chipstat = AscGetChipStatus(iop_base);
9075 saved_ram_addr = AscGetChipLramAddr(iop_base);
9076 host_flag = AscReadLramByte(iop_base,
9077 ASCV_HOST_FLAG_B) &
9078 (uchar)(~ASC_HOST_FLAG_IN_ISR);
9079 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
9080 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
9081 if ((chipstat & CSW_INT_PENDING)
9082 || (int_pending)
9084 AscAckInterrupt(iop_base);
9085 int_pending = TRUE;
9086 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
9087 if (AscIsrChipHalted(asc_dvc) == ERR) {
9088 goto ISR_REPORT_QDONE_FATAL_ERROR;
9089 } else {
9090 saved_ctrl_reg &= (uchar)(~CC_HALT);
9092 } else {
9093 ISR_REPORT_QDONE_FATAL_ERROR:
9094 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
9095 while (((status =
9096 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
9098 } else {
9099 do {
9100 if ((status =
9101 AscIsrQDone(asc_dvc)) == 1) {
9102 break;
9104 } while (status == 0x11);
9106 if ((status & 0x80) != 0)
9107 int_pending = ERR;
9110 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
9111 AscSetChipLramAddr(iop_base, saved_ram_addr);
9112 AscSetChipControl(iop_base, saved_ctrl_reg);
9113 asc_dvc->is_in_int = FALSE;
9114 return (int_pending);
9117 /* Microcode buffer is kept after initialization for error recovery. */
9118 static uchar _asc_mcode_buf[] = {
9119 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9120 0x00, 0x00, 0x00, 0x00,
9121 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00,
9122 0x00, 0x00, 0x00, 0x00,
9123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9124 0x00, 0x00, 0x00, 0x00,
9125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9126 0x00, 0x00, 0x00, 0x00,
9127 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00,
9128 0x00, 0xFF, 0x00, 0x00,
9129 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00,
9130 0x00, 0x00, 0x00, 0x00,
9131 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
9132 0x00, 0x00, 0x00, 0x00,
9133 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88,
9134 0x00, 0x00, 0x00, 0x00,
9135 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73,
9136 0x03, 0x23, 0x36, 0x40,
9137 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
9138 0xC2, 0x00, 0x92, 0x80,
9139 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60,
9140 0xB6, 0x00, 0x92, 0x80,
9141 0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00,
9142 0x92, 0x80, 0x80, 0x62,
9143 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
9144 0xCD, 0x04, 0x4D, 0x00,
9145 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01,
9146 0xE6, 0x84, 0xD2, 0xC1,
9147 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97,
9148 0xC6, 0x81, 0xC2, 0x88,
9149 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
9150 0x84, 0x97, 0x07, 0xA6,
9151 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE,
9152 0xC2, 0x88, 0xCE, 0x00,
9153 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01,
9154 0x80, 0x63, 0x07, 0xA6,
9155 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
9156 0x34, 0x01, 0x00, 0x33,
9157 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23,
9158 0x68, 0x98, 0x4D, 0x04,
9159 0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23,
9160 0xF8, 0x88, 0xFB, 0x23,
9161 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
9162 0x00, 0x33, 0x0A, 0x00,
9163 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00,
9164 0xC2, 0x88, 0xCD, 0x04,
9165 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81,
9166 0x06, 0xAB, 0x82, 0x01,
9167 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
9168 0x3C, 0x01, 0x00, 0x05,
9169 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01,
9170 0x15, 0x23, 0xA1, 0x01,
9171 0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00,
9172 0x06, 0x61, 0x00, 0xA0,
9173 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
9174 0xC2, 0x88, 0x06, 0x23,
9175 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01,
9176 0x57, 0x60, 0x00, 0xA0,
9177 0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73,
9178 0x4B, 0x00, 0x06, 0x61,
9179 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
9180 0x4F, 0x00, 0x84, 0x97,
9181 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97,
9182 0x48, 0x04, 0x84, 0x80,
9183 0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00,
9184 0x81, 0x73, 0x06, 0x29,
9185 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
9186 0x04, 0x98, 0xF0, 0x80,
9187 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6,
9188 0x34, 0x02, 0x03, 0xA6,
9189 0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96,
9190 0x46, 0x82, 0xFE, 0x95,
9191 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
9192 0x07, 0xA6, 0x5A, 0x02,
9193 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95,
9194 0x48, 0x82, 0x60, 0x96,
9195 0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84,
9196 0x04, 0x01, 0x0C, 0xDC,
9197 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
9198 0x6F, 0x00, 0xA5, 0x01,
9199 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01,
9200 0x02, 0xA6, 0xAA, 0x02,
9201 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04,
9202 0x01, 0xA6, 0xB4, 0x02,
9203 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
9204 0x80, 0x63, 0x00, 0x43,
9205 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23,
9206 0x04, 0x61, 0x84, 0x01,
9207 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F,
9208 0x00, 0x00, 0xEA, 0x82,
9209 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
9210 0x00, 0x33, 0x1F, 0x00,
9211 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98,
9212 0xB6, 0x2D, 0x01, 0xA6,
9213 0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6,
9214 0x10, 0x03, 0x03, 0xA6,
9215 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
9216 0x7C, 0x95, 0xEE, 0x82,
9217 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4,
9218 0x04, 0x01, 0x2D, 0xC8,
9219 0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01,
9220 0x05, 0x05, 0x86, 0x98,
9221 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
9222 0x3C, 0x04, 0x06, 0xA6,
9223 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88,
9224 0x7C, 0x95, 0x32, 0x83,
9225 0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05,
9226 0xEB, 0x04, 0x00, 0x33,
9227 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
9228 0xFF, 0xA2, 0x7A, 0x03,
9229 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01,
9230 0x00, 0xA2, 0x9A, 0x03,
9231 0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00,
9232 0x01, 0xA6, 0x96, 0x03,
9233 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
9234 0xA4, 0x03, 0x00, 0xA6,
9235 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03,
9236 0x07, 0xA6, 0xB2, 0x03,
9237 0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88,
9238 0xA8, 0x98, 0x80, 0x42,
9239 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
9240 0xC0, 0x83, 0x00, 0x33,
9241 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23,
9242 0xA0, 0x01, 0x12, 0x23,
9243 0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B,
9244 0x80, 0x67, 0x05, 0x23,
9245 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
9246 0x06, 0xA6, 0x0A, 0x04,
9247 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96,
9248 0xF4, 0x83, 0x20, 0x84,
9249 0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
9250 0x83, 0x03, 0x80, 0x63,
9251 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
9252 0x38, 0x04, 0x00, 0x33,
9253 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84,
9254 0x1D, 0x01, 0x06, 0xCC,
9255 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62,
9256 0xA2, 0x0D, 0x80, 0x63,
9257 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
9258 0x80, 0x63, 0xA3, 0x01,
9259 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0,
9260 0x76, 0x04, 0xE0, 0x00,
9261 0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00,
9262 0x00, 0x33, 0x1E, 0x00,
9263 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
9264 0x08, 0x23, 0x22, 0xA3,
9265 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3,
9266 0xC4, 0x04, 0x42, 0x23,
9267 0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23,
9268 0xF8, 0x88, 0x04, 0x98,
9269 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
9270 0x81, 0x62, 0xE8, 0x81,
9271 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98,
9272 0x00, 0x33, 0x00, 0x81,
9273 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23,
9274 0xF8, 0x88, 0x04, 0x23,
9275 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
9276 0xF4, 0x04, 0x00, 0x33,
9277 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01,
9278 0x04, 0x23, 0xA0, 0x01,
9279 0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00,
9280 0x00, 0xA3, 0x22, 0x05,
9281 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
9282 0x46, 0x97, 0xCD, 0x04,
9283 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23,
9284 0x82, 0x01, 0x34, 0x85,
9285 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05,
9286 0x1D, 0x01, 0x04, 0xD6,
9287 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
9288 0x49, 0x00, 0x81, 0x01,
9289 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01,
9290 0x49, 0x04, 0x80, 0x01,
9291 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04,
9292 0x01, 0x23, 0xEA, 0x00,
9293 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
9294 0x07, 0xA4, 0xF8, 0x05,
9295 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00,
9296 0xC2, 0x88, 0x04, 0xA0,
9297 0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61,
9298 0x00, 0xA2, 0xA4, 0x05,
9299 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
9300 0x62, 0x97, 0x04, 0x85,
9301 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05,
9302 0xF4, 0x85, 0x03, 0xA0,
9303 0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63,
9304 0xCC, 0x86, 0x07, 0xA0,
9305 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
9306 0x80, 0x67, 0x80, 0x63,
9307 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23,
9308 0xF8, 0x88, 0x07, 0x23,
9309 0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00,
9310 0x00, 0x63, 0x4A, 0x00,
9311 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
9312 0x07, 0x41, 0x83, 0x03,
9313 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88,
9314 0x1D, 0x01, 0x01, 0xD6,
9315 0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00,
9316 0x07, 0xA6, 0x7C, 0x05,
9317 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
9318 0x52, 0x00, 0x06, 0x61,
9319 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41,
9320 0x00, 0x63, 0x1D, 0x01,
9321 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23,
9322 0x07, 0x41, 0x00, 0x63,
9323 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
9324 0xDF, 0x00, 0x06, 0xA6,
9325 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33,
9326 0x00, 0x40, 0xC0, 0x20,
9327 0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63,
9328 0x06, 0xA6, 0x94, 0x06,
9329 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
9330 0x40, 0x0E, 0x80, 0x63,
9331 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E,
9332 0x80, 0x63, 0x00, 0x43,
9333 0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05,
9334 0x80, 0x67, 0x40, 0x0E,
9335 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
9336 0x07, 0xA6, 0xD6, 0x06,
9337 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00,
9338 0x0A, 0x2B, 0x07, 0xA6,
9339 0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2,
9340 0xF4, 0x06, 0xC0, 0x0E,
9341 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
9342 0x81, 0x62, 0x04, 0x01,
9343 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6,
9344 0x8C, 0x06, 0x00, 0x33,
9345 0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03,
9346 0x80, 0x63, 0x06, 0xA6,
9347 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
9348 0x00, 0x00, 0x80, 0x67,
9349 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05,
9350 0xBF, 0x23, 0x04, 0x61,
9351 0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00,
9352 0x00, 0x01, 0xF2, 0x00,
9353 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
9354 0x80, 0x05, 0x81, 0x05,
9355 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00,
9356 0x70, 0x00, 0x81, 0x01,
9357 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04,
9358 0x70, 0x00, 0x80, 0x01,
9359 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
9360 0xF1, 0x00, 0x70, 0x00,
9361 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01,
9362 0x71, 0x04, 0x70, 0x00,
9363 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05,
9364 0xA3, 0x01, 0xA2, 0x01,
9365 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
9366 0xC4, 0x07, 0x00, 0x33,
9367 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8,
9368 0x48, 0x00, 0xB0, 0x01,
9369 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43,
9370 0x00, 0xA2, 0xE4, 0x07,
9371 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
9372 0x05, 0x05, 0x00, 0x63,
9373 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43,
9374 0x76, 0x08, 0x80, 0x02,
9375 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
9376 0x00, 0x02, 0x00, 0xA0,
9377 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
9378 0x00, 0x63, 0xF3, 0x04,
9379 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40,
9380 0x00, 0xA2, 0x44, 0x08,
9381 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1,
9382 0x24, 0x08, 0x04, 0x98,
9383 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
9384 0x5A, 0x88, 0x02, 0x01,
9385 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00,
9386 0x00, 0xA3, 0x64, 0x08,
9387 0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63,
9388 0x06, 0xA6, 0x76, 0x08,
9389 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
9390 0x00, 0x63, 0x38, 0x2B,
9391 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98,
9392 0x05, 0x05, 0xB2, 0x09,
9393 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63,
9394 0x80, 0x32, 0x80, 0x36,
9395 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
9396 0x40, 0x36, 0x40, 0x3A,
9397 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08,
9398 0x5D, 0x00, 0xFE, 0xC3,
9399 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73,
9400 0xFF, 0xFD, 0x80, 0x73,
9401 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
9402 0xA1, 0x23, 0xA1, 0x01,
9403 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2,
9404 0x80, 0x00, 0x03, 0xC2,
9405 0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23,
9406 0xA0, 0x01, 0xE6, 0x84,
9409 static ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
9410 static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
9412 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
9413 static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
9414 INQUIRY,
9415 REQUEST_SENSE,
9416 READ_CAPACITY,
9417 READ_TOC,
9418 MODE_SELECT,
9419 MODE_SENSE,
9420 MODE_SELECT_10,
9421 MODE_SENSE_10,
9422 0xFF,
9423 0xFF,
9424 0xFF,
9425 0xFF,
9426 0xFF,
9427 0xFF,
9428 0xFF,
9429 0xFF
9432 static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
9434 PortAddr iop_base;
9435 ulong last_int_level;
9436 int sta;
9437 int n_q_required;
9438 int disable_syn_offset_one_fix;
9439 int i;
9440 ASC_PADDR addr;
9441 ASC_EXE_CALLBACK asc_exe_callback;
9442 ushort sg_entry_cnt = 0;
9443 ushort sg_entry_cnt_minus_one = 0;
9444 uchar target_ix;
9445 uchar tid_no;
9446 uchar sdtr_data;
9447 uchar extra_bytes;
9448 uchar scsi_cmd;
9449 uchar disable_cmd;
9450 ASC_SG_HEAD *sg_head;
9451 ASC_DCNT data_cnt;
9453 iop_base = asc_dvc->iop_base;
9454 sg_head = scsiq->sg_head;
9455 asc_exe_callback = asc_dvc->exe_callback;
9456 if (asc_dvc->err_code != 0)
9457 return (ERR);
9458 if (scsiq == (ASC_SCSI_Q *)0L) {
9459 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
9460 return (ERR);
9462 scsiq->q1.q_no = 0;
9463 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
9464 scsiq->q1.extra_bytes = 0;
9466 sta = 0;
9467 target_ix = scsiq->q2.target_ix;
9468 tid_no = ASC_TIX_TO_TID(target_ix);
9469 n_q_required = 1;
9470 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
9471 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
9472 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
9473 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9474 AscMsgOutSDTR(asc_dvc,
9475 asc_dvc->
9476 sdtr_period_tbl[(sdtr_data >> 4) &
9477 (uchar)(asc_dvc->
9478 max_sdtr_index -
9479 1)],
9480 (uchar)(sdtr_data & (uchar)
9481 ASC_SYN_MAX_OFFSET));
9482 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
9485 last_int_level = DvcEnterCritical();
9486 if (asc_dvc->in_critical_cnt != 0) {
9487 DvcLeaveCritical(last_int_level);
9488 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
9489 return (ERR);
9491 asc_dvc->in_critical_cnt++;
9492 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9493 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
9494 asc_dvc->in_critical_cnt--;
9495 DvcLeaveCritical(last_int_level);
9496 return (ERR);
9498 #if !CC_VERY_LONG_SG_LIST
9499 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9500 asc_dvc->in_critical_cnt--;
9501 DvcLeaveCritical(last_int_level);
9502 return (ERR);
9504 #endif /* !CC_VERY_LONG_SG_LIST */
9505 if (sg_entry_cnt == 1) {
9506 scsiq->q1.data_addr =
9507 (ADV_PADDR)sg_head->sg_list[0].addr;
9508 scsiq->q1.data_cnt =
9509 (ADV_DCNT)sg_head->sg_list[0].bytes;
9510 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
9512 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
9514 scsi_cmd = scsiq->cdbptr[0];
9515 disable_syn_offset_one_fix = FALSE;
9516 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
9517 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
9518 if (scsiq->q1.cntl & QC_SG_HEAD) {
9519 data_cnt = 0;
9520 for (i = 0; i < sg_entry_cnt; i++) {
9521 data_cnt +=
9522 (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
9523 bytes);
9525 } else {
9526 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
9528 if (data_cnt != 0UL) {
9529 if (data_cnt < 512UL) {
9530 disable_syn_offset_one_fix = TRUE;
9531 } else {
9532 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
9533 i++) {
9534 disable_cmd =
9535 _syn_offset_one_disable_cmd[i];
9536 if (disable_cmd == 0xFF) {
9537 break;
9539 if (scsi_cmd == disable_cmd) {
9540 disable_syn_offset_one_fix =
9541 TRUE;
9542 break;
9548 if (disable_syn_offset_one_fix) {
9549 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9550 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
9551 ASC_TAG_FLAG_DISABLE_DISCONNECT);
9552 } else {
9553 scsiq->q2.tag_code &= 0x27;
9555 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9556 if (asc_dvc->bug_fix_cntl) {
9557 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9558 if ((scsi_cmd == READ_6) ||
9559 (scsi_cmd == READ_10)) {
9560 addr =
9561 (ADV_PADDR)le32_to_cpu(sg_head->
9562 sg_list
9563 [sg_entry_cnt_minus_one].
9564 addr) +
9565 (ADV_DCNT)le32_to_cpu(sg_head->
9566 sg_list
9567 [sg_entry_cnt_minus_one].
9568 bytes);
9569 extra_bytes =
9570 (uchar)((ushort)addr & 0x0003);
9571 if ((extra_bytes != 0)
9573 ((scsiq->q2.
9574 tag_code &
9575 ASC_TAG_FLAG_EXTRA_BYTES)
9576 == 0)) {
9577 scsiq->q2.tag_code |=
9578 ASC_TAG_FLAG_EXTRA_BYTES;
9579 scsiq->q1.extra_bytes =
9580 extra_bytes;
9581 data_cnt =
9582 le32_to_cpu(sg_head->
9583 sg_list
9584 [sg_entry_cnt_minus_one].
9585 bytes);
9586 data_cnt -=
9587 (ASC_DCNT) extra_bytes;
9588 sg_head->
9589 sg_list
9590 [sg_entry_cnt_minus_one].
9591 bytes =
9592 cpu_to_le32(data_cnt);
9597 sg_head->entry_to_copy = sg_head->entry_cnt;
9598 #if CC_VERY_LONG_SG_LIST
9600 * Set the sg_entry_cnt to the maximum possible. The rest of
9601 * the SG elements will be copied when the RISC completes the
9602 * SG elements that fit and halts.
9604 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9605 sg_entry_cnt = ASC_MAX_SG_LIST;
9607 #endif /* CC_VERY_LONG_SG_LIST */
9608 n_q_required = AscSgListToQueue(sg_entry_cnt);
9609 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
9610 (uint) n_q_required)
9611 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9612 if ((sta =
9613 AscSendScsiQueue(asc_dvc, scsiq,
9614 n_q_required)) == 1) {
9615 asc_dvc->in_critical_cnt--;
9616 if (asc_exe_callback != 0) {
9617 (*asc_exe_callback) (asc_dvc, scsiq);
9619 DvcLeaveCritical(last_int_level);
9620 return (sta);
9623 } else {
9624 if (asc_dvc->bug_fix_cntl) {
9625 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9626 if ((scsi_cmd == READ_6) ||
9627 (scsi_cmd == READ_10)) {
9628 addr =
9629 le32_to_cpu(scsiq->q1.data_addr) +
9630 le32_to_cpu(scsiq->q1.data_cnt);
9631 extra_bytes =
9632 (uchar)((ushort)addr & 0x0003);
9633 if ((extra_bytes != 0)
9635 ((scsiq->q2.
9636 tag_code &
9637 ASC_TAG_FLAG_EXTRA_BYTES)
9638 == 0)) {
9639 data_cnt =
9640 le32_to_cpu(scsiq->q1.
9641 data_cnt);
9642 if (((ushort)data_cnt & 0x01FF)
9643 == 0) {
9644 scsiq->q2.tag_code |=
9645 ASC_TAG_FLAG_EXTRA_BYTES;
9646 data_cnt -= (ASC_DCNT)
9647 extra_bytes;
9648 scsiq->q1.data_cnt =
9649 cpu_to_le32
9650 (data_cnt);
9651 scsiq->q1.extra_bytes =
9652 extra_bytes;
9658 n_q_required = 1;
9659 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
9660 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9661 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
9662 n_q_required)) == 1) {
9663 asc_dvc->in_critical_cnt--;
9664 if (asc_exe_callback != 0) {
9665 (*asc_exe_callback) (asc_dvc, scsiq);
9667 DvcLeaveCritical(last_int_level);
9668 return (sta);
9672 asc_dvc->in_critical_cnt--;
9673 DvcLeaveCritical(last_int_level);
9674 return (sta);
9677 static int
9678 AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
9680 PortAddr iop_base;
9681 uchar free_q_head;
9682 uchar next_qp;
9683 uchar tid_no;
9684 uchar target_ix;
9685 int sta;
9687 iop_base = asc_dvc->iop_base;
9688 target_ix = scsiq->q2.target_ix;
9689 tid_no = ASC_TIX_TO_TID(target_ix);
9690 sta = 0;
9691 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
9692 if (n_q_required > 1) {
9693 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
9694 free_q_head, (uchar)
9695 (n_q_required)))
9696 != (uchar)ASC_QLINK_END) {
9697 asc_dvc->last_q_shortage = 0;
9698 scsiq->sg_head->queue_cnt = n_q_required - 1;
9699 scsiq->q1.q_no = free_q_head;
9700 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
9701 free_q_head)) == 1) {
9702 AscPutVarFreeQHead(iop_base, next_qp);
9703 asc_dvc->cur_total_qng += (uchar)(n_q_required);
9704 asc_dvc->cur_dvc_qng[tid_no]++;
9706 return (sta);
9708 } else if (n_q_required == 1) {
9709 if ((next_qp = AscAllocFreeQueue(iop_base,
9710 free_q_head)) !=
9711 ASC_QLINK_END) {
9712 scsiq->q1.q_no = free_q_head;
9713 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
9714 free_q_head)) == 1) {
9715 AscPutVarFreeQHead(iop_base, next_qp);
9716 asc_dvc->cur_total_qng++;
9717 asc_dvc->cur_dvc_qng[tid_no]++;
9719 return (sta);
9722 return (sta);
9725 static int AscSgListToQueue(int sg_list)
9727 int n_sg_list_qs;
9729 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
9730 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
9731 n_sg_list_qs++;
9732 return (n_sg_list_qs + 1);
9735 static uint
9736 AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
9738 uint cur_used_qs;
9739 uint cur_free_qs;
9740 ASC_SCSI_BIT_ID_TYPE target_id;
9741 uchar tid_no;
9743 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
9744 tid_no = ASC_TIX_TO_TID(target_ix);
9745 if ((asc_dvc->unit_not_ready & target_id) ||
9746 (asc_dvc->queue_full_or_busy & target_id)) {
9747 return (0);
9749 if (n_qs == 1) {
9750 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9751 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
9752 } else {
9753 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9754 (uint) ASC_MIN_FREE_Q;
9756 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
9757 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
9758 if (asc_dvc->cur_dvc_qng[tid_no] >=
9759 asc_dvc->max_dvc_qng[tid_no]) {
9760 return (0);
9762 return (cur_free_qs);
9764 if (n_qs > 1) {
9765 if ((n_qs > asc_dvc->last_q_shortage)
9766 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
9767 asc_dvc->last_q_shortage = n_qs;
9770 return (0);
9773 static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
9775 ushort q_addr;
9776 uchar tid_no;
9777 uchar sdtr_data;
9778 uchar syn_period_ix;
9779 uchar syn_offset;
9780 PortAddr iop_base;
9782 iop_base = asc_dvc->iop_base;
9783 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
9784 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
9785 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
9786 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9787 syn_period_ix =
9788 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
9789 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
9790 AscMsgOutSDTR(asc_dvc,
9791 asc_dvc->sdtr_period_tbl[syn_period_ix],
9792 syn_offset);
9793 scsiq->q1.cntl |= QC_MSG_OUT;
9795 q_addr = ASC_QNO_TO_QADDR(q_no);
9796 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
9797 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9799 scsiq->q1.status = QS_FREE;
9800 AscMemWordCopyPtrToLram(iop_base,
9801 q_addr + ASC_SCSIQ_CDB_BEG,
9802 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
9804 DvcPutScsiQ(iop_base,
9805 q_addr + ASC_SCSIQ_CPY_BEG,
9806 (uchar *)&scsiq->q1.cntl,
9807 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
9808 AscWriteLramWord(iop_base,
9809 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
9810 (ushort)(((ushort)scsiq->q1.
9811 q_no << 8) | (ushort)QS_READY));
9812 return (1);
9815 static int
9816 AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
9818 int sta;
9819 int i;
9820 ASC_SG_HEAD *sg_head;
9821 ASC_SG_LIST_Q scsi_sg_q;
9822 ASC_DCNT saved_data_addr;
9823 ASC_DCNT saved_data_cnt;
9824 PortAddr iop_base;
9825 ushort sg_list_dwords;
9826 ushort sg_index;
9827 ushort sg_entry_cnt;
9828 ushort q_addr;
9829 uchar next_qp;
9831 iop_base = asc_dvc->iop_base;
9832 sg_head = scsiq->sg_head;
9833 saved_data_addr = scsiq->q1.data_addr;
9834 saved_data_cnt = scsiq->q1.data_cnt;
9835 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
9836 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
9837 #if CC_VERY_LONG_SG_LIST
9839 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
9840 * then not all SG elements will fit in the allocated queues.
9841 * The rest of the SG elements will be copied when the RISC
9842 * completes the SG elements that fit and halts.
9844 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9846 * Set sg_entry_cnt to be the number of SG elements that
9847 * will fit in the allocated SG queues. It is minus 1, because
9848 * the first SG element is handled above. ASC_MAX_SG_LIST is
9849 * already inflated by 1 to account for this. For example it
9850 * may be 50 which is 1 + 7 queues * 7 SG elements.
9852 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
9855 * Keep track of remaining number of SG elements that will
9856 * need to be handled from a_isr.c.
9858 scsiq->remain_sg_entry_cnt =
9859 sg_head->entry_cnt - ASC_MAX_SG_LIST;
9860 } else {
9861 #endif /* CC_VERY_LONG_SG_LIST */
9863 * Set sg_entry_cnt to be the number of SG elements that
9864 * will fit in the allocated SG queues. It is minus 1, because
9865 * the first SG element is handled above.
9867 sg_entry_cnt = sg_head->entry_cnt - 1;
9868 #if CC_VERY_LONG_SG_LIST
9870 #endif /* CC_VERY_LONG_SG_LIST */
9871 if (sg_entry_cnt != 0) {
9872 scsiq->q1.cntl |= QC_SG_HEAD;
9873 q_addr = ASC_QNO_TO_QADDR(q_no);
9874 sg_index = 1;
9875 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
9876 scsi_sg_q.sg_head_qp = q_no;
9877 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
9878 for (i = 0; i < sg_head->queue_cnt; i++) {
9879 scsi_sg_q.seq_no = i + 1;
9880 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
9881 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
9882 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
9883 if (i == 0) {
9884 scsi_sg_q.sg_list_cnt =
9885 ASC_SG_LIST_PER_Q;
9886 scsi_sg_q.sg_cur_list_cnt =
9887 ASC_SG_LIST_PER_Q;
9888 } else {
9889 scsi_sg_q.sg_list_cnt =
9890 ASC_SG_LIST_PER_Q - 1;
9891 scsi_sg_q.sg_cur_list_cnt =
9892 ASC_SG_LIST_PER_Q - 1;
9894 } else {
9895 #if CC_VERY_LONG_SG_LIST
9897 * This is the last SG queue in the list of
9898 * allocated SG queues. If there are more
9899 * SG elements than will fit in the allocated
9900 * queues, then set the QCSG_SG_XFER_MORE flag.
9902 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9903 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
9904 } else {
9905 #endif /* CC_VERY_LONG_SG_LIST */
9906 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
9907 #if CC_VERY_LONG_SG_LIST
9909 #endif /* CC_VERY_LONG_SG_LIST */
9910 sg_list_dwords = sg_entry_cnt << 1;
9911 if (i == 0) {
9912 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
9913 scsi_sg_q.sg_cur_list_cnt =
9914 sg_entry_cnt;
9915 } else {
9916 scsi_sg_q.sg_list_cnt =
9917 sg_entry_cnt - 1;
9918 scsi_sg_q.sg_cur_list_cnt =
9919 sg_entry_cnt - 1;
9921 sg_entry_cnt = 0;
9923 next_qp = AscReadLramByte(iop_base,
9924 (ushort)(q_addr +
9925 ASC_SCSIQ_B_FWD));
9926 scsi_sg_q.q_no = next_qp;
9927 q_addr = ASC_QNO_TO_QADDR(next_qp);
9928 AscMemWordCopyPtrToLram(iop_base,
9929 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
9930 (uchar *)&scsi_sg_q,
9931 sizeof(ASC_SG_LIST_Q) >> 1);
9932 AscMemDWordCopyPtrToLram(iop_base,
9933 q_addr + ASC_SGQ_LIST_BEG,
9934 (uchar *)&sg_head->
9935 sg_list[sg_index],
9936 sg_list_dwords);
9937 sg_index += ASC_SG_LIST_PER_Q;
9938 scsiq->next_sg_index = sg_index;
9940 } else {
9941 scsiq->q1.cntl &= ~QC_SG_HEAD;
9943 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
9944 scsiq->q1.data_addr = saved_data_addr;
9945 scsiq->q1.data_cnt = saved_data_cnt;
9946 return (sta);
9949 static int
9950 AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
9952 int sta = FALSE;
9954 if (AscHostReqRiscHalt(iop_base)) {
9955 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9956 AscStartChip(iop_base);
9957 return (sta);
9959 return (sta);
9962 static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
9964 ASC_SCSI_BIT_ID_TYPE org_id;
9965 int i;
9966 int sta = TRUE;
9968 AscSetBank(iop_base, 1);
9969 org_id = AscReadChipDvcID(iop_base);
9970 for (i = 0; i <= ASC_MAX_TID; i++) {
9971 if (org_id == (0x01 << i))
9972 break;
9974 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
9975 AscWriteChipDvcID(iop_base, id);
9976 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
9977 AscSetBank(iop_base, 0);
9978 AscSetChipSyn(iop_base, sdtr_data);
9979 if (AscGetChipSyn(iop_base) != sdtr_data) {
9980 sta = FALSE;
9982 } else {
9983 sta = FALSE;
9985 AscSetBank(iop_base, 1);
9986 AscWriteChipDvcID(iop_base, org_id);
9987 AscSetBank(iop_base, 0);
9988 return (sta);
9991 static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
9993 uchar i;
9994 ushort s_addr;
9995 PortAddr iop_base;
9996 ushort warn_code;
9998 iop_base = asc_dvc->iop_base;
9999 warn_code = 0;
10000 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
10001 (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
10002 64) >> 1)
10004 i = ASC_MIN_ACTIVE_QNO;
10005 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
10006 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
10007 (uchar)(i + 1));
10008 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
10009 (uchar)(asc_dvc->max_total_qng));
10010 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
10011 (uchar)i);
10012 i++;
10013 s_addr += ASC_QBLK_SIZE;
10014 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
10015 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
10016 (uchar)(i + 1));
10017 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
10018 (uchar)(i - 1));
10019 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
10020 (uchar)i);
10022 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
10023 (uchar)ASC_QLINK_END);
10024 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
10025 (uchar)(asc_dvc->max_total_qng - 1));
10026 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
10027 (uchar)asc_dvc->max_total_qng);
10028 i++;
10029 s_addr += ASC_QBLK_SIZE;
10030 for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
10031 i++, s_addr += ASC_QBLK_SIZE) {
10032 AscWriteLramByte(iop_base,
10033 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
10034 AscWriteLramByte(iop_base,
10035 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
10036 AscWriteLramByte(iop_base,
10037 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
10039 return (warn_code);
10042 static ushort AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
10044 PortAddr iop_base;
10045 int i;
10046 ushort lram_addr;
10048 iop_base = asc_dvc->iop_base;
10049 AscPutRiscVarFreeQHead(iop_base, 1);
10050 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
10051 AscPutVarFreeQHead(iop_base, 1);
10052 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
10053 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
10054 (uchar)((int)asc_dvc->max_total_qng + 1));
10055 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
10056 (uchar)((int)asc_dvc->max_total_qng + 2));
10057 AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
10058 asc_dvc->max_total_qng);
10059 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
10060 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10061 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
10062 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
10063 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
10064 AscPutQDoneInProgress(iop_base, 0);
10065 lram_addr = ASC_QADR_BEG;
10066 for (i = 0; i < 32; i++, lram_addr += 2) {
10067 AscWriteLramWord(iop_base, lram_addr, 0);
10069 return (0);
10072 static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
10074 if (asc_dvc->err_code == 0) {
10075 asc_dvc->err_code = err_code;
10076 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
10077 err_code);
10079 return (err_code);
10082 static uchar
10083 AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
10085 EXT_MSG sdtr_buf;
10086 uchar sdtr_period_index;
10087 PortAddr iop_base;
10089 iop_base = asc_dvc->iop_base;
10090 sdtr_buf.msg_type = MS_EXTEND;
10091 sdtr_buf.msg_len = MS_SDTR_LEN;
10092 sdtr_buf.msg_req = MS_SDTR_CODE;
10093 sdtr_buf.xfer_period = sdtr_period;
10094 sdtr_offset &= ASC_SYN_MAX_OFFSET;
10095 sdtr_buf.req_ack_offset = sdtr_offset;
10096 if ((sdtr_period_index =
10097 AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
10098 asc_dvc->max_sdtr_index) {
10099 AscMemWordCopyPtrToLram(iop_base,
10100 ASCV_MSGOUT_BEG,
10101 (uchar *)&sdtr_buf,
10102 sizeof(EXT_MSG) >> 1);
10103 return ((sdtr_period_index << 4) | sdtr_offset);
10104 } else {
10106 sdtr_buf.req_ack_offset = 0;
10107 AscMemWordCopyPtrToLram(iop_base,
10108 ASCV_MSGOUT_BEG,
10109 (uchar *)&sdtr_buf,
10110 sizeof(EXT_MSG) >> 1);
10111 return (0);
10115 static uchar
10116 AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
10118 uchar byte;
10119 uchar sdtr_period_ix;
10121 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
10122 if ((sdtr_period_ix > asc_dvc->max_sdtr_index)
10124 return (0xFF);
10126 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
10127 return (byte);
10130 static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
10132 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
10133 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
10134 return;
10137 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
10139 uchar *period_table;
10140 int max_index;
10141 int min_index;
10142 int i;
10144 period_table = asc_dvc->sdtr_period_tbl;
10145 max_index = (int)asc_dvc->max_sdtr_index;
10146 min_index = (int)asc_dvc->host_init_sdtr_index;
10147 if ((syn_time <= period_table[max_index])) {
10148 for (i = min_index; i < (max_index - 1); i++) {
10149 if (syn_time <= period_table[i]) {
10150 return ((uchar)i);
10153 return ((uchar)max_index);
10154 } else {
10155 return ((uchar)(max_index + 1));
10159 static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
10161 ushort q_addr;
10162 uchar next_qp;
10163 uchar q_status;
10165 q_addr = ASC_QNO_TO_QADDR(free_q_head);
10166 q_status = (uchar)AscReadLramByte(iop_base,
10167 (ushort)(q_addr +
10168 ASC_SCSIQ_B_STATUS));
10169 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
10170 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
10171 return (next_qp);
10173 return (ASC_QLINK_END);
10176 static uchar
10177 AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
10179 uchar i;
10181 for (i = 0; i < n_free_q; i++) {
10182 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
10183 == ASC_QLINK_END) {
10184 return (ASC_QLINK_END);
10187 return (free_q_head);
10190 static int AscHostReqRiscHalt(PortAddr iop_base)
10192 int count = 0;
10193 int sta = 0;
10194 uchar saved_stop_code;
10196 if (AscIsChipHalted(iop_base))
10197 return (1);
10198 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
10199 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
10200 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
10201 do {
10202 if (AscIsChipHalted(iop_base)) {
10203 sta = 1;
10204 break;
10206 DvcSleepMilliSecond(100);
10207 } while (count++ < 20);
10208 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
10209 return (sta);
10212 static int AscStopQueueExe(PortAddr iop_base)
10214 int count = 0;
10216 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
10217 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
10218 ASC_STOP_REQ_RISC_STOP);
10219 do {
10220 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
10221 ASC_STOP_ACK_RISC_STOP) {
10222 return (1);
10224 DvcSleepMilliSecond(100);
10225 } while (count++ < 20);
10227 return (0);
10230 static void DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
10232 udelay(micro_sec);
10235 static void DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
10237 udelay((nano_sec + 999) / 1000);
10240 static int AscStartChip(PortAddr iop_base)
10242 AscSetChipControl(iop_base, 0);
10243 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
10244 return (0);
10246 return (1);
10249 static int AscStopChip(PortAddr iop_base)
10251 uchar cc_val;
10253 cc_val =
10254 AscGetChipControl(iop_base) &
10255 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
10256 AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
10257 AscSetChipIH(iop_base, INS_HALT);
10258 AscSetChipIH(iop_base, INS_RFLAG_WTM);
10259 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
10260 return (0);
10262 return (1);
10265 static int AscIsChipHalted(PortAddr iop_base)
10267 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
10268 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
10269 return (1);
10272 return (0);
10275 static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
10277 AscSetBank(iop_base, 1);
10278 AscWriteChipIH(iop_base, ins_code);
10279 AscSetBank(iop_base, 0);
10280 return;
10283 static void AscAckInterrupt(PortAddr iop_base)
10285 uchar host_flag;
10286 uchar risc_flag;
10287 ushort loop;
10289 loop = 0;
10290 do {
10291 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
10292 if (loop++ > 0x7FFF) {
10293 break;
10295 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
10296 host_flag =
10297 AscReadLramByte(iop_base,
10298 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
10299 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10300 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
10301 AscSetChipStatus(iop_base, CIW_INT_ACK);
10302 loop = 0;
10303 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
10304 AscSetChipStatus(iop_base, CIW_INT_ACK);
10305 if (loop++ > 3) {
10306 break;
10309 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10310 return;
10313 static void AscDisableInterrupt(PortAddr iop_base)
10315 ushort cfg;
10317 cfg = AscGetChipCfgLsw(iop_base);
10318 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
10319 return;
10322 static void AscEnableInterrupt(PortAddr iop_base)
10324 ushort cfg;
10326 cfg = AscGetChipCfgLsw(iop_base);
10327 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
10328 return;
10331 static void AscSetBank(PortAddr iop_base, uchar bank)
10333 uchar val;
10335 val = AscGetChipControl(iop_base) &
10337 (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
10338 CC_CHIP_RESET));
10339 if (bank == 1) {
10340 val |= CC_BANK_ONE;
10341 } else if (bank == 2) {
10342 val |= CC_DIAG | CC_BANK_ONE;
10343 } else {
10344 val &= ~CC_BANK_ONE;
10346 AscSetChipControl(iop_base, val);
10347 return;
10350 static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
10352 PortAddr iop_base;
10353 int i = 10;
10355 iop_base = asc_dvc->iop_base;
10356 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
10357 && (i-- > 0)) {
10358 DvcSleepMilliSecond(100);
10360 AscStopChip(iop_base);
10361 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
10362 DvcDelayNanoSecond(asc_dvc, 60000);
10363 AscSetChipIH(iop_base, INS_RFLAG_WTM);
10364 AscSetChipIH(iop_base, INS_HALT);
10365 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
10366 AscSetChipControl(iop_base, CC_HALT);
10367 DvcSleepMilliSecond(200);
10368 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10369 AscSetChipStatus(iop_base, 0);
10370 return (AscIsChipHalted(iop_base));
10373 static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
10375 if (bus_type & ASC_IS_ISA)
10376 return (ASC_MAX_ISA_DMA_COUNT);
10377 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
10378 return (ASC_MAX_VL_DMA_COUNT);
10379 return (ASC_MAX_PCI_DMA_COUNT);
10382 #ifdef CONFIG_ISA
10383 static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
10385 ushort channel;
10387 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
10388 if (channel == 0x03)
10389 return (0);
10390 else if (channel == 0x00)
10391 return (7);
10392 return (channel + 4);
10395 static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
10397 ushort cfg_lsw;
10398 uchar value;
10400 if ((dma_channel >= 5) && (dma_channel <= 7)) {
10401 if (dma_channel == 7)
10402 value = 0x00;
10403 else
10404 value = dma_channel - 4;
10405 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
10406 cfg_lsw |= value;
10407 AscSetChipCfgLsw(iop_base, cfg_lsw);
10408 return (AscGetIsaDmaChannel(iop_base));
10410 return (0);
10413 static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
10415 speed_value &= 0x07;
10416 AscSetBank(iop_base, 1);
10417 AscWriteChipDmaSpeed(iop_base, speed_value);
10418 AscSetBank(iop_base, 0);
10419 return (AscGetIsaDmaSpeed(iop_base));
10422 static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
10424 uchar speed_value;
10426 AscSetBank(iop_base, 1);
10427 speed_value = AscReadChipDmaSpeed(iop_base);
10428 speed_value &= 0x07;
10429 AscSetBank(iop_base, 0);
10430 return (speed_value);
10432 #endif /* CONFIG_ISA */
10434 static ushort __devinit
10435 AscReadPCIConfigWord(ASC_DVC_VAR *asc_dvc, ushort pci_config_offset)
10437 uchar lsb, msb;
10439 lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
10440 msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
10441 return ((ushort)((msb << 8) | lsb));
10444 static ushort __devinit AscInitGetConfig(ASC_DVC_VAR *asc_dvc)
10446 ushort warn_code;
10447 PortAddr iop_base;
10448 ushort PCIDeviceID;
10449 ushort PCIVendorID;
10450 uchar PCIRevisionID;
10451 uchar prevCmdRegBits;
10453 warn_code = 0;
10454 iop_base = asc_dvc->iop_base;
10455 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
10456 if (asc_dvc->err_code != 0) {
10457 return (UW_ERR);
10459 if (asc_dvc->bus_type == ASC_IS_PCI) {
10460 PCIVendorID = AscReadPCIConfigWord(asc_dvc,
10461 AscPCIConfigVendorIDRegister);
10463 PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
10464 AscPCIConfigDeviceIDRegister);
10466 PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
10467 AscPCIConfigRevisionIDRegister);
10469 if (PCIVendorID != PCI_VENDOR_ID_ASP) {
10470 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10472 prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
10473 AscPCIConfigCommandRegister);
10475 if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
10476 AscPCICmdRegBits_IOMemBusMaster) {
10477 DvcWritePCIConfigByte(asc_dvc,
10478 AscPCIConfigCommandRegister,
10479 (prevCmdRegBits |
10480 AscPCICmdRegBits_IOMemBusMaster));
10482 if ((DvcReadPCIConfigByte(asc_dvc,
10483 AscPCIConfigCommandRegister)
10484 & AscPCICmdRegBits_IOMemBusMaster)
10485 != AscPCICmdRegBits_IOMemBusMaster) {
10486 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10489 if ((PCIDeviceID == PCI_DEVICE_ID_ASP_1200A) ||
10490 (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940)) {
10491 DvcWritePCIConfigByte(asc_dvc,
10492 AscPCIConfigLatencyTimer, 0x00);
10493 if (DvcReadPCIConfigByte
10494 (asc_dvc, AscPCIConfigLatencyTimer)
10495 != 0x00) {
10496 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10498 } else if (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940U) {
10499 if (DvcReadPCIConfigByte(asc_dvc,
10500 AscPCIConfigLatencyTimer) <
10501 0x20) {
10502 DvcWritePCIConfigByte(asc_dvc,
10503 AscPCIConfigLatencyTimer,
10504 0x20);
10506 if (DvcReadPCIConfigByte(asc_dvc,
10507 AscPCIConfigLatencyTimer)
10508 < 0x20) {
10509 warn_code |=
10510 ASC_WARN_SET_PCI_CONFIG_SPACE;
10516 if (AscFindSignature(iop_base)) {
10517 warn_code |= AscInitAscDvcVar(asc_dvc);
10518 warn_code |= AscInitFromEEP(asc_dvc);
10519 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
10520 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
10521 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
10523 } else {
10524 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10526 return (warn_code);
10529 static ushort __devinit AscInitSetConfig(ASC_DVC_VAR *asc_dvc)
10531 ushort warn_code = 0;
10533 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
10534 if (asc_dvc->err_code != 0)
10535 return (UW_ERR);
10536 if (AscFindSignature(asc_dvc->iop_base)) {
10537 warn_code |= AscInitFromAscDvcVar(asc_dvc);
10538 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
10539 } else {
10540 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10542 return (warn_code);
10545 static ushort __devinit AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc)
10547 PortAddr iop_base;
10548 ushort cfg_msw;
10549 ushort warn_code;
10550 ushort pci_device_id = 0;
10552 iop_base = asc_dvc->iop_base;
10553 #ifdef CONFIG_PCI
10554 if (asc_dvc->cfg->dev)
10555 pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device;
10556 #endif
10557 warn_code = 0;
10558 cfg_msw = AscGetChipCfgMsw(iop_base);
10559 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10560 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10561 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10562 AscSetChipCfgMsw(iop_base, cfg_msw);
10564 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
10565 asc_dvc->cfg->cmd_qng_enabled) {
10566 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
10567 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10569 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10570 warn_code |= ASC_WARN_AUTO_CONFIG;
10572 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
10573 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
10574 != asc_dvc->irq_no) {
10575 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
10578 if (asc_dvc->bus_type & ASC_IS_PCI) {
10579 cfg_msw &= 0xFFC0;
10580 AscSetChipCfgMsw(iop_base, cfg_msw);
10581 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
10582 } else {
10583 if ((pci_device_id == PCI_DEVICE_ID_ASP_1200A) ||
10584 (pci_device_id == PCI_DEVICE_ID_ASP_ABP940)) {
10585 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
10586 asc_dvc->bug_fix_cntl |=
10587 ASC_BUG_FIX_ASYN_USE_SYN;
10590 } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
10591 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
10592 == ASC_CHIP_VER_ASYN_BUG) {
10593 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
10596 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
10597 asc_dvc->cfg->chip_scsi_id) {
10598 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
10600 #ifdef CONFIG_ISA
10601 if (asc_dvc->bus_type & ASC_IS_ISA) {
10602 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
10603 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
10605 #endif /* CONFIG_ISA */
10606 return (warn_code);
10609 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
10611 ushort warn_code;
10612 PortAddr iop_base;
10614 iop_base = asc_dvc->iop_base;
10615 warn_code = 0;
10616 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
10617 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
10618 AscResetChipAndScsiBus(asc_dvc);
10619 DvcSleepMilliSecond((ASC_DCNT)
10620 ((ushort)asc_dvc->scsi_reset_wait * 1000));
10622 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
10623 if (asc_dvc->err_code != 0)
10624 return (UW_ERR);
10625 if (!AscFindSignature(asc_dvc->iop_base)) {
10626 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10627 return (warn_code);
10629 AscDisableInterrupt(iop_base);
10630 warn_code |= AscInitLram(asc_dvc);
10631 if (asc_dvc->err_code != 0)
10632 return (UW_ERR);
10633 ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
10634 (ulong)_asc_mcode_chksum);
10635 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
10636 _asc_mcode_size) != _asc_mcode_chksum) {
10637 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
10638 return (warn_code);
10640 warn_code |= AscInitMicroCodeVar(asc_dvc);
10641 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
10642 AscEnableInterrupt(iop_base);
10643 return (warn_code);
10646 static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
10648 int i;
10649 PortAddr iop_base;
10650 ushort warn_code;
10651 uchar chip_version;
10653 iop_base = asc_dvc->iop_base;
10654 warn_code = 0;
10655 asc_dvc->err_code = 0;
10656 if ((asc_dvc->bus_type &
10657 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
10658 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
10660 AscSetChipControl(iop_base, CC_HALT);
10661 AscSetChipStatus(iop_base, 0);
10662 asc_dvc->bug_fix_cntl = 0;
10663 asc_dvc->pci_fix_asyn_xfer = 0;
10664 asc_dvc->pci_fix_asyn_xfer_always = 0;
10665 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
10666 asc_dvc->sdtr_done = 0;
10667 asc_dvc->cur_total_qng = 0;
10668 asc_dvc->is_in_int = 0;
10669 asc_dvc->in_critical_cnt = 0;
10670 asc_dvc->last_q_shortage = 0;
10671 asc_dvc->use_tagged_qng = 0;
10672 asc_dvc->no_scam = 0;
10673 asc_dvc->unit_not_ready = 0;
10674 asc_dvc->queue_full_or_busy = 0;
10675 asc_dvc->redo_scam = 0;
10676 asc_dvc->res2 = 0;
10677 asc_dvc->host_init_sdtr_index = 0;
10678 asc_dvc->cfg->can_tagged_qng = 0;
10679 asc_dvc->cfg->cmd_qng_enabled = 0;
10680 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
10681 asc_dvc->init_sdtr = 0;
10682 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
10683 asc_dvc->scsi_reset_wait = 3;
10684 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
10685 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
10686 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
10687 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
10688 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
10689 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
10690 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
10691 ASC_LIB_VERSION_MINOR;
10692 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
10693 asc_dvc->cfg->chip_version = chip_version;
10694 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
10695 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
10696 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
10697 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
10698 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
10699 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
10700 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
10701 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
10702 asc_dvc->max_sdtr_index = 7;
10703 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
10704 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
10705 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
10706 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
10707 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
10708 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
10709 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
10710 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
10711 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
10712 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
10713 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
10714 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
10715 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
10716 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
10717 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
10718 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
10719 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
10720 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
10721 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
10722 asc_dvc->max_sdtr_index = 15;
10723 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
10724 AscSetExtraControl(iop_base,
10725 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10726 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
10727 AscSetExtraControl(iop_base,
10728 (SEC_ACTIVE_NEGATE |
10729 SEC_ENABLE_FILTER));
10732 if (asc_dvc->bus_type == ASC_IS_PCI) {
10733 AscSetExtraControl(iop_base,
10734 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10737 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
10738 if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
10739 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
10740 asc_dvc->bus_type = ASC_IS_ISAPNP;
10742 #ifdef CONFIG_ISA
10743 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
10744 asc_dvc->cfg->isa_dma_channel =
10745 (uchar)AscGetIsaDmaChannel(iop_base);
10747 #endif /* CONFIG_ISA */
10748 for (i = 0; i <= ASC_MAX_TID; i++) {
10749 asc_dvc->cur_dvc_qng[i] = 0;
10750 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
10751 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
10752 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
10753 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
10755 return (warn_code);
10758 static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
10760 ASCEEP_CONFIG eep_config_buf;
10761 ASCEEP_CONFIG *eep_config;
10762 PortAddr iop_base;
10763 ushort chksum;
10764 ushort warn_code;
10765 ushort cfg_msw, cfg_lsw;
10766 int i;
10767 int write_eep = 0;
10769 iop_base = asc_dvc->iop_base;
10770 warn_code = 0;
10771 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
10772 AscStopQueueExe(iop_base);
10773 if ((AscStopChip(iop_base) == FALSE) ||
10774 (AscGetChipScsiCtrl(iop_base) != 0)) {
10775 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
10776 AscResetChipAndScsiBus(asc_dvc);
10777 DvcSleepMilliSecond((ASC_DCNT)
10778 ((ushort)asc_dvc->scsi_reset_wait * 1000));
10780 if (AscIsChipHalted(iop_base) == FALSE) {
10781 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10782 return (warn_code);
10784 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10785 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10786 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10787 return (warn_code);
10789 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
10790 cfg_msw = AscGetChipCfgMsw(iop_base);
10791 cfg_lsw = AscGetChipCfgLsw(iop_base);
10792 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10793 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10794 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10795 AscSetChipCfgMsw(iop_base, cfg_msw);
10797 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
10798 ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
10799 if (chksum == 0) {
10800 chksum = 0xaa55;
10802 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10803 warn_code |= ASC_WARN_AUTO_CONFIG;
10804 if (asc_dvc->cfg->chip_version == 3) {
10805 if (eep_config->cfg_lsw != cfg_lsw) {
10806 warn_code |= ASC_WARN_EEPROM_RECOVER;
10807 eep_config->cfg_lsw =
10808 AscGetChipCfgLsw(iop_base);
10810 if (eep_config->cfg_msw != cfg_msw) {
10811 warn_code |= ASC_WARN_EEPROM_RECOVER;
10812 eep_config->cfg_msw =
10813 AscGetChipCfgMsw(iop_base);
10817 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
10818 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
10819 ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
10820 eep_config->chksum);
10821 if (chksum != eep_config->chksum) {
10822 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
10823 ASC_CHIP_VER_PCI_ULTRA_3050) {
10824 ASC_DBG(1,
10825 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
10826 eep_config->init_sdtr = 0xFF;
10827 eep_config->disc_enable = 0xFF;
10828 eep_config->start_motor = 0xFF;
10829 eep_config->use_cmd_qng = 0;
10830 eep_config->max_total_qng = 0xF0;
10831 eep_config->max_tag_qng = 0x20;
10832 eep_config->cntl = 0xBFFF;
10833 ASC_EEP_SET_CHIP_ID(eep_config, 7);
10834 eep_config->no_scam = 0;
10835 eep_config->adapter_info[0] = 0;
10836 eep_config->adapter_info[1] = 0;
10837 eep_config->adapter_info[2] = 0;
10838 eep_config->adapter_info[3] = 0;
10839 eep_config->adapter_info[4] = 0;
10840 /* Indicate EEPROM-less board. */
10841 eep_config->adapter_info[5] = 0xBB;
10842 } else {
10843 ASC_PRINT
10844 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
10845 write_eep = 1;
10846 warn_code |= ASC_WARN_EEPROM_CHKSUM;
10849 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
10850 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
10851 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
10852 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
10853 asc_dvc->start_motor = eep_config->start_motor;
10854 asc_dvc->dvc_cntl = eep_config->cntl;
10855 asc_dvc->no_scam = eep_config->no_scam;
10856 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
10857 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
10858 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
10859 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
10860 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
10861 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
10862 if (!AscTestExternalLram(asc_dvc)) {
10863 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
10864 ASC_IS_PCI_ULTRA)) {
10865 eep_config->max_total_qng =
10866 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
10867 eep_config->max_tag_qng =
10868 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
10869 } else {
10870 eep_config->cfg_msw |= 0x0800;
10871 cfg_msw |= 0x0800;
10872 AscSetChipCfgMsw(iop_base, cfg_msw);
10873 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
10874 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
10876 } else {
10878 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
10879 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
10881 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
10882 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
10884 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
10885 eep_config->max_tag_qng = eep_config->max_total_qng;
10887 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
10888 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
10890 asc_dvc->max_total_qng = eep_config->max_total_qng;
10891 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
10892 eep_config->use_cmd_qng) {
10893 eep_config->disc_enable = eep_config->use_cmd_qng;
10894 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10896 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
10897 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
10899 ASC_EEP_SET_CHIP_ID(eep_config,
10900 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
10901 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
10902 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
10903 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
10904 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
10907 for (i = 0; i <= ASC_MAX_TID; i++) {
10908 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
10909 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
10910 asc_dvc->cfg->sdtr_period_offset[i] =
10911 (uchar)(ASC_DEF_SDTR_OFFSET |
10912 (asc_dvc->host_init_sdtr_index << 4));
10914 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
10915 if (write_eep) {
10916 if ((i =
10917 AscSetEEPConfig(iop_base, eep_config,
10918 asc_dvc->bus_type)) != 0) {
10919 ASC_PRINT1
10920 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
10922 } else {
10923 ASC_PRINT
10924 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
10927 return (warn_code);
10930 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
10932 int i;
10933 ushort warn_code;
10934 PortAddr iop_base;
10935 ASC_PADDR phy_addr;
10936 ASC_DCNT phy_size;
10938 iop_base = asc_dvc->iop_base;
10939 warn_code = 0;
10940 for (i = 0; i <= ASC_MAX_TID; i++) {
10941 AscPutMCodeInitSDTRAtID(iop_base, i,
10942 asc_dvc->cfg->sdtr_period_offset[i]
10946 AscInitQLinkVar(asc_dvc);
10947 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
10948 asc_dvc->cfg->disc_enable);
10949 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
10950 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
10952 /* Align overrun buffer on an 8 byte boundary. */
10953 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
10954 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
10955 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
10956 (uchar *)&phy_addr, 1);
10957 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
10958 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
10959 (uchar *)&phy_size, 1);
10961 asc_dvc->cfg->mcode_date =
10962 AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
10963 asc_dvc->cfg->mcode_version =
10964 AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
10966 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10967 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10968 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10969 return (warn_code);
10971 if (AscStartChip(iop_base) != 1) {
10972 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10973 return (warn_code);
10976 return (warn_code);
10979 static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
10981 PortAddr iop_base;
10982 ushort q_addr;
10983 ushort saved_word;
10984 int sta;
10986 iop_base = asc_dvc->iop_base;
10987 sta = 0;
10988 q_addr = ASC_QNO_TO_QADDR(241);
10989 saved_word = AscReadLramWord(iop_base, q_addr);
10990 AscSetChipLramAddr(iop_base, q_addr);
10991 AscSetChipLramData(iop_base, 0x55AA);
10992 DvcSleepMilliSecond(10);
10993 AscSetChipLramAddr(iop_base, q_addr);
10994 if (AscGetChipLramData(iop_base) == 0x55AA) {
10995 sta = 1;
10996 AscWriteLramWord(iop_base, q_addr, saved_word);
10998 return (sta);
11001 static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
11003 uchar read_back;
11004 int retry;
11006 retry = 0;
11007 while (TRUE) {
11008 AscSetChipEEPCmd(iop_base, cmd_reg);
11009 DvcSleepMilliSecond(1);
11010 read_back = AscGetChipEEPCmd(iop_base);
11011 if (read_back == cmd_reg) {
11012 return (1);
11014 if (retry++ > ASC_EEP_MAX_RETRY) {
11015 return (0);
11020 static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
11022 ushort read_back;
11023 int retry;
11025 retry = 0;
11026 while (TRUE) {
11027 AscSetChipEEPData(iop_base, data_reg);
11028 DvcSleepMilliSecond(1);
11029 read_back = AscGetChipEEPData(iop_base);
11030 if (read_back == data_reg) {
11031 return (1);
11033 if (retry++ > ASC_EEP_MAX_RETRY) {
11034 return (0);
11039 static void __devinit AscWaitEEPRead(void)
11041 DvcSleepMilliSecond(1);
11042 return;
11045 static void __devinit AscWaitEEPWrite(void)
11047 DvcSleepMilliSecond(20);
11048 return;
11051 static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
11053 ushort read_wval;
11054 uchar cmd_reg;
11056 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11057 AscWaitEEPRead();
11058 cmd_reg = addr | ASC_EEP_CMD_READ;
11059 AscWriteEEPCmdReg(iop_base, cmd_reg);
11060 AscWaitEEPRead();
11061 read_wval = AscGetChipEEPData(iop_base);
11062 AscWaitEEPRead();
11063 return (read_wval);
11066 static ushort __devinit
11067 AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
11069 ushort read_wval;
11071 read_wval = AscReadEEPWord(iop_base, addr);
11072 if (read_wval != word_val) {
11073 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
11074 AscWaitEEPRead();
11075 AscWriteEEPDataReg(iop_base, word_val);
11076 AscWaitEEPRead();
11077 AscWriteEEPCmdReg(iop_base,
11078 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
11079 AscWaitEEPWrite();
11080 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
11081 AscWaitEEPRead();
11082 return (AscReadEEPWord(iop_base, addr));
11084 return (read_wval);
11087 static ushort __devinit
11088 AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11090 ushort wval;
11091 ushort sum;
11092 ushort *wbuf;
11093 int cfg_beg;
11094 int cfg_end;
11095 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11096 int s_addr;
11098 wbuf = (ushort *)cfg_buf;
11099 sum = 0;
11100 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
11101 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11102 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11103 sum += *wbuf;
11105 if (bus_type & ASC_IS_VL) {
11106 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11107 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11108 } else {
11109 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11110 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11112 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11113 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
11114 if (s_addr <= uchar_end_in_config) {
11116 * Swap all char fields - must unswap bytes already swapped
11117 * by AscReadEEPWord().
11119 *wbuf = le16_to_cpu(wval);
11120 } else {
11121 /* Don't swap word field at the end - cntl field. */
11122 *wbuf = wval;
11124 sum += wval; /* Checksum treats all EEPROM data as words. */
11127 * Read the checksum word which will be compared against 'sum'
11128 * by the caller. Word field already swapped.
11130 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11131 return (sum);
11134 static int __devinit
11135 AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11137 int n_error;
11138 ushort *wbuf;
11139 ushort word;
11140 ushort sum;
11141 int s_addr;
11142 int cfg_beg;
11143 int cfg_end;
11144 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11146 wbuf = (ushort *)cfg_buf;
11147 n_error = 0;
11148 sum = 0;
11149 /* Write two config words; AscWriteEEPWord() will swap bytes. */
11150 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11151 sum += *wbuf;
11152 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11153 n_error++;
11156 if (bus_type & ASC_IS_VL) {
11157 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11158 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11159 } else {
11160 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11161 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11163 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11164 if (s_addr <= uchar_end_in_config) {
11166 * This is a char field. Swap char fields before they are
11167 * swapped again by AscWriteEEPWord().
11169 word = cpu_to_le16(*wbuf);
11170 if (word !=
11171 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
11172 n_error++;
11174 } else {
11175 /* Don't swap word field at the end - cntl field. */
11176 if (*wbuf !=
11177 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11178 n_error++;
11181 sum += *wbuf; /* Checksum calculated from word values. */
11183 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
11184 *wbuf = sum;
11185 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
11186 n_error++;
11189 /* Read EEPROM back again. */
11190 wbuf = (ushort *)cfg_buf;
11192 * Read two config words; Byte-swapping done by AscReadEEPWord().
11194 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11195 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
11196 n_error++;
11199 if (bus_type & ASC_IS_VL) {
11200 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11201 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11202 } else {
11203 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11204 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11206 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11207 if (s_addr <= uchar_end_in_config) {
11209 * Swap all char fields. Must unswap bytes already swapped
11210 * by AscReadEEPWord().
11212 word =
11213 le16_to_cpu(AscReadEEPWord
11214 (iop_base, (uchar)s_addr));
11215 } else {
11216 /* Don't swap word field at the end - cntl field. */
11217 word = AscReadEEPWord(iop_base, (uchar)s_addr);
11219 if (*wbuf != word) {
11220 n_error++;
11223 /* Read checksum; Byte swapping not needed. */
11224 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
11225 n_error++;
11227 return (n_error);
11230 static int __devinit
11231 AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11233 int retry;
11234 int n_error;
11236 retry = 0;
11237 while (TRUE) {
11238 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
11239 bus_type)) == 0) {
11240 break;
11242 if (++retry > ASC_EEP_MAX_RETRY) {
11243 break;
11246 return (n_error);
11249 static void
11250 AscAsyncFix(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq)
11252 uchar dvc_type;
11253 ASC_SCSI_BIT_ID_TYPE tid_bits;
11255 dvc_type = ASC_INQ_DVC_TYPE(inq);
11256 tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
11258 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
11259 if (!(asc_dvc->init_sdtr & tid_bits)) {
11260 if ((dvc_type == TYPE_ROM) &&
11261 (AscCompareString((uchar *)inq->vendor_id,
11262 (uchar *)"HP ", 3) == 0)) {
11263 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
11265 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
11266 if ((dvc_type == TYPE_PROCESSOR) ||
11267 (dvc_type == TYPE_SCANNER) ||
11268 (dvc_type == TYPE_ROM) || (dvc_type == TYPE_TAPE)) {
11269 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
11272 if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
11273 AscSetRunChipSynRegAtID(asc_dvc->iop_base,
11274 tid_no,
11275 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
11279 return;
11282 static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
11284 if ((inq->add_len >= 32) &&
11285 (AscCompareString((uchar *)inq->vendor_id,
11286 (uchar *)"QUANTUM XP34301", 15) == 0) &&
11287 (AscCompareString((uchar *)inq->product_rev_level,
11288 (uchar *)"1071", 4) == 0)) {
11289 return 0;
11291 return 1;
11294 static void
11295 AscInquiryHandling(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq)
11297 ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
11298 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
11300 orig_init_sdtr = asc_dvc->init_sdtr;
11301 orig_use_tagged_qng = asc_dvc->use_tagged_qng;
11303 asc_dvc->init_sdtr &= ~tid_bit;
11304 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
11305 asc_dvc->use_tagged_qng &= ~tid_bit;
11307 if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) {
11308 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) {
11309 asc_dvc->init_sdtr |= tid_bit;
11311 if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) &&
11312 ASC_INQ_CMD_QUEUE(inq)) {
11313 if (AscTagQueuingSafe(inq)) {
11314 asc_dvc->use_tagged_qng |= tid_bit;
11315 asc_dvc->cfg->can_tagged_qng |= tid_bit;
11319 if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
11320 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
11321 asc_dvc->cfg->disc_enable);
11322 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
11323 asc_dvc->use_tagged_qng);
11324 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
11325 asc_dvc->cfg->can_tagged_qng);
11327 asc_dvc->max_dvc_qng[tid_no] =
11328 asc_dvc->cfg->max_tag_qng[tid_no];
11329 AscWriteLramByte(asc_dvc->iop_base,
11330 (ushort)(ASCV_MAX_DVC_QNG_BEG + tid_no),
11331 asc_dvc->max_dvc_qng[tid_no]);
11333 if (orig_init_sdtr != asc_dvc->init_sdtr) {
11334 AscAsyncFix(asc_dvc, tid_no, inq);
11336 return;
11339 static int AscCompareString(uchar *str1, uchar *str2, int len)
11341 int i;
11342 int diff;
11344 for (i = 0; i < len; i++) {
11345 diff = (int)(str1[i] - str2[i]);
11346 if (diff != 0)
11347 return (diff);
11349 return (0);
11352 static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
11354 uchar byte_data;
11355 ushort word_data;
11357 if (isodd_word(addr)) {
11358 AscSetChipLramAddr(iop_base, addr - 1);
11359 word_data = AscGetChipLramData(iop_base);
11360 byte_data = (uchar)((word_data >> 8) & 0xFF);
11361 } else {
11362 AscSetChipLramAddr(iop_base, addr);
11363 word_data = AscGetChipLramData(iop_base);
11364 byte_data = (uchar)(word_data & 0xFF);
11366 return (byte_data);
11369 static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
11371 ushort word_data;
11373 AscSetChipLramAddr(iop_base, addr);
11374 word_data = AscGetChipLramData(iop_base);
11375 return (word_data);
11378 #if CC_VERY_LONG_SG_LIST
11379 static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
11381 ushort val_low, val_high;
11382 ASC_DCNT dword_data;
11384 AscSetChipLramAddr(iop_base, addr);
11385 val_low = AscGetChipLramData(iop_base);
11386 val_high = AscGetChipLramData(iop_base);
11387 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
11388 return (dword_data);
11390 #endif /* CC_VERY_LONG_SG_LIST */
11392 static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
11394 AscSetChipLramAddr(iop_base, addr);
11395 AscSetChipLramData(iop_base, word_val);
11396 return;
11399 static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
11401 ushort word_data;
11403 if (isodd_word(addr)) {
11404 addr--;
11405 word_data = AscReadLramWord(iop_base, addr);
11406 word_data &= 0x00FF;
11407 word_data |= (((ushort)byte_val << 8) & 0xFF00);
11408 } else {
11409 word_data = AscReadLramWord(iop_base, addr);
11410 word_data &= 0xFF00;
11411 word_data |= ((ushort)byte_val & 0x00FF);
11413 AscWriteLramWord(iop_base, addr, word_data);
11414 return;
11418 * Copy 2 bytes to LRAM.
11420 * The source data is assumed to be in little-endian order in memory
11421 * and is maintained in little-endian order when written to LRAM.
11423 static void
11424 AscMemWordCopyPtrToLram(PortAddr iop_base,
11425 ushort s_addr, uchar *s_buffer, int words)
11427 int i;
11429 AscSetChipLramAddr(iop_base, s_addr);
11430 for (i = 0; i < 2 * words; i += 2) {
11432 * On a little-endian system the second argument below
11433 * produces a little-endian ushort which is written to
11434 * LRAM in little-endian order. On a big-endian system
11435 * the second argument produces a big-endian ushort which
11436 * is "transparently" byte-swapped by outpw() and written
11437 * in little-endian order to LRAM.
11439 outpw(iop_base + IOP_RAM_DATA,
11440 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
11442 return;
11446 * Copy 4 bytes to LRAM.
11448 * The source data is assumed to be in little-endian order in memory
11449 * and is maintained in little-endian order when writen to LRAM.
11451 static void
11452 AscMemDWordCopyPtrToLram(PortAddr iop_base,
11453 ushort s_addr, uchar *s_buffer, int dwords)
11455 int i;
11457 AscSetChipLramAddr(iop_base, s_addr);
11458 for (i = 0; i < 4 * dwords; i += 4) {
11459 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
11460 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
11462 return;
11466 * Copy 2 bytes from LRAM.
11468 * The source data is assumed to be in little-endian order in LRAM
11469 * and is maintained in little-endian order when written to memory.
11471 static void
11472 AscMemWordCopyPtrFromLram(PortAddr iop_base,
11473 ushort s_addr, uchar *d_buffer, int words)
11475 int i;
11476 ushort word;
11478 AscSetChipLramAddr(iop_base, s_addr);
11479 for (i = 0; i < 2 * words; i += 2) {
11480 word = inpw(iop_base + IOP_RAM_DATA);
11481 d_buffer[i] = word & 0xff;
11482 d_buffer[i + 1] = (word >> 8) & 0xff;
11484 return;
11487 static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
11489 ASC_DCNT sum;
11490 int i;
11492 sum = 0L;
11493 for (i = 0; i < words; i++, s_addr += 2) {
11494 sum += AscReadLramWord(iop_base, s_addr);
11496 return (sum);
11499 static void
11500 AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
11502 int i;
11504 AscSetChipLramAddr(iop_base, s_addr);
11505 for (i = 0; i < words; i++) {
11506 AscSetChipLramData(iop_base, set_wval);
11508 return;
11512 * --- Adv Library Functions
11515 /* a_mcode.h */
11517 /* Microcode buffer is kept after initialization for error recovery. */
11518 static unsigned char _adv_asc3550_buf[] = {
11519 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
11520 0x01, 0x00, 0x48, 0xe4,
11521 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff,
11522 0x28, 0x0e, 0x9e, 0xe7,
11523 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7,
11524 0x55, 0xf0, 0x01, 0xf6,
11525 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
11526 0x00, 0xec, 0x85, 0xf0,
11527 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0,
11528 0x86, 0xf0, 0xb4, 0x00,
11529 0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00,
11530 0xaa, 0x18, 0x02, 0x80,
11531 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
11532 0x00, 0x57, 0x01, 0xea,
11533 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80,
11534 0x03, 0xe6, 0xb6, 0x00,
11535 0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12,
11536 0x02, 0x4a, 0xb9, 0x54,
11537 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
11538 0x3e, 0x00, 0x80, 0x00,
11539 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
11540 0x74, 0x01, 0x76, 0x01,
11541 0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13,
11542 0x4c, 0x1c, 0xbb, 0x55,
11543 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
11544 0x03, 0xf7, 0x06, 0xf7,
11545 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08,
11546 0x30, 0x13, 0x64, 0x15,
11547 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c,
11548 0x04, 0xea, 0x5d, 0xf0,
11549 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
11550 0xcc, 0x00, 0x20, 0x01,
11551 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13,
11552 0x40, 0x13, 0x30, 0x1c,
11553 0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
11554 0x59, 0xf0, 0xa7, 0xf0,
11555 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
11556 0xa4, 0x00, 0xb5, 0x00,
11557 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a,
11558 0x14, 0x0e, 0x02, 0x10,
11559 0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13,
11560 0x10, 0x15, 0x14, 0x15,
11561 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
11562 0x91, 0x44, 0x0a, 0x45,
11563 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58,
11564 0x83, 0x59, 0x05, 0xe6,
11565 0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8,
11566 0x02, 0xfa, 0x03, 0xfa,
11567 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
11568 0x9e, 0x00, 0xa8, 0x00,
11569 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01,
11570 0x7a, 0x01, 0xc0, 0x01,
11571 0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08,
11572 0x69, 0x08, 0xba, 0x08,
11573 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
11574 0xf1, 0x10, 0x06, 0x12,
11575 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14,
11576 0x8a, 0x15, 0xc6, 0x17,
11577 0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
11578 0x0e, 0x47, 0x48, 0x47,
11579 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
11580 0x14, 0x56, 0x77, 0x57,
11581 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c,
11582 0xf0, 0x29, 0x02, 0xfe,
11583 0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf,
11584 0xfe, 0x80, 0x01, 0xff,
11585 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
11586 0x00, 0xfe, 0x57, 0x24,
11587 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09,
11588 0x00, 0x00, 0xff, 0x08,
11589 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
11590 0xff, 0xff, 0xff, 0x0f,
11591 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
11592 0xfe, 0x04, 0xf7, 0xcf,
11593 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67,
11594 0x0b, 0x3c, 0x2a, 0xfe,
11595 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0,
11596 0xfe, 0xf0, 0x01, 0xfe,
11597 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
11598 0x02, 0xfe, 0xd4, 0x0c,
11599 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
11600 0x1c, 0x05, 0xfe, 0xa6,
11601 0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48,
11602 0xf0, 0xfe, 0x86, 0x02,
11603 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
11604 0xfe, 0x46, 0xf0, 0xfe,
11605 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
11606 0x44, 0x02, 0xfe, 0x44,
11607 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b,
11608 0xa0, 0x17, 0x06, 0x18,
11609 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
11610 0x1e, 0x1c, 0xfe, 0xe9,
11611 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7,
11612 0x0a, 0x6b, 0x01, 0x9e,
11613 0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b,
11614 0x01, 0x82, 0xfe, 0xbd,
11615 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
11616 0x58, 0x1c, 0x17, 0x06,
11617 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21,
11618 0xfe, 0x94, 0x02, 0xfe,
11619 0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97,
11620 0x01, 0xfe, 0x54, 0x0f,
11621 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
11622 0x69, 0x10, 0x17, 0x06,
11623 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05,
11624 0xf6, 0xc7, 0x01, 0xfe,
11625 0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6,
11626 0x02, 0x29, 0x0a, 0x40,
11627 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
11628 0x58, 0x0a, 0x99, 0x01,
11629 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29,
11630 0x2a, 0x46, 0xfe, 0x02,
11631 0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc,
11632 0x01, 0xfe, 0x07, 0x4b,
11633 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
11634 0xfe, 0x56, 0x03, 0xfe,
11635 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10,
11636 0xfe, 0x9f, 0xf0, 0xfe,
11637 0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48,
11638 0x1c, 0xeb, 0x09, 0x04,
11639 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
11640 0x01, 0x0e, 0xac, 0x75,
11641 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2,
11642 0xfe, 0x82, 0xf0, 0xfe,
11643 0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25,
11644 0x32, 0x1f, 0xfe, 0xb4,
11645 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
11646 0x0a, 0xf0, 0xfe, 0x7a,
11647 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c,
11648 0x01, 0x33, 0x8f, 0xfe,
11649 0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8,
11650 0xf7, 0xfe, 0x48, 0x1c,
11651 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
11652 0x0a, 0xca, 0x01, 0x0e,
11653 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14,
11654 0x2c, 0x01, 0x33, 0x8f,
11655 0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65,
11656 0xfe, 0x3c, 0x04, 0x1f,
11657 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
11658 0x12, 0x2b, 0xff, 0x02,
11659 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f,
11660 0x22, 0x30, 0x2e, 0xd5,
11661 0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c,
11662 0xfe, 0x4c, 0x54, 0x64,
11663 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
11664 0xfe, 0x2a, 0x13, 0x2f,
11665 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
11666 0xd3, 0xfa, 0xef, 0x86,
11667 0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04,
11668 0x1d, 0xfe, 0x1c, 0x12,
11669 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
11670 0x70, 0x0c, 0x02, 0x22,
11671 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92,
11672 0x01, 0x33, 0x02, 0x29,
11673 0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87,
11674 0x80, 0xfe, 0x31, 0xe4,
11675 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
11676 0xfe, 0x70, 0x12, 0x49,
11677 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe,
11678 0x80, 0x05, 0xfe, 0x31,
11679 0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00,
11680 0x28, 0xfe, 0x42, 0x12,
11681 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
11682 0x11, 0xfe, 0xe3, 0x00,
11683 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
11684 0x64, 0x05, 0x83, 0x24,
11685 0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe,
11686 0x09, 0x48, 0x01, 0x08,
11687 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
11688 0x86, 0x24, 0x06, 0x12,
11689 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47,
11690 0x01, 0xa7, 0x14, 0x92,
11691 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c,
11692 0x02, 0x22, 0x05, 0xfe,
11693 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
11694 0x47, 0x01, 0xa7, 0x26,
11695 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f,
11696 0x01, 0xfe, 0xaa, 0x14,
11697 0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00,
11698 0x05, 0x50, 0xb4, 0x0c,
11699 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
11700 0x13, 0x01, 0xfe, 0x14,
11701 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c,
11702 0xff, 0x02, 0x00, 0x57,
11703 0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe,
11704 0x72, 0x06, 0x49, 0x04,
11705 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
11706 0x06, 0x11, 0x9a, 0x01,
11707 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06,
11708 0x01, 0xa7, 0xec, 0x72,
11709 0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32,
11710 0xfe, 0x0a, 0xf0, 0xfe,
11711 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
11712 0x8d, 0x81, 0x02, 0x22,
11713 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00,
11714 0x01, 0x08, 0x15, 0x00,
11715 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15,
11716 0x00, 0x02, 0xfe, 0x32,
11717 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
11718 0xfe, 0x1b, 0x00, 0x01,
11719 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
11720 0x08, 0x15, 0x06, 0x01,
11721 0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe,
11722 0x9a, 0x81, 0x4b, 0x1d,
11723 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
11724 0x45, 0xfe, 0x32, 0x12,
11725 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0,
11726 0xfe, 0x32, 0x07, 0x8d,
11727 0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a,
11728 0x06, 0x15, 0x19, 0x02,
11729 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
11730 0x90, 0x77, 0xfe, 0xca,
11731 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07,
11732 0x10, 0xfe, 0x0e, 0x12,
11733 0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe,
11734 0x83, 0xe7, 0xc4, 0xa1,
11735 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
11736 0x40, 0x12, 0x58, 0x01,
11737 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6,
11738 0x51, 0x83, 0xfb, 0xfe,
11739 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90,
11740 0xfe, 0x40, 0x50, 0xfe,
11741 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
11742 0xfe, 0x2a, 0x12, 0xfe,
11743 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f,
11744 0x85, 0x01, 0xa8, 0xfe,
11745 0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56,
11746 0x18, 0x57, 0xfb, 0xfe,
11747 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
11748 0x0c, 0x39, 0x18, 0x3a,
11749 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e,
11750 0x11, 0x65, 0xfe, 0x48,
11751 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73,
11752 0xdd, 0xb8, 0xfe, 0x80,
11753 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
11754 0xfe, 0x7a, 0x08, 0x8d,
11755 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9,
11756 0x10, 0x61, 0x04, 0x06,
11757 0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68,
11758 0x12, 0xfe, 0x2e, 0x1c,
11759 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
11760 0x52, 0x12, 0xfe, 0x2c,
11761 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe,
11762 0x08, 0xfe, 0x8a, 0x10,
11763 0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe,
11764 0x24, 0x0a, 0xab, 0xfe,
11765 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
11766 0x1c, 0x12, 0xb5, 0xfe,
11767 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb,
11768 0x1c, 0x06, 0x16, 0x9d,
11769 0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b,
11770 0x14, 0x92, 0x01, 0x33,
11771 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
11772 0xfe, 0x74, 0x18, 0x1c,
11773 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b,
11774 0x01, 0xe6, 0x1e, 0x27,
11775 0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a,
11776 0x09, 0x04, 0x6a, 0xfe,
11777 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
11778 0xfe, 0x83, 0x80, 0xfe,
11779 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63,
11780 0x27, 0xfe, 0x40, 0x59,
11781 0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18,
11782 0x7c, 0xbe, 0x54, 0xbf,
11783 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
11784 0x79, 0x56, 0x68, 0x57,
11785 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5,
11786 0xa2, 0x23, 0x0c, 0x7b,
11787 0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19,
11788 0x16, 0xd7, 0x79, 0x39,
11789 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
11790 0xfe, 0x10, 0x58, 0xfe,
11791 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04,
11792 0x19, 0x16, 0xd7, 0x09,
11793 0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f,
11794 0xfe, 0x10, 0x90, 0xfe,
11795 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
11796 0x11, 0x9b, 0x09, 0x04,
11797 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08,
11798 0xfe, 0x0c, 0x58, 0xfe,
11799 0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04,
11800 0x0b, 0xfe, 0x1a, 0x12,
11801 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
11802 0x14, 0x7a, 0x01, 0x33,
11803 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39,
11804 0xfe, 0xed, 0x19, 0xbf,
11805 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff,
11806 0x34, 0xfe, 0x74, 0x10,
11807 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
11808 0x84, 0x05, 0xcb, 0x1c,
11809 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1,
11810 0xf0, 0xfe, 0xc4, 0x0a,
11811 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe,
11812 0xce, 0xf0, 0xfe, 0xca,
11813 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
11814 0x22, 0x00, 0x02, 0x5a,
11815 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a,
11816 0xfe, 0xd0, 0xf0, 0xfe,
11817 0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f,
11818 0x4c, 0xfe, 0x10, 0x10,
11819 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
11820 0x2a, 0x13, 0xfe, 0x4e,
11821 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1,
11822 0x16, 0x32, 0x2a, 0x73,
11823 0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25,
11824 0x32, 0x8c, 0xfe, 0x48,
11825 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
11826 0xdb, 0x10, 0x11, 0xfe,
11827 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0,
11828 0x22, 0x30, 0x2e, 0xd8,
11829 0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1,
11830 0x45, 0x0f, 0xfe, 0x42,
11831 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
11832 0x09, 0x04, 0x0b, 0xfe,
11833 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28,
11834 0x00, 0x21, 0xfe, 0xa6,
11835 0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00,
11836 0xfe, 0xe2, 0x10, 0x01,
11837 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
11838 0x01, 0x6f, 0x02, 0x29,
11839 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10,
11840 0x01, 0x86, 0x3e, 0x0b,
11841 0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3,
11842 0x3e, 0x0b, 0x0f, 0xfe,
11843 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
11844 0xe8, 0x59, 0x11, 0x2d,
11845 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09,
11846 0x04, 0x0b, 0x84, 0x3e,
11847 0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12,
11848 0x09, 0x04, 0x1b, 0xfe,
11849 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
11850 0x1c, 0x1c, 0xfe, 0x9d,
11851 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f,
11852 0xfe, 0x15, 0x00, 0xfe,
11853 0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10,
11854 0x0f, 0xfe, 0x47, 0x00,
11855 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
11856 0xab, 0x70, 0x05, 0x6b,
11857 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe,
11858 0x1c, 0x42, 0x59, 0x01,
11859 0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31,
11860 0x00, 0x37, 0x97, 0x01,
11861 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
11862 0x1d, 0xfe, 0xce, 0x45,
11863 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75,
11864 0x57, 0x05, 0x51, 0xfe,
11865 0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48,
11866 0x46, 0x09, 0x04, 0x1d,
11867 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
11868 0x99, 0x01, 0x0e, 0xfe,
11869 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51,
11870 0xfe, 0xee, 0x14, 0xee,
11871 0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad,
11872 0x13, 0x02, 0x29, 0x1e,
11873 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
11874 0xce, 0x1e, 0x2d, 0x47,
11875 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06,
11876 0x12, 0x4d, 0x01, 0xfe,
11877 0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe,
11878 0xf0, 0x0d, 0xfe, 0x02,
11879 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
11880 0xf6, 0xfe, 0x34, 0x01,
11881 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13,
11882 0xaf, 0xfe, 0x02, 0xea,
11883 0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c,
11884 0x05, 0xfe, 0x38, 0x01,
11885 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
11886 0x0c, 0xfe, 0x62, 0x01,
11887 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06,
11888 0x03, 0x23, 0x03, 0x1e,
11889 0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe,
11890 0x71, 0x13, 0xfe, 0x24,
11891 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
11892 0xdc, 0xfe, 0x73, 0x57,
11893 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe,
11894 0x80, 0x5d, 0x03, 0xfe,
11895 0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6,
11896 0x75, 0x03, 0x09, 0x04,
11897 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
11898 0xfe, 0x1e, 0x80, 0xe1,
11899 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e,
11900 0x90, 0xa3, 0xfe, 0x3c,
11901 0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82,
11902 0x16, 0x2f, 0x07, 0x2d,
11903 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
11904 0xe8, 0x11, 0xfe, 0xe9,
11905 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe,
11906 0x1e, 0x1c, 0xfe, 0x14,
11907 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01,
11908 0x09, 0x04, 0x4f, 0xfe,
11909 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
11910 0x40, 0x12, 0x20, 0x63,
11911 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08,
11912 0x1c, 0x05, 0xfe, 0xac,
11913 0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05,
11914 0xfe, 0xb0, 0x00, 0xfe,
11915 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
11916 0x24, 0x69, 0x12, 0xc9,
11917 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe,
11918 0x90, 0x4d, 0xfe, 0x91,
11919 0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c,
11920 0xfe, 0x90, 0x4d, 0xfe,
11921 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
11922 0x46, 0x1e, 0x20, 0xed,
11923 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea,
11924 0x70, 0xfe, 0x14, 0x1c,
11925 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee,
11926 0xfe, 0x07, 0xe6, 0x1d,
11927 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
11928 0xfa, 0xef, 0xfe, 0x42,
11929 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0,
11930 0xfe, 0x36, 0x12, 0xf0,
11931 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
11932 0x3d, 0x75, 0x07, 0x10,
11933 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
11934 0x10, 0x07, 0x7e, 0x45,
11935 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74,
11936 0xfe, 0x01, 0xec, 0x97,
11937 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76,
11938 0x27, 0x01, 0xda, 0xfe,
11939 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
11940 0xfe, 0x48, 0x12, 0x07,
11941 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16,
11942 0xfe, 0x3e, 0x11, 0x07,
11943 0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8,
11944 0x11, 0x07, 0x19, 0xfe,
11945 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
11946 0x01, 0x08, 0x8c, 0x43,
11947 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11,
11948 0x7e, 0x02, 0x29, 0x2b,
11949 0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe,
11950 0xfc, 0x10, 0x09, 0x04,
11951 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
11952 0xc6, 0x10, 0x1e, 0x58,
11953 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c,
11954 0x54, 0x18, 0x55, 0x23,
11955 0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01,
11956 0xa5, 0xc0, 0x38, 0xc1,
11957 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
11958 0x05, 0xfa, 0x4e, 0xfe,
11959 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56,
11960 0x0c, 0x56, 0x18, 0x57,
11961 0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe,
11962 0x00, 0x56, 0xfe, 0xa1,
11963 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
11964 0x58, 0xfe, 0x1f, 0x40,
11965 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56,
11966 0x31, 0x57, 0xfe, 0x44,
11967 0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe,
11968 0x8a, 0x50, 0x05, 0x39,
11969 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
11970 0x12, 0xcd, 0x02, 0x5b,
11971 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44,
11972 0x2f, 0x07, 0x9b, 0x21,
11973 0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79,
11974 0x39, 0x68, 0x3a, 0xfe,
11975 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
11976 0x51, 0xfe, 0x8e, 0x51,
11977 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b,
11978 0x01, 0x08, 0x25, 0x32,
11979 0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b,
11980 0x3b, 0x02, 0x44, 0x01,
11981 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
11982 0x01, 0x08, 0x1f, 0xa2,
11983 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c,
11984 0x00, 0x28, 0x84, 0x49,
11985 0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06,
11986 0x78, 0x3d, 0xfe, 0xda,
11987 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
11988 0x05, 0xc6, 0x28, 0x84,
11989 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8,
11990 0x14, 0xfe, 0x03, 0x17,
11991 0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01,
11992 0xfe, 0xaa, 0x14, 0x02,
11993 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
11994 0x21, 0x44, 0x01, 0xfe,
11995 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87,
11996 0xfe, 0x4a, 0xf4, 0x0b,
11997 0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a,
11998 0x85, 0x02, 0x5b, 0x05,
11999 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
12000 0xd8, 0x14, 0x02, 0x5c,
12001 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1,
12002 0x01, 0x08, 0x23, 0x72,
12003 0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca,
12004 0x12, 0x5e, 0x2b, 0x01,
12005 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
12006 0x1c, 0xfe, 0xff, 0x7f,
12007 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00,
12008 0x57, 0x48, 0x8b, 0x1c,
12009 0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02,
12010 0x00, 0x57, 0x48, 0x8b,
12011 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
12012 0x03, 0x0a, 0x50, 0x01,
12013 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00,
12014 0x54, 0xfe, 0x00, 0xf4,
12015 0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe,
12016 0x03, 0x7c, 0x63, 0x27,
12017 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
12018 0xfe, 0x82, 0x4a, 0xfe,
12019 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe,
12020 0x42, 0x48, 0x5f, 0x60,
12021 0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08,
12022 0x1f, 0xfe, 0xa2, 0x14,
12023 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
12024 0xcc, 0x12, 0x49, 0x04,
12025 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe,
12026 0xe8, 0x13, 0x3b, 0x13,
12027 0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55,
12028 0xa1, 0xff, 0x02, 0x83,
12029 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
12030 0x13, 0x06, 0xfe, 0x56,
12031 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe,
12032 0x64, 0x00, 0x17, 0x93,
12033 0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe,
12034 0xc8, 0x00, 0x8e, 0xe4,
12035 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
12036 0x01, 0xba, 0xfe, 0x4e,
12037 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0,
12038 0xfe, 0x60, 0x14, 0xfe,
12039 0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01,
12040 0xfe, 0x22, 0x13, 0x1c,
12041 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
12042 0xfe, 0x9c, 0x14, 0xb7,
12043 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba,
12044 0xfe, 0x9c, 0x14, 0xb7,
12045 0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06,
12046 0xfe, 0xb4, 0x56, 0xfe,
12047 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
12048 0xe5, 0x15, 0x0b, 0x01,
12049 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89,
12050 0x49, 0x01, 0x08, 0x03,
12051 0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6,
12052 0x15, 0x06, 0x01, 0x08,
12053 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
12054 0x4a, 0x01, 0x08, 0x03,
12055 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc,
12056 0xfe, 0x49, 0xf4, 0x00,
12057 0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01,
12058 0x08, 0x2f, 0x07, 0xfe,
12059 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
12060 0x01, 0x43, 0x1e, 0xcd,
12061 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e,
12062 0xed, 0x88, 0x07, 0x10,
12063 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a,
12064 0x80, 0x01, 0x0e, 0x88,
12065 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
12066 0x88, 0x03, 0x0a, 0x42,
12067 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e,
12068 0xfe, 0x80, 0x80, 0xf2,
12069 0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51,
12070 0x01, 0x82, 0x03, 0x17,
12071 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
12072 0xfe, 0x24, 0x1c, 0xfe,
12073 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0,
12074 0x91, 0x1d, 0x66, 0xfe,
12075 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe,
12076 0xda, 0x10, 0x17, 0x10,
12077 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
12078 0x05, 0xfe, 0x66, 0x01,
12079 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06,
12080 0xfe, 0x3c, 0x50, 0x66,
12081 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe,
12082 0x40, 0x16, 0xfe, 0xb6,
12083 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
12084 0x10, 0x71, 0xfe, 0x83,
12085 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90,
12086 0xfe, 0x62, 0x16, 0xfe,
12087 0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19,
12088 0xfe, 0x98, 0xe7, 0x00,
12089 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
12090 0xfe, 0x30, 0xbc, 0xfe,
12091 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
12092 0xc5, 0x90, 0xfe, 0x9a,
12093 0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe,
12094 0x42, 0x10, 0xfe, 0x02,
12095 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
12096 0xfe, 0x1d, 0xf7, 0x4f,
12097 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f,
12098 0x47, 0xfe, 0x83, 0x58,
12099 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11,
12100 0xfe, 0xdd, 0x00, 0x63,
12101 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
12102 0x06, 0x37, 0x95, 0xa9,
12103 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e,
12104 0x18, 0x1c, 0x1a, 0x5d,
12105 0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe,
12106 0xe1, 0x10, 0x78, 0x2c,
12107 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
12108 0x13, 0x3c, 0x8a, 0x0a,
12109 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
12110 0xe3, 0xfe, 0x00, 0xcc,
12111 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01,
12112 0x0e, 0xf2, 0x01, 0x6f,
12113 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
12114 0xf6, 0xfe, 0xd6, 0xf0,
12115 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe,
12116 0x15, 0x00, 0x59, 0x76,
12117 0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35,
12118 0x11, 0x2d, 0x01, 0x6f,
12119 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
12120 0xc8, 0xfe, 0x48, 0x55,
12121 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a,
12122 0x99, 0x01, 0x0e, 0xf0,
12123 0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73,
12124 0x75, 0x03, 0x0a, 0x42,
12125 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
12126 0x0e, 0x73, 0x75, 0x03,
12127 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00,
12128 0xfe, 0x3a, 0x45, 0x5b,
12129 0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00,
12130 0xfe, 0x02, 0xe6, 0x1b,
12131 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
12132 0xfe, 0x94, 0x00, 0xfe,
12133 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02,
12134 0xe6, 0x2c, 0xfe, 0x4e,
12135 0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69,
12136 0x03, 0x07, 0x7a, 0xfe,
12137 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
12138 0x07, 0x1b, 0xfe, 0x5a,
12139 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d,
12140 0x24, 0x2c, 0xdc, 0x07,
12141 0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d,
12142 0x9f, 0xad, 0x03, 0x14,
12143 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
12144 0x03, 0x25, 0xfe, 0xca,
12145 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a,
12146 0x00, 0x00,
12149 static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
12150 static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
12152 /* Microcode buffer is kept after initialization for error recovery. */
12153 static unsigned char _adv_asc38C0800_buf[] = {
12154 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
12155 0x01, 0x00, 0x48, 0xe4,
12156 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff,
12157 0x1c, 0x0f, 0x00, 0xf6,
12158 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6,
12159 0x09, 0xe7, 0x55, 0xf0,
12160 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
12161 0x18, 0xf4, 0x08, 0x00,
12162 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6,
12163 0x86, 0xf0, 0xb1, 0xf0,
12164 0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c,
12165 0x3c, 0x00, 0xbb, 0x00,
12166 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
12167 0xba, 0x13, 0x18, 0x40,
12168 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01,
12169 0x6e, 0x01, 0x74, 0x01,
12170 0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00,
12171 0xc0, 0x00, 0x01, 0x01,
12172 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
12173 0x08, 0x12, 0x02, 0x4a,
12174 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4,
12175 0x5d, 0xf0, 0x02, 0xfa,
12176 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01,
12177 0x68, 0x01, 0x6a, 0x01,
12178 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
12179 0x06, 0x13, 0x4c, 0x1c,
12180 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00,
12181 0x0f, 0x00, 0x47, 0x00,
12182 0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c,
12183 0x4e, 0x1c, 0x10, 0x44,
12184 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
12185 0x05, 0x00, 0x34, 0x00,
12186 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b,
12187 0x42, 0x0c, 0x12, 0x0f,
12188 0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48,
12189 0x00, 0x4e, 0x42, 0x54,
12190 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
12191 0x59, 0xf0, 0xb8, 0xf0,
12192 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00,
12193 0x19, 0x00, 0x33, 0x00,
12194 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00,
12195 0xe7, 0x00, 0xe2, 0x03,
12196 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
12197 0x12, 0x13, 0x24, 0x14,
12198 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c,
12199 0x36, 0x1c, 0x08, 0x44,
12200 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54,
12201 0x3a, 0x55, 0x83, 0x55,
12202 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
12203 0x0c, 0xf0, 0x04, 0xf8,
12204 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00,
12205 0xa8, 0x00, 0xaa, 0x00,
12206 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01,
12207 0xc4, 0x01, 0xc6, 0x01,
12208 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
12209 0x68, 0x08, 0x69, 0x08,
12210 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10,
12211 0xed, 0x10, 0xf1, 0x10,
12212 0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13,
12213 0x1e, 0x13, 0x46, 0x14,
12214 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
12215 0xca, 0x18, 0xe6, 0x19,
12216 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c,
12217 0xf0, 0x2b, 0x02, 0xfe,
12218 0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6,
12219 0xfe, 0x84, 0x01, 0xff,
12220 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
12221 0x00, 0xfe, 0x57, 0x24,
12222 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09,
12223 0x00, 0x00, 0xff, 0x08,
12224 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
12225 0xff, 0xff, 0xff, 0x11,
12226 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
12227 0xfe, 0x04, 0xf7, 0xd6,
12228 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99,
12229 0x0a, 0x42, 0x2c, 0xfe,
12230 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0,
12231 0xfe, 0xf4, 0x01, 0xfe,
12232 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
12233 0x02, 0xfe, 0xc8, 0x0d,
12234 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
12235 0x1c, 0x03, 0xfe, 0xa6,
12236 0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48,
12237 0xf0, 0xfe, 0x8a, 0x02,
12238 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
12239 0xfe, 0x46, 0xf0, 0xfe,
12240 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
12241 0x48, 0x02, 0xfe, 0x44,
12242 0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a,
12243 0xaa, 0x18, 0x06, 0x14,
12244 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
12245 0x1e, 0x1c, 0xfe, 0xe9,
12246 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce,
12247 0x09, 0x70, 0x01, 0xa8,
12248 0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70,
12249 0x01, 0x87, 0xfe, 0xbd,
12250 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
12251 0x58, 0x1c, 0x18, 0x06,
12252 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23,
12253 0xfe, 0x98, 0x02, 0xfe,
12254 0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2,
12255 0x01, 0xfe, 0x48, 0x10,
12256 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
12257 0x69, 0x10, 0x18, 0x06,
12258 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05,
12259 0xf6, 0xce, 0x01, 0xfe,
12260 0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe,
12261 0x82, 0x16, 0x02, 0x2b,
12262 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
12263 0xfe, 0x41, 0x58, 0x09,
12264 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe,
12265 0x82, 0x16, 0x02, 0x2b,
12266 0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43,
12267 0xfe, 0x77, 0x57, 0xfe,
12268 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
12269 0xfe, 0x40, 0x1c, 0x1c,
12270 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48,
12271 0x03, 0xfe, 0x11, 0xf0,
12272 0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10,
12273 0xfe, 0x11, 0x00, 0x02,
12274 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
12275 0x21, 0x22, 0xa3, 0xb7,
12276 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16,
12277 0x12, 0xd1, 0x1c, 0xd9,
12278 0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12,
12279 0xfe, 0xe4, 0x00, 0x27,
12280 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
12281 0x06, 0xf0, 0xfe, 0xc8,
12282 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03,
12283 0x70, 0x28, 0x17, 0xfe,
12284 0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8,
12285 0xf9, 0x2c, 0x99, 0x19,
12286 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
12287 0x74, 0x01, 0xaf, 0x8c,
12288 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e,
12289 0x8d, 0x51, 0x64, 0x79,
12290 0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b,
12291 0xfe, 0x6a, 0x02, 0x02,
12292 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
12293 0xfe, 0x3c, 0x04, 0x3b,
12294 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02,
12295 0x00, 0x10, 0x01, 0x0b,
12296 0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde,
12297 0xfe, 0x4c, 0x44, 0xfe,
12298 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
12299 0xda, 0x4f, 0x79, 0x2a,
12300 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b,
12301 0xfe, 0x2a, 0x13, 0x32,
12302 0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c,
12303 0x54, 0x6b, 0xda, 0xfe,
12304 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
12305 0x08, 0x13, 0x32, 0x07,
12306 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d,
12307 0x08, 0x05, 0x06, 0x4d,
12308 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24,
12309 0x2d, 0x12, 0xfe, 0xe6,
12310 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
12311 0x02, 0x2b, 0xfe, 0x42,
12312 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
12313 0xfe, 0x87, 0x80, 0xfe,
12314 0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80,
12315 0x07, 0x19, 0xfe, 0x7c,
12316 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
12317 0x17, 0xfe, 0x90, 0x05,
12318 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe,
12319 0xa0, 0x00, 0x28, 0xfe,
12320 0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c,
12321 0x34, 0xfe, 0x89, 0x48,
12322 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
12323 0x12, 0xfe, 0xe3, 0x00,
12324 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
12325 0x70, 0x05, 0x88, 0x25,
12326 0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe,
12327 0x09, 0x48, 0xff, 0x02,
12328 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
12329 0x08, 0x53, 0x05, 0xcb,
12330 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08,
12331 0x05, 0x1b, 0xfe, 0x22,
12332 0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe,
12333 0x0d, 0x00, 0x01, 0x36,
12334 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
12335 0x03, 0x5c, 0x28, 0xfe,
12336 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53,
12337 0x05, 0x1f, 0xfe, 0x02,
12338 0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5,
12339 0x01, 0x4b, 0x12, 0xfe,
12340 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
12341 0x12, 0x03, 0x45, 0x28,
12342 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe,
12343 0x43, 0x48, 0xc4, 0xcc,
12344 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4,
12345 0x6e, 0x41, 0x01, 0xb2,
12346 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
12347 0xfe, 0xcc, 0x15, 0x1d,
12348 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03,
12349 0x45, 0xc1, 0x0c, 0x45,
12350 0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe,
12351 0xe2, 0x00, 0x27, 0xdb,
12352 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
12353 0xfe, 0x06, 0xf0, 0xfe,
12354 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12,
12355 0x16, 0x19, 0x01, 0x0b,
12356 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
12357 0xfe, 0x99, 0xa4, 0x01,
12358 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
12359 0x12, 0x08, 0x05, 0x1a,
12360 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
12361 0x0b, 0x16, 0x00, 0x01,
12362 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02,
12363 0xe2, 0x6c, 0x58, 0xbe,
12364 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
12365 0xfe, 0x09, 0x6f, 0xba,
12366 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27,
12367 0xfe, 0x54, 0x07, 0x1c,
12368 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c,
12369 0x07, 0x02, 0x24, 0x01,
12370 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
12371 0x2c, 0x90, 0xfe, 0xae,
12372 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a,
12373 0x37, 0x22, 0x20, 0x07,
12374 0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a,
12375 0xfe, 0x06, 0x10, 0xfe,
12376 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
12377 0x37, 0x01, 0xb3, 0xb8,
12378 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a,
12379 0x50, 0xfe, 0x44, 0x51,
12380 0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e,
12381 0x14, 0x5f, 0xfe, 0x0c,
12382 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
12383 0x14, 0x3e, 0xfe, 0x4a,
12384 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
12385 0x90, 0x0c, 0x60, 0x14,
12386 0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62,
12387 0xfe, 0x44, 0x90, 0xfe,
12388 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
12389 0x0c, 0x5e, 0x14, 0x5f,
12390 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e,
12391 0x14, 0x3c, 0x21, 0x0c,
12392 0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11,
12393 0x27, 0xdd, 0xfe, 0x9e,
12394 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
12395 0x9a, 0x08, 0xc6, 0xfe,
12396 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08,
12397 0x95, 0x86, 0x02, 0x24,
12398 0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05,
12399 0x06, 0xfe, 0x10, 0x12,
12400 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
12401 0x1c, 0x02, 0xfe, 0x18,
12402 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe,
12403 0x2c, 0x1c, 0xfe, 0xaa,
12404 0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe,
12405 0xde, 0x09, 0xfe, 0xb7,
12406 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
12407 0xfe, 0xf1, 0x18, 0xfe,
12408 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe,
12409 0x14, 0x59, 0xfe, 0x95,
12410 0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0,
12411 0xfe, 0xf0, 0x08, 0xb5,
12412 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
12413 0x0b, 0xb6, 0xfe, 0xbf,
12414 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c,
12415 0x12, 0xc2, 0xfe, 0xd2,
12416 0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e,
12417 0x06, 0x17, 0x85, 0xc5,
12418 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
12419 0x9d, 0x01, 0x36, 0x10,
12420 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe,
12421 0x98, 0x80, 0xfe, 0x19,
12422 0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18,
12423 0xfe, 0x44, 0x54, 0xbe,
12424 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
12425 0x02, 0x4a, 0x08, 0x05,
12426 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e,
12427 0x9c, 0x3c, 0xfe, 0x6c,
12428 0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f,
12429 0x3b, 0x40, 0x03, 0x49,
12430 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
12431 0x8f, 0xfe, 0xe3, 0x54,
12432 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe,
12433 0xda, 0x09, 0xfe, 0x8b,
12434 0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa,
12435 0x0a, 0x3a, 0x49, 0x3b,
12436 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
12437 0xad, 0xfe, 0x01, 0x59,
12438 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a,
12439 0x49, 0x8f, 0xfe, 0xe3,
12440 0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02,
12441 0x4a, 0x3a, 0x49, 0x3b,
12442 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
12443 0x02, 0x4a, 0x08, 0x05,
12444 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62,
12445 0xb7, 0xfe, 0x03, 0xa1,
12446 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
12447 0xfe, 0x86, 0x91, 0x6a,
12448 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
12449 0x61, 0x0c, 0x7f, 0x14,
12450 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62,
12451 0x9b, 0x2e, 0x9c, 0x3c,
12452 0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05,
12453 0xfa, 0x3c, 0x01, 0xef,
12454 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
12455 0xe4, 0x08, 0x05, 0x1f,
12456 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37,
12457 0x03, 0x5e, 0x29, 0x5f,
12458 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe,
12459 0xf4, 0x09, 0x08, 0x05,
12460 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
12461 0x81, 0x50, 0xfe, 0x10,
12462 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe,
12463 0x08, 0x09, 0x12, 0xa6,
12464 0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe,
12465 0x08, 0x09, 0xfe, 0x0c,
12466 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
12467 0x08, 0x05, 0x0a, 0xfe,
12468 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1,
12469 0xf0, 0xe2, 0x15, 0x7e,
12470 0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19,
12471 0x57, 0x3d, 0xfe, 0xed,
12472 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
12473 0x00, 0xff, 0x35, 0xfe,
12474 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18,
12475 0x1e, 0x19, 0x8a, 0x03,
12476 0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65,
12477 0xfe, 0xd1, 0xf0, 0xfe,
12478 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
12479 0x10, 0xfe, 0xce, 0xf0,
12480 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b,
12481 0x10, 0xfe, 0x22, 0x00,
12482 0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00,
12483 0x02, 0x65, 0xfe, 0xd0,
12484 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
12485 0x0b, 0x10, 0x58, 0xfe,
12486 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe,
12487 0x12, 0x00, 0x2c, 0x0f,
12488 0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14,
12489 0x0c, 0xbc, 0x17, 0x34,
12490 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
12491 0x0c, 0x1c, 0x34, 0x94,
12492 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01,
12493 0x4b, 0xfe, 0xdb, 0x10,
12494 0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe,
12495 0x89, 0xf0, 0x24, 0x33,
12496 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
12497 0x33, 0x31, 0xdf, 0xbc,
12498 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49,
12499 0x17, 0xfe, 0x2c, 0x0d,
12500 0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54,
12501 0x12, 0x55, 0xfe, 0x28,
12502 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
12503 0x44, 0xfe, 0x28, 0x00,
12504 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26,
12505 0x0f, 0x64, 0x12, 0x2f,
12506 0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44,
12507 0x0a, 0xfe, 0xb4, 0x10,
12508 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
12509 0xfe, 0x34, 0x46, 0xac,
12510 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a,
12511 0x37, 0x01, 0xf5, 0x01,
12512 0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02,
12513 0xfe, 0x2e, 0x03, 0x08,
12514 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
12515 0x1a, 0xfe, 0x58, 0x12,
12516 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
12517 0xfe, 0x50, 0x0d, 0xfe,
12518 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37,
12519 0xfe, 0xa9, 0x10, 0x10,
12520 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
12521 0xfe, 0x13, 0x00, 0xfe,
12522 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe,
12523 0x24, 0x00, 0x8c, 0xb5,
12524 0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a,
12525 0xfe, 0x9d, 0x41, 0xfe,
12526 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
12527 0xb4, 0x15, 0xfe, 0x31,
12528 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06,
12529 0xec, 0xd0, 0xfc, 0x44,
12530 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47,
12531 0x4b, 0x91, 0xfe, 0x75,
12532 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
12533 0x0e, 0xfe, 0x44, 0x48,
12534 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41,
12535 0xfe, 0x41, 0x58, 0x09,
12536 0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe,
12537 0x2e, 0x03, 0x09, 0x5d,
12538 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
12539 0xce, 0x47, 0xfe, 0xad,
12540 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13,
12541 0x59, 0x13, 0x9f, 0x13,
12542 0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe,
12543 0xe0, 0x0e, 0x0f, 0x06,
12544 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
12545 0x3a, 0x01, 0x56, 0xfe,
12546 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec,
12547 0x20, 0x4f, 0xfe, 0x05,
12548 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe,
12549 0x48, 0xf4, 0x0d, 0xfe,
12550 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
12551 0x15, 0x1a, 0x39, 0xa0,
12552 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff,
12553 0x0c, 0xfe, 0x60, 0x01,
12554 0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25,
12555 0x06, 0x13, 0x2f, 0x12,
12556 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
12557 0x22, 0x9f, 0xb7, 0x13,
12558 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39,
12559 0xa0, 0xb4, 0xfe, 0xd9,
12560 0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04,
12561 0xc3, 0xfe, 0x03, 0xdc,
12562 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
12563 0xfe, 0x00, 0xcc, 0x04,
12564 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13,
12565 0xfe, 0x1c, 0x80, 0x07,
12566 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae,
12567 0xfe, 0x0c, 0x90, 0xfe,
12568 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
12569 0x0a, 0xfe, 0x3c, 0x50,
12570 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4,
12571 0x16, 0x08, 0x05, 0x1b,
12572 0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58,
12573 0xfe, 0x2c, 0x13, 0x01,
12574 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
12575 0x0c, 0xfe, 0x64, 0x01,
12576 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03,
12577 0x80, 0x8d, 0xfe, 0x01,
12578 0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64,
12579 0x22, 0x20, 0xfb, 0x79,
12580 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
12581 0x03, 0xfe, 0xae, 0x00,
12583 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe,
12584 0xb2, 0x00, 0xfe, 0x09,
12585 0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c,
12586 0x45, 0x0f, 0x46, 0x52,
12587 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
12588 0x0f, 0x44, 0x11, 0x0f,
12589 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4,
12590 0x25, 0x11, 0x13, 0x20,
12591 0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14,
12592 0x56, 0xfe, 0xd6, 0xf0,
12593 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
12594 0x18, 0x1c, 0x04, 0x42,
12595 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe,
12596 0xf5, 0x13, 0x04, 0x01,
12597 0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
12598 0x13, 0x32, 0x07, 0x2f,
12599 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
12600 0x41, 0x48, 0xfe, 0x45,
12601 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78,
12602 0x07, 0x11, 0xac, 0x09,
12603 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07,
12604 0x82, 0x4e, 0xfe, 0x14,
12605 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
12606 0xfe, 0x01, 0xec, 0xa2,
12607 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79,
12608 0x2a, 0x01, 0xe3, 0xfe,
12609 0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a,
12610 0xfe, 0x48, 0x12, 0x07,
12611 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
12612 0xfe, 0x32, 0x12, 0x07,
12613 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07,
12614 0x1f, 0xfe, 0x12, 0x12,
12615 0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b,
12616 0x94, 0x4b, 0x04, 0x2d,
12617 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
12618 0x32, 0x07, 0xa6, 0xfe,
12619 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05,
12620 0x5a, 0xfe, 0x72, 0x12,
12621 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62,
12622 0xfe, 0x26, 0x13, 0x03,
12623 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
12624 0x0c, 0x7f, 0x0c, 0x80,
12625 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c,
12626 0x3c, 0xfe, 0x04, 0x55,
12627 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe,
12628 0x91, 0x10, 0x03, 0x3f,
12629 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
12630 0x88, 0x9b, 0x2e, 0x9c,
12631 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
12632 0x56, 0x0c, 0x5e, 0x14,
12633 0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40,
12634 0x03, 0x60, 0x29, 0x61,
12635 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
12636 0x50, 0xfe, 0xc6, 0x50,
12637 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d,
12638 0x29, 0x3e, 0xfe, 0x40,
12639 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72,
12640 0x2d, 0x01, 0x0b, 0x1d,
12641 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
12642 0x72, 0x01, 0xaf, 0x1e,
12643 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe,
12644 0x0a, 0x55, 0x35, 0xfe,
12645 0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51,
12646 0x02, 0x72, 0xfe, 0x19,
12647 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
12648 0x1d, 0xe8, 0x33, 0x31,
12649 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01,
12650 0x0b, 0x1c, 0x34, 0x1d,
12651 0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8,
12652 0x33, 0x31, 0xfe, 0xe8,
12653 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
12654 0x05, 0x1f, 0x35, 0xa9,
12655 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda,
12656 0x14, 0x01, 0xaf, 0x8c,
12657 0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a,
12658 0x03, 0x45, 0x28, 0x35,
12659 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
12660 0x03, 0x5c, 0xc1, 0x0c,
12661 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02,
12662 0x89, 0x01, 0x0b, 0x1c,
12663 0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1,
12664 0xfe, 0x42, 0x58, 0xf1,
12665 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
12666 0xf4, 0x06, 0xea, 0x32,
12667 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d,
12668 0x01, 0x0b, 0x26, 0x89,
12669 0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13,
12670 0x26, 0xfe, 0xd4, 0x13,
12671 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
12672 0x13, 0x1c, 0xfe, 0xd0,
12673 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10,
12674 0x0f, 0x71, 0xff, 0x02,
12675 0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe,
12676 0x00, 0x5c, 0x04, 0x0f,
12677 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
12678 0xfe, 0x00, 0x5c, 0x04,
12679 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff,
12680 0x02, 0x00, 0x57, 0x52,
12681 0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01,
12682 0x87, 0x04, 0xfe, 0x03,
12683 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
12684 0xfe, 0x00, 0x7d, 0xfe,
12685 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e,
12686 0x14, 0x5f, 0x57, 0x3f,
12687 0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83,
12688 0x5a, 0x8d, 0x04, 0x01,
12689 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
12690 0xfe, 0x96, 0x15, 0x33,
12691 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8,
12692 0x0a, 0xfe, 0xc1, 0x59,
12693 0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13,
12694 0x21, 0x69, 0x1a, 0xee,
12695 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
12696 0x30, 0xfe, 0x78, 0x10,
12697 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae,
12698 0x98, 0xfe, 0x30, 0x00,
12699 0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed,
12700 0x98, 0xfe, 0x64, 0x00,
12701 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
12702 0x10, 0x69, 0x06, 0xfe,
12703 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00,
12704 0x18, 0x59, 0x0f, 0x06,
12705 0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe,
12706 0x43, 0xf4, 0x9f, 0xfe,
12707 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
12708 0x9e, 0xfe, 0xf3, 0x10,
12709 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00,
12710 0x17, 0xfe, 0x4d, 0xe4,
12711 0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00,
12712 0x17, 0xfe, 0x4d, 0xe4,
12713 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
12714 0xf4, 0x00, 0xe9, 0x91,
12715 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a,
12716 0x04, 0x16, 0x06, 0x01,
12717 0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01,
12718 0x0b, 0x26, 0xf3, 0x76,
12719 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
12720 0x16, 0x19, 0x01, 0x0b,
12721 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01,
12722 0x0b, 0x26, 0xb1, 0x76,
12723 0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06,
12724 0xfe, 0x48, 0x13, 0xb8,
12725 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
12726 0xec, 0xfe, 0x27, 0x01,
12727 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32,
12728 0x07, 0xfe, 0xe3, 0x00,
12729 0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b,
12730 0x22, 0xd4, 0x07, 0x06,
12731 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
12732 0x07, 0x11, 0xae, 0x09,
12733 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01,
12734 0x0e, 0x8e, 0xfe, 0x80,
12735 0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04,
12736 0x09, 0x48, 0x01, 0x0e,
12737 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
12738 0x80, 0xfe, 0x80, 0x4c,
12739 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c,
12740 0x09, 0x5d, 0x01, 0x87,
12741 0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe,
12742 0x19, 0xde, 0xfe, 0x24,
12743 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
12744 0x17, 0xad, 0x9a, 0x1b,
12745 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde,
12746 0x16, 0xfe, 0xda, 0x10,
12747 0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe,
12748 0x18, 0x58, 0x03, 0xfe,
12749 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
12750 0xf4, 0x06, 0xfe, 0x3c,
12751 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f,
12752 0x97, 0xfe, 0x38, 0x17,
12753 0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c,
12754 0x10, 0x18, 0x11, 0x75,
12755 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
12756 0x2e, 0x97, 0xfe, 0x5a,
12757 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19,
12758 0xfe, 0x98, 0xe7, 0x00,
12759 0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75,
12760 0xfe, 0x30, 0xbc, 0xfe,
12761 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
12762 0xcb, 0x97, 0xfe, 0x92,
12763 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe,
12764 0x42, 0x10, 0xfe, 0x02,
12765 0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe,
12766 0x03, 0xa1, 0xfe, 0x1d,
12767 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
12768 0x9a, 0x5b, 0x41, 0xfe,
12769 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7,
12770 0x11, 0x12, 0xfe, 0xdd,
12771 0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8,
12772 0x17, 0x15, 0x06, 0x39,
12773 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
12774 0xfe, 0x7e, 0x18, 0x1e,
12775 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef,
12776 0x12, 0xfe, 0xe1, 0x10,
12777 0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42,
12778 0x13, 0x42, 0x92, 0x09,
12779 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
12780 0xf0, 0xfe, 0x00, 0xcc,
12781 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01,
12782 0x0e, 0xfe, 0x80, 0x4c,
12783 0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe,
12784 0x24, 0x12, 0xfe, 0x14,
12785 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
12786 0xe7, 0x0a, 0x10, 0xfe,
12787 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92,
12788 0x08, 0x54, 0x1b, 0x37,
12789 0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba,
12790 0x90, 0x3a, 0xce, 0x3b,
12791 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
12792 0x13, 0xa3, 0x04, 0x09,
12793 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49,
12794 0x44, 0x17, 0xfe, 0xe8,
12795 0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09,
12796 0x5d, 0x01, 0xa8, 0x09,
12797 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
12798 0x1c, 0x19, 0x03, 0xfe,
12799 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9,
12800 0x6b, 0xfe, 0x2e, 0x19,
12801 0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4,
12802 0xfe, 0x0b, 0x00, 0x6b,
12803 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
12804 0x08, 0x10, 0x03, 0xfe,
12805 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff,
12806 0x04, 0x68, 0x54, 0xe7,
12807 0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe,
12808 0x1a, 0xf4, 0xfe, 0x00,
12809 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
12810 0x04, 0x07, 0x7e, 0xfe,
12811 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
12812 0x07, 0x1a, 0xfe, 0x5a,
12813 0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66,
12814 0x25, 0x6d, 0xe5, 0x07,
12815 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
12816 0xa9, 0xb8, 0x04, 0x15,
12817 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe,
12818 0x40, 0x5c, 0x04, 0x1c,
12819 0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b,
12820 0xf7, 0xfe, 0x82, 0xf0,
12821 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
12824 static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
12825 static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
12827 /* Microcode buffer is kept after initialization for error recovery. */
12828 static unsigned char _adv_asc38C1600_buf[] = {
12829 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
12830 0x18, 0xe4, 0x01, 0x00,
12831 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00,
12832 0x07, 0x17, 0xc0, 0x5f,
12833 0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7,
12834 0x85, 0xf0, 0x86, 0xf0,
12835 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
12836 0x98, 0x57, 0x01, 0xe6,
12837 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d,
12838 0x38, 0x54, 0x32, 0xf0,
12839 0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4,
12840 0x00, 0xe6, 0xb1, 0xf0,
12841 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
12842 0x06, 0x13, 0x0c, 0x1c,
12843 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12,
12844 0xb9, 0x54, 0x00, 0x80,
12845 0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56,
12846 0x03, 0xe6, 0x01, 0xea,
12847 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
12848 0x04, 0x13, 0xbb, 0x55,
12849 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00,
12850 0xbb, 0x00, 0xc0, 0x00,
12851 0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12,
12852 0x4c, 0x1c, 0x4e, 0x1c,
12853 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
12854 0x24, 0x01, 0x3c, 0x01,
12855 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01,
12856 0x78, 0x01, 0x7c, 0x01,
12857 0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c,
12858 0x6e, 0x1e, 0x02, 0x48,
12859 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
12860 0x03, 0xfc, 0x06, 0x00,
12861 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a,
12862 0x30, 0x1c, 0x38, 0x1c,
12863 0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea,
12864 0x5d, 0xf0, 0xa7, 0xf0,
12865 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
12866 0x33, 0x00, 0x34, 0x00,
12867 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01,
12868 0x79, 0x01, 0x3c, 0x09,
12869 0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13,
12870 0x40, 0x16, 0x50, 0x16,
12871 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
12872 0x05, 0xf0, 0x09, 0xf0,
12873 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00,
12874 0x9c, 0x00, 0xa4, 0x00,
12875 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08,
12876 0xe9, 0x09, 0x5c, 0x0c,
12877 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
12878 0x42, 0x1d, 0x08, 0x44,
12879 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54,
12880 0x83, 0x55, 0x83, 0x59,
12881 0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0,
12882 0x4b, 0xf4, 0x04, 0xf8,
12883 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
12884 0xa8, 0x00, 0xaa, 0x00,
12885 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01,
12886 0x7a, 0x01, 0x82, 0x01,
12887 0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07,
12888 0x68, 0x08, 0x10, 0x0d,
12889 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
12890 0xf3, 0x10, 0x06, 0x12,
12891 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c,
12892 0xf0, 0x35, 0x05, 0xfe,
12893 0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8,
12894 0xfe, 0x88, 0x01, 0xff,
12895 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
12896 0x00, 0xfe, 0x57, 0x24,
12897 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09,
12898 0x00, 0x00, 0xff, 0x08,
12899 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
12900 0xff, 0xff, 0xff, 0x13,
12901 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
12902 0xfe, 0x04, 0xf7, 0xe8,
12903 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d,
12904 0x0d, 0x51, 0x37, 0xfe,
12905 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0,
12906 0xfe, 0xf8, 0x01, 0xfe,
12907 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
12908 0x05, 0xfe, 0x08, 0x0f,
12909 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe,
12910 0x28, 0x1c, 0x03, 0xfe,
12911 0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe,
12912 0x48, 0xf0, 0xfe, 0x90,
12913 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
12914 0x02, 0xfe, 0x46, 0xf0,
12915 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0,
12916 0xfe, 0x4e, 0x02, 0xfe,
12917 0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c,
12918 0x0d, 0xa2, 0x1c, 0x07,
12919 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
12920 0x1c, 0xf5, 0xfe, 0x1e,
12921 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc,
12922 0xde, 0x0a, 0x81, 0x01,
12923 0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a,
12924 0x81, 0x01, 0x5c, 0xfe,
12925 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
12926 0xfe, 0x58, 0x1c, 0x1c,
12927 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02,
12928 0x2b, 0xfe, 0x9e, 0x02,
12929 0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30,
12930 0x00, 0x47, 0xb8, 0x01,
12931 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
12932 0x1a, 0x31, 0xfe, 0x69,
12933 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe,
12934 0x1e, 0x1e, 0x20, 0x2c,
12935 0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a,
12936 0x44, 0x15, 0x56, 0x51,
12937 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
12938 0x01, 0x18, 0x09, 0x00,
12939 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01,
12940 0x18, 0xfe, 0xc8, 0x54,
12941 0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60,
12942 0xfe, 0x02, 0xe8, 0x30,
12943 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
12944 0xfe, 0xe4, 0x01, 0xfe,
12945 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe,
12946 0x26, 0xf0, 0xfe, 0x66,
12947 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe,
12948 0xef, 0x10, 0xfe, 0x9f,
12949 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
12950 0x70, 0x37, 0xfe, 0x48,
12951 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26,
12952 0x21, 0xb9, 0xc7, 0x20,
12953 0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15,
12954 0xe1, 0x2a, 0xeb, 0xfe,
12955 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
12956 0x15, 0xfe, 0xe4, 0x00,
12957 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41,
12958 0xfe, 0x06, 0xf0, 0xfe,
12959 0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29,
12960 0x03, 0x81, 0x1e, 0x1b,
12961 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
12962 0xea, 0xfe, 0x46, 0x1c,
12963 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
12964 0xfe, 0x48, 0x1c, 0x75,
12965 0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a,
12966 0xe1, 0x01, 0x18, 0x77,
12967 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
12968 0x8f, 0xfe, 0x70, 0x02,
12969 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04,
12970 0x16, 0xfe, 0x4a, 0x04,
12971 0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff,
12972 0x02, 0x00, 0x10, 0x01,
12973 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
12974 0xee, 0xfe, 0x4c, 0x44,
12975 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54,
12976 0x7b, 0xec, 0x60, 0x8d,
12977 0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01,
12978 0x0c, 0x06, 0x28, 0xfe,
12979 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
12980 0x13, 0x34, 0xfe, 0x4c,
12981 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54,
12982 0x13, 0x01, 0x0c, 0x06,
12983 0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06,
12984 0x28, 0xf9, 0x1f, 0x7f,
12985 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
12986 0xfe, 0xa4, 0x0e, 0x05,
12987 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe,
12988 0x9c, 0x93, 0x3a, 0x0b,
12989 0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b,
12990 0x7d, 0x1d, 0xfe, 0x46,
12991 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
12992 0xfe, 0x87, 0x83, 0xfe,
12993 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98,
12994 0x13, 0x0f, 0xfe, 0x20,
12995 0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84,
12996 0x12, 0x01, 0x38, 0x06,
12997 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
12998 0x05, 0xd0, 0x54, 0x01,
12999 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe,
13000 0x50, 0x12, 0x5e, 0xff,
13001 0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02,
13002 0x00, 0x10, 0x2f, 0xfe,
13003 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
13004 0x38, 0xfe, 0x4a, 0xf0,
13005 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe,
13006 0x21, 0x00, 0xf1, 0x2e,
13007 0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00,
13008 0x10, 0x2f, 0xfe, 0xd0,
13009 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
13010 0x1c, 0x00, 0x4d, 0x01,
13011 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06,
13012 0x28, 0xfe, 0x24, 0x12,
13013 0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe,
13014 0x0d, 0x00, 0x01, 0x42,
13015 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
13016 0x03, 0xb6, 0x1e, 0xfe,
13017 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17,
13018 0xfe, 0x72, 0x06, 0x0a,
13019 0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56,
13020 0x19, 0x16, 0xfe, 0x68,
13021 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
13022 0x03, 0x9a, 0x1e, 0xfe,
13023 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12,
13024 0x48, 0xfe, 0x92, 0x06,
13025 0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13,
13026 0x58, 0xff, 0x02, 0x00,
13027 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
13028 0xfe, 0xea, 0x06, 0x01,
13029 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16,
13030 0xfe, 0xe0, 0x06, 0x15,
13031 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07,
13032 0x01, 0x84, 0xfe, 0xae,
13033 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
13034 0x1e, 0xfe, 0x1a, 0x12,
13035 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
13036 0x43, 0x48, 0x62, 0x80,
13037 0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24,
13038 0x36, 0xfe, 0x02, 0xf6,
13039 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
13040 0xd0, 0x0d, 0x17, 0xfe,
13041 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20,
13042 0x9e, 0x15, 0x82, 0x01,
13043 0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58,
13044 0x57, 0x10, 0xe6, 0x05,
13045 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
13046 0xfe, 0x9c, 0x32, 0x5f,
13047 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c,
13048 0xfe, 0x0a, 0xf0, 0xfe,
13049 0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08,
13050 0xaf, 0xa0, 0x05, 0x29,
13051 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
13052 0x00, 0x01, 0x08, 0x14,
13053 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08,
13054 0x14, 0x00, 0x05, 0xfe,
13055 0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06,
13056 0x12, 0xfe, 0x30, 0x13,
13057 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
13058 0x01, 0x08, 0x14, 0x00,
13059 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a,
13060 0x78, 0x4f, 0x0f, 0xfe,
13061 0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d,
13062 0x28, 0x48, 0xfe, 0x6c,
13063 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
13064 0x12, 0x53, 0x63, 0x4e,
13065 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe,
13066 0x6c, 0x08, 0xaf, 0xa0,
13067 0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24,
13068 0x05, 0xed, 0xfe, 0x9c,
13069 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
13070 0x1e, 0xfe, 0x99, 0x58,
13071 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a,
13072 0x22, 0x6b, 0x01, 0x0c,
13073 0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e,
13074 0x1e, 0x47, 0x2c, 0x7a,
13075 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
13076 0x01, 0x0c, 0x61, 0x65,
13077 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a,
13078 0x16, 0xfe, 0x08, 0x50,
13079 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10,
13080 0x01, 0xfe, 0xce, 0x1e,
13081 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
13082 0x01, 0xfe, 0xfe, 0x1e,
13083 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a,
13084 0x10, 0x01, 0x0c, 0x06,
13085 0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e,
13086 0x10, 0x6a, 0x22, 0x6b,
13087 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
13088 0xfe, 0x9f, 0x83, 0x33,
13089 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93,
13090 0x3a, 0x0b, 0xfe, 0xc6,
13091 0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d,
13092 0x01, 0xfe, 0xce, 0x1e,
13093 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
13094 0x04, 0xfe, 0xc0, 0x93,
13095 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e,
13096 0x10, 0x4b, 0x22, 0x4c,
13097 0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe,
13098 0x4e, 0x11, 0x2f, 0xfe,
13099 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
13100 0x3c, 0x37, 0x88, 0xf5,
13101 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a,
13102 0xd3, 0xfe, 0x42, 0x0a,
13103 0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0,
13104 0x05, 0x29, 0x01, 0x41,
13105 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
13106 0xfe, 0x14, 0x12, 0x01,
13107 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe,
13108 0x2e, 0x1c, 0x05, 0xfe,
13109 0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41,
13110 0xfe, 0x2c, 0x1c, 0xfe,
13111 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
13112 0x92, 0x10, 0xc4, 0xf6,
13113 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe,
13114 0xe7, 0x10, 0xfe, 0x2b,
13115 0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12,
13116 0xac, 0xfe, 0xd2, 0xf0,
13117 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
13118 0x1b, 0xbf, 0xd4, 0x5b,
13119 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75,
13120 0x5e, 0x32, 0x1f, 0x7f,
13121 0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98,
13122 0x05, 0x70, 0xfe, 0x74,
13123 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
13124 0x0f, 0x4d, 0x01, 0xfe,
13125 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06,
13126 0x0d, 0x2b, 0xfe, 0xe2,
13127 0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24,
13128 0xfe, 0x88, 0x13, 0x21,
13129 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
13130 0x83, 0x83, 0xfe, 0xc9,
13131 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04,
13132 0x91, 0x04, 0xfe, 0x84,
13133 0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93,
13134 0xfe, 0xcb, 0x57, 0x0b,
13135 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
13136 0x6a, 0x3b, 0x6b, 0x10,
13137 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30,
13138 0x20, 0x6e, 0xdb, 0x64,
13139 0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55,
13140 0xfe, 0x04, 0xfa, 0x64,
13141 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
13142 0x10, 0x98, 0x91, 0x6c,
13143 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91,
13144 0x4b, 0x7e, 0x4c, 0x01,
13145 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10,
13146 0x58, 0xfe, 0x91, 0x58,
13147 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
13148 0x1b, 0x40, 0x01, 0x0c,
13149 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f,
13150 0xfe, 0x10, 0x90, 0x04,
13151 0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93,
13152 0x79, 0x0b, 0x0e, 0xfe,
13153 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
13154 0x01, 0x0c, 0x06, 0x0d,
13155 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe,
13156 0x0c, 0x58, 0xfe, 0x8d,
13157 0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99,
13158 0x83, 0x33, 0x0b, 0x0e,
13159 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
13160 0x19, 0xfe, 0x19, 0x41,
13161 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42,
13162 0x19, 0xfe, 0x44, 0x00,
13163 0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda,
13164 0x4c, 0xfe, 0x0c, 0x51,
13165 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
13166 0x76, 0x10, 0xac, 0xfe,
13167 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03,
13168 0xe3, 0x23, 0x07, 0xfe,
13169 0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe,
13170 0xcc, 0x0c, 0x1f, 0x92,
13171 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
13172 0x0c, 0xfe, 0x3e, 0x10,
13173 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70,
13174 0xfe, 0xcb, 0xf0, 0xfe,
13175 0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe,
13176 0xf4, 0x0c, 0x19, 0x94,
13177 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
13178 0xfe, 0xcc, 0xf0, 0xef,
13179 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe,
13180 0x4e, 0x11, 0x2f, 0xfe,
13181 0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b,
13182 0x3c, 0x37, 0x88, 0xf5,
13183 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
13184 0x2f, 0xfe, 0x3e, 0x0d,
13185 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f,
13186 0xd2, 0x9f, 0xd3, 0x9f,
13187 0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4,
13188 0xc5, 0x75, 0xd7, 0x99,
13189 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
13190 0x9c, 0x2f, 0xfe, 0x8c,
13191 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe,
13192 0x42, 0x00, 0x05, 0x70,
13193 0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06,
13194 0x0d, 0xfe, 0x44, 0x13,
13195 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
13196 0xfe, 0xda, 0x0e, 0x0a,
13197 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa,
13198 0x10, 0x01, 0xfe, 0xf4,
13199 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40,
13200 0x15, 0x56, 0x01, 0x85,
13201 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
13202 0xcc, 0x10, 0x01, 0xa7,
13203 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04,
13204 0xfe, 0x99, 0x83, 0xfe,
13205 0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe,
13206 0x43, 0x00, 0xfe, 0xa2,
13207 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
13208 0x00, 0x1d, 0x40, 0x15,
13209 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05,
13210 0xfe, 0x3a, 0x03, 0x01,
13211 0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01,
13212 0x76, 0x06, 0x12, 0xfe,
13213 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
13214 0xfe, 0x9d, 0xf0, 0xfe,
13215 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01,
13216 0x0c, 0x61, 0x12, 0x44,
13217 0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f,
13218 0xfe, 0x2e, 0x10, 0x19,
13219 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
13220 0xfe, 0x41, 0x00, 0xa2,
13221 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b,
13222 0xea, 0x4f, 0xfe, 0x04,
13223 0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05,
13224 0x35, 0xfe, 0x12, 0x1c,
13225 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
13226 0xfe, 0xd4, 0x11, 0x05,
13227 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe,
13228 0xce, 0x45, 0x31, 0x51,
13229 0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03,
13230 0x67, 0xfe, 0x98, 0x56,
13231 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
13232 0x0c, 0x06, 0x28, 0xfe,
13233 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba,
13234 0xfe, 0xfa, 0x14, 0xfe,
13235 0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67,
13236 0xfe, 0xe0, 0x14, 0xfe,
13237 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
13238 0xfe, 0xad, 0x13, 0x05,
13239 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20,
13240 0xe7, 0xfe, 0x08, 0x1c,
13241 0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe,
13242 0x48, 0x55, 0xa5, 0x3b,
13243 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
13244 0xf0, 0x1a, 0x03, 0xfe,
13245 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02,
13246 0xec, 0xe7, 0x53, 0x00,
13247 0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
13248 0x01, 0xfe, 0x62, 0x1b,
13249 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
13250 0xea, 0xe7, 0x53, 0x92,
13251 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03,
13252 0xfe, 0x38, 0x01, 0x23,
13253 0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62,
13254 0x01, 0x01, 0xfe, 0x1e,
13255 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
13256 0x26, 0x02, 0x21, 0x96,
13257 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5,
13258 0xc3, 0xfe, 0xe1, 0x10,
13259 0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf,
13260 0xfe, 0x03, 0xdc, 0xfe,
13261 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
13262 0x00, 0xcc, 0x02, 0xfe,
13263 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13,
13264 0x0f, 0xfe, 0x1c, 0x80,
13265 0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13,
13266 0x0f, 0xfe, 0x1e, 0x80,
13267 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
13268 0x1d, 0x80, 0x04, 0xfe,
13269 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee,
13270 0x1e, 0xac, 0xfe, 0x14,
13271 0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e,
13272 0x1f, 0xfe, 0x30, 0xf4,
13273 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
13274 0x56, 0xfb, 0x01, 0xfe,
13275 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01,
13276 0xfe, 0x00, 0x1d, 0x15,
13277 0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe,
13278 0x22, 0x1b, 0xfe, 0x1e,
13279 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
13280 0x96, 0x90, 0x04, 0xfe,
13281 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66,
13282 0x01, 0x01, 0x0c, 0x06,
13283 0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b,
13284 0x0e, 0x77, 0xfe, 0x01,
13285 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
13286 0x21, 0x2c, 0xfe, 0x00,
13287 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe,
13288 0x06, 0x58, 0x03, 0xfe,
13289 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58,
13290 0x03, 0xfe, 0xb2, 0x00,
13291 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
13292 0x66, 0x10, 0x55, 0x10,
13293 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91,
13294 0x54, 0x2b, 0xfe, 0x88,
13295 0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe,
13296 0x91, 0x54, 0x2b, 0xfe,
13297 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
13298 0x00, 0x40, 0x8d, 0x2c,
13299 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe,
13300 0x12, 0x1c, 0x75, 0xfe,
13301 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c,
13302 0x14, 0xfe, 0x0e, 0x47,
13303 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
13304 0xa7, 0x90, 0x34, 0x60,
13305 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80,
13306 0x09, 0x56, 0xfe, 0x34,
13307 0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48,
13308 0xfe, 0x45, 0x48, 0x01,
13309 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
13310 0x09, 0x1a, 0xa5, 0x0a,
13311 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4,
13312 0xfe, 0x14, 0x56, 0xfe,
13313 0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01,
13314 0xec, 0xb8, 0xfe, 0x9e,
13315 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
13316 0xf4, 0xfe, 0xdd, 0x10,
13317 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48,
13318 0x12, 0x09, 0x0d, 0xfe,
13319 0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4,
13320 0x13, 0x09, 0xfe, 0x23,
13321 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
13322 0x24, 0xfe, 0x12, 0x12,
13323 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08,
13324 0xae, 0x41, 0x02, 0x32,
13325 0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05,
13326 0x35, 0x32, 0x01, 0x43,
13327 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
13328 0x13, 0x01, 0x0c, 0x06,
13329 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe,
13330 0xe5, 0x55, 0xb0, 0xfe,
13331 0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e,
13332 0xfe, 0xb6, 0x0e, 0x10,
13333 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
13334 0x88, 0x20, 0x6e, 0x01,
13335 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5,
13336 0x55, 0xfe, 0x04, 0xfa,
13337 0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d,
13338 0xfe, 0x40, 0x56, 0xfe,
13339 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
13340 0x44, 0x55, 0xfe, 0xe5,
13341 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10,
13342 0x68, 0x22, 0x69, 0x01,
13343 0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b,
13344 0x6b, 0xfe, 0x2c, 0x50,
13345 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
13346 0x50, 0x03, 0x68, 0x3b,
13347 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe,
13348 0x40, 0x50, 0xfe, 0xc2,
13349 0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08,
13350 0x16, 0x3d, 0x27, 0x25,
13351 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
13352 0xa6, 0x23, 0x3f, 0x1b,
13353 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c,
13354 0xfe, 0x0a, 0x55, 0x31,
13355 0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e,
13356 0x51, 0x05, 0x72, 0x01,
13357 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
13358 0x2a, 0x3c, 0x16, 0xc0,
13359 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b,
13360 0xfe, 0x66, 0x15, 0x05,
13361 0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d,
13362 0x2b, 0x3d, 0x01, 0x08,
13363 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
13364 0xb6, 0x1e, 0x83, 0x01,
13365 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46,
13366 0x07, 0x90, 0x3f, 0x01,
13367 0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13,
13368 0x01, 0x43, 0x09, 0x82,
13369 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
13370 0x05, 0x72, 0xfe, 0xc0,
13371 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e,
13372 0x32, 0x01, 0x08, 0x17,
13373 0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16,
13374 0x3d, 0x27, 0x25, 0xbd,
13375 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
13376 0xe8, 0x14, 0x01, 0xa6,
13377 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe,
13378 0x0e, 0x12, 0x01, 0x43,
13379 0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32,
13380 0x01, 0x08, 0x17, 0x73,
13381 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
13382 0x27, 0x25, 0xbd, 0x09,
13383 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe,
13384 0xb6, 0x14, 0x86, 0xa8,
13385 0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09,
13386 0x82, 0x4e, 0x05, 0x72,
13387 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
13388 0xfe, 0xc0, 0x19, 0x05,
13389 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f,
13390 0xcc, 0x01, 0x08, 0x26,
13391 0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe,
13392 0xcc, 0x15, 0x5e, 0x32,
13393 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
13394 0xad, 0x23, 0xfe, 0xff,
13395 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02,
13396 0x00, 0x57, 0x52, 0xad,
13397 0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff,
13398 0x02, 0x00, 0x57, 0x52,
13399 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
13400 0x02, 0x13, 0x58, 0xff,
13401 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01,
13402 0x5c, 0x0a, 0x55, 0x01,
13403 0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a,
13404 0xff, 0x03, 0x00, 0x54,
13405 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
13406 0x7c, 0x3a, 0x0b, 0x0e,
13407 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19,
13408 0xfe, 0x1a, 0xf7, 0x00,
13409 0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c,
13410 0xda, 0x6d, 0x02, 0xfe,
13411 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
13412 0x02, 0x01, 0xc6, 0xfe,
13413 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27,
13414 0x25, 0xbe, 0x01, 0x08,
13415 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59,
13416 0x03, 0x9a, 0x1e, 0xfe,
13417 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
13418 0x48, 0xfe, 0x08, 0x17,
13419 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26,
13420 0x17, 0x4d, 0x13, 0x07,
13421 0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1,
13422 0xff, 0x02, 0x83, 0x55,
13423 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
13424 0x17, 0x1c, 0x63, 0x13,
13425 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64,
13426 0x00, 0xb0, 0xfe, 0x80,
13427 0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10,
13428 0x53, 0x07, 0xfe, 0x60,
13429 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
13430 0x00, 0x1c, 0x95, 0x13,
13431 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3,
13432 0xfe, 0x43, 0xf4, 0x96,
13433 0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43,
13434 0xf4, 0x94, 0xf6, 0x8b,
13435 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
13436 0xda, 0x17, 0x62, 0x49,
13437 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80,
13438 0x71, 0x50, 0x26, 0xfe,
13439 0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3,
13440 0x58, 0x02, 0x50, 0x13,
13441 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
13442 0x25, 0xbe, 0xfe, 0x03,
13443 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9,
13444 0x0a, 0x01, 0x08, 0x16,
13445 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01,
13446 0x01, 0x08, 0x16, 0xa9,
13447 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
13448 0x08, 0x16, 0xa9, 0x27,
13449 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83,
13450 0x01, 0x38, 0x06, 0x24,
13451 0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1,
13452 0x78, 0x03, 0x9a, 0x1e,
13453 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
13454 0xfe, 0x40, 0x5a, 0x23,
13455 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c,
13456 0x80, 0x48, 0xfe, 0xaa,
13457 0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01,
13458 0xfe, 0xac, 0x1d, 0xfe,
13459 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
13460 0x43, 0x48, 0x2d, 0x93,
13461 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4,
13462 0x36, 0xfe, 0x34, 0xf4,
13463 0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe,
13464 0x28, 0x10, 0xfe, 0xc0,
13465 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
13466 0x18, 0x45, 0xfe, 0x1c,
13467 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c,
13468 0x19, 0xfe, 0x04, 0xf4,
13469 0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d,
13470 0x21, 0xfe, 0x7f, 0x01,
13471 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
13472 0x7e, 0x01, 0xfe, 0xc8,
13473 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa,
13474 0x21, 0xfe, 0x81, 0x01,
13475 0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50,
13476 0x13, 0x0d, 0x02, 0x14,
13477 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
13478 0xfe, 0x82, 0x19, 0x14,
13479 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01,
13480 0x08, 0x02, 0x14, 0x07,
13481 0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07,
13482 0x01, 0x08, 0x17, 0xc1,
13483 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
13484 0x08, 0x02, 0x50, 0x02,
13485 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74,
13486 0x14, 0x12, 0x01, 0x08,
13487 0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01,
13488 0x08, 0x17, 0x74, 0xfe,
13489 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
13490 0x74, 0x5f, 0xcc, 0x01,
13491 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4,
13492 0xfe, 0x49, 0xf4, 0x00,
13493 0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff,
13494 0x02, 0x00, 0x10, 0x2f,
13495 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
13496 0x16, 0xfe, 0x64, 0x1a,
13497 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c,
13498 0x61, 0x07, 0x44, 0x02,
13499 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12,
13500 0x13, 0x0a, 0x9d, 0x01,
13501 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
13502 0xfe, 0x80, 0xe7, 0x1a,
13503 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02,
13504 0x0a, 0x5a, 0x01, 0x18,
13505 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe,
13506 0x7e, 0x1e, 0xfe, 0x80,
13507 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
13508 0xfe, 0x80, 0x4c, 0x0a,
13509 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf,
13510 0xfe, 0x19, 0xde, 0xfe,
13511 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe,
13512 0x2a, 0x1c, 0xfa, 0xb3,
13513 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
13514 0xf4, 0x1a, 0xfe, 0xfa,
13515 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24,
13516 0xfe, 0x18, 0x58, 0x03,
13517 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f,
13518 0xfe, 0x30, 0xf4, 0x07,
13519 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
13520 0xf7, 0x24, 0xb1, 0xfe,
13521 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b,
13522 0xfe, 0xba, 0x10, 0x1c,
13523 0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
13524 0x1d, 0xf7, 0x54, 0xb1,
13525 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
13526 0xaf, 0x19, 0xfe, 0x98,
13527 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c,
13528 0x1a, 0x87, 0x8b, 0x0f,
13529 0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58,
13530 0xfe, 0x32, 0x90, 0x04,
13531 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
13532 0x7c, 0x12, 0xfe, 0x0f,
13533 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14,
13534 0x31, 0x02, 0xc9, 0x2b,
13535 0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe,
13536 0x6a, 0xfe, 0x19, 0xfe,
13537 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
13538 0x1b, 0xfe, 0x36, 0x14,
13539 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19,
13540 0xfe, 0x80, 0xe7, 0x1a,
13541 0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a,
13542 0x30, 0xfe, 0x12, 0x45,
13543 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
13544 0x39, 0xf0, 0x75, 0x26,
13545 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03,
13546 0xe3, 0x23, 0x07, 0xfe,
13547 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09,
13548 0x56, 0xfe, 0x3c, 0x13,
13549 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
13550 0x01, 0x18, 0xcb, 0xfe,
13551 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16,
13552 0xfe, 0x00, 0xcc, 0xcb,
13553 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18,
13554 0xfe, 0x80, 0x4c, 0x01,
13555 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
13556 0x12, 0xfe, 0x14, 0x56,
13557 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7,
13558 0x0d, 0x19, 0xfe, 0x15,
13559 0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06,
13560 0x83, 0xfe, 0x18, 0x80,
13561 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
13562 0x90, 0xfe, 0xba, 0x90,
13563 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02,
13564 0x21, 0xb9, 0x88, 0x20,
13565 0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01,
13566 0x18, 0xfe, 0x49, 0x44,
13567 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
13568 0x1a, 0xa4, 0x0a, 0x67,
13569 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4,
13570 0x1d, 0x7b, 0xfe, 0x52,
13571 0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe,
13572 0x4e, 0xe4, 0xdd, 0x7b,
13573 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
13574 0xfe, 0x4e, 0xe4, 0xfe,
13575 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24,
13576 0xfe, 0x08, 0x10, 0x03,
13577 0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04,
13578 0x68, 0x54, 0xfe, 0xf1,
13579 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
13580 0xfe, 0x1a, 0xf4, 0xfe,
13581 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02,
13582 0x09, 0x92, 0xfe, 0x5a,
13583 0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe,
13584 0x5a, 0xf0, 0xfe, 0xc8,
13585 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
13586 0x1a, 0x10, 0x09, 0x0d,
13587 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02,
13588 0x1f, 0x93, 0x01, 0x42,
13589 0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e,
13590 0xfe, 0x14, 0xf0, 0x08,
13591 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
13592 0xfe, 0x82, 0xf0, 0xfe,
13593 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e,
13594 0x02, 0x0f, 0xfe, 0x18,
13595 0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02,
13596 0x80, 0x04, 0xfe, 0x82,
13597 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
13598 0x83, 0x33, 0x0b, 0x0e,
13599 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e,
13600 0x02, 0x0f, 0xfe, 0x04,
13601 0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80,
13602 0x80, 0x04, 0xfe, 0x80,
13603 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
13604 0xfe, 0x99, 0x83, 0xfe,
13605 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86,
13606 0x83, 0xfe, 0xce, 0x47,
13607 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a,
13608 0x0b, 0x0e, 0x02, 0x0f,
13609 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13610 0xfe, 0x08, 0x90, 0x04,
13611 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04,
13612 0xfe, 0x8a, 0x93, 0x79,
13613 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a,
13614 0x0b, 0x0e, 0x02, 0x0f,
13615 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13616 0xfe, 0x3c, 0x90, 0x04,
13617 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80,
13618 0x04, 0xfe, 0x83, 0x83,
13619 0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
13622 static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
13623 static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
13625 /* a_init.c */
13627 * EEPROM Configuration.
13629 * All drivers should use this structure to set the default EEPROM
13630 * configuration. The BIOS now uses this structure when it is built.
13631 * Additional structure information can be found in a_condor.h where
13632 * the structure is defined.
13634 * The *_Field_IsChar structs are needed to correct for endianness.
13635 * These values are read from the board 16 bits at a time directly
13636 * into the structs. Because some fields are char, the values will be
13637 * in the wrong order. The *_Field_IsChar tells when to flip the
13638 * bytes. Data read and written to PCI memory is automatically swapped
13639 * on big-endian platforms so char fields read as words are actually being
13640 * unswapped on big-endian platforms.
13642 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
13643 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
13644 0x0000, /* cfg_msw */
13645 0xFFFF, /* disc_enable */
13646 0xFFFF, /* wdtr_able */
13647 0xFFFF, /* sdtr_able */
13648 0xFFFF, /* start_motor */
13649 0xFFFF, /* tagqng_able */
13650 0xFFFF, /* bios_scan */
13651 0, /* scam_tolerant */
13652 7, /* adapter_scsi_id */
13653 0, /* bios_boot_delay */
13654 3, /* scsi_reset_delay */
13655 0, /* bios_id_lun */
13656 0, /* termination */
13657 0, /* reserved1 */
13658 0xFFE7, /* bios_ctrl */
13659 0xFFFF, /* ultra_able */
13660 0, /* reserved2 */
13661 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
13662 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13663 0, /* dvc_cntl */
13664 0, /* bug_fix */
13665 0, /* serial_number_word1 */
13666 0, /* serial_number_word2 */
13667 0, /* serial_number_word3 */
13668 0, /* check_sum */
13669 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13670 , /* oem_name[16] */
13671 0, /* dvc_err_code */
13672 0, /* adv_err_code */
13673 0, /* adv_err_addr */
13674 0, /* saved_dvc_err_code */
13675 0, /* saved_adv_err_code */
13676 0, /* saved_adv_err_addr */
13677 0 /* num_of_err */
13680 static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
13681 0, /* cfg_lsw */
13682 0, /* cfg_msw */
13683 0, /* -disc_enable */
13684 0, /* wdtr_able */
13685 0, /* sdtr_able */
13686 0, /* start_motor */
13687 0, /* tagqng_able */
13688 0, /* bios_scan */
13689 0, /* scam_tolerant */
13690 1, /* adapter_scsi_id */
13691 1, /* bios_boot_delay */
13692 1, /* scsi_reset_delay */
13693 1, /* bios_id_lun */
13694 1, /* termination */
13695 1, /* reserved1 */
13696 0, /* bios_ctrl */
13697 0, /* ultra_able */
13698 0, /* reserved2 */
13699 1, /* max_host_qng */
13700 1, /* max_dvc_qng */
13701 0, /* dvc_cntl */
13702 0, /* bug_fix */
13703 0, /* serial_number_word1 */
13704 0, /* serial_number_word2 */
13705 0, /* serial_number_word3 */
13706 0, /* check_sum */
13707 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13708 , /* oem_name[16] */
13709 0, /* dvc_err_code */
13710 0, /* adv_err_code */
13711 0, /* adv_err_addr */
13712 0, /* saved_dvc_err_code */
13713 0, /* saved_adv_err_code */
13714 0, /* saved_adv_err_addr */
13715 0 /* num_of_err */
13718 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
13719 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13720 0x0000, /* 01 cfg_msw */
13721 0xFFFF, /* 02 disc_enable */
13722 0xFFFF, /* 03 wdtr_able */
13723 0x4444, /* 04 sdtr_speed1 */
13724 0xFFFF, /* 05 start_motor */
13725 0xFFFF, /* 06 tagqng_able */
13726 0xFFFF, /* 07 bios_scan */
13727 0, /* 08 scam_tolerant */
13728 7, /* 09 adapter_scsi_id */
13729 0, /* bios_boot_delay */
13730 3, /* 10 scsi_reset_delay */
13731 0, /* bios_id_lun */
13732 0, /* 11 termination_se */
13733 0, /* termination_lvd */
13734 0xFFE7, /* 12 bios_ctrl */
13735 0x4444, /* 13 sdtr_speed2 */
13736 0x4444, /* 14 sdtr_speed3 */
13737 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
13738 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13739 0, /* 16 dvc_cntl */
13740 0x4444, /* 17 sdtr_speed4 */
13741 0, /* 18 serial_number_word1 */
13742 0, /* 19 serial_number_word2 */
13743 0, /* 20 serial_number_word3 */
13744 0, /* 21 check_sum */
13745 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13746 , /* 22-29 oem_name[16] */
13747 0, /* 30 dvc_err_code */
13748 0, /* 31 adv_err_code */
13749 0, /* 32 adv_err_addr */
13750 0, /* 33 saved_dvc_err_code */
13751 0, /* 34 saved_adv_err_code */
13752 0, /* 35 saved_adv_err_addr */
13753 0, /* 36 reserved */
13754 0, /* 37 reserved */
13755 0, /* 38 reserved */
13756 0, /* 39 reserved */
13757 0, /* 40 reserved */
13758 0, /* 41 reserved */
13759 0, /* 42 reserved */
13760 0, /* 43 reserved */
13761 0, /* 44 reserved */
13762 0, /* 45 reserved */
13763 0, /* 46 reserved */
13764 0, /* 47 reserved */
13765 0, /* 48 reserved */
13766 0, /* 49 reserved */
13767 0, /* 50 reserved */
13768 0, /* 51 reserved */
13769 0, /* 52 reserved */
13770 0, /* 53 reserved */
13771 0, /* 54 reserved */
13772 0, /* 55 reserved */
13773 0, /* 56 cisptr_lsw */
13774 0, /* 57 cisprt_msw */
13775 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
13776 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
13777 0, /* 60 reserved */
13778 0, /* 61 reserved */
13779 0, /* 62 reserved */
13780 0 /* 63 reserved */
13783 static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
13784 0, /* 00 cfg_lsw */
13785 0, /* 01 cfg_msw */
13786 0, /* 02 disc_enable */
13787 0, /* 03 wdtr_able */
13788 0, /* 04 sdtr_speed1 */
13789 0, /* 05 start_motor */
13790 0, /* 06 tagqng_able */
13791 0, /* 07 bios_scan */
13792 0, /* 08 scam_tolerant */
13793 1, /* 09 adapter_scsi_id */
13794 1, /* bios_boot_delay */
13795 1, /* 10 scsi_reset_delay */
13796 1, /* bios_id_lun */
13797 1, /* 11 termination_se */
13798 1, /* termination_lvd */
13799 0, /* 12 bios_ctrl */
13800 0, /* 13 sdtr_speed2 */
13801 0, /* 14 sdtr_speed3 */
13802 1, /* 15 max_host_qng */
13803 1, /* max_dvc_qng */
13804 0, /* 16 dvc_cntl */
13805 0, /* 17 sdtr_speed4 */
13806 0, /* 18 serial_number_word1 */
13807 0, /* 19 serial_number_word2 */
13808 0, /* 20 serial_number_word3 */
13809 0, /* 21 check_sum */
13810 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13811 , /* 22-29 oem_name[16] */
13812 0, /* 30 dvc_err_code */
13813 0, /* 31 adv_err_code */
13814 0, /* 32 adv_err_addr */
13815 0, /* 33 saved_dvc_err_code */
13816 0, /* 34 saved_adv_err_code */
13817 0, /* 35 saved_adv_err_addr */
13818 0, /* 36 reserved */
13819 0, /* 37 reserved */
13820 0, /* 38 reserved */
13821 0, /* 39 reserved */
13822 0, /* 40 reserved */
13823 0, /* 41 reserved */
13824 0, /* 42 reserved */
13825 0, /* 43 reserved */
13826 0, /* 44 reserved */
13827 0, /* 45 reserved */
13828 0, /* 46 reserved */
13829 0, /* 47 reserved */
13830 0, /* 48 reserved */
13831 0, /* 49 reserved */
13832 0, /* 50 reserved */
13833 0, /* 51 reserved */
13834 0, /* 52 reserved */
13835 0, /* 53 reserved */
13836 0, /* 54 reserved */
13837 0, /* 55 reserved */
13838 0, /* 56 cisptr_lsw */
13839 0, /* 57 cisprt_msw */
13840 0, /* 58 subsysvid */
13841 0, /* 59 subsysid */
13842 0, /* 60 reserved */
13843 0, /* 61 reserved */
13844 0, /* 62 reserved */
13845 0 /* 63 reserved */
13848 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
13849 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13850 0x0000, /* 01 cfg_msw */
13851 0xFFFF, /* 02 disc_enable */
13852 0xFFFF, /* 03 wdtr_able */
13853 0x5555, /* 04 sdtr_speed1 */
13854 0xFFFF, /* 05 start_motor */
13855 0xFFFF, /* 06 tagqng_able */
13856 0xFFFF, /* 07 bios_scan */
13857 0, /* 08 scam_tolerant */
13858 7, /* 09 adapter_scsi_id */
13859 0, /* bios_boot_delay */
13860 3, /* 10 scsi_reset_delay */
13861 0, /* bios_id_lun */
13862 0, /* 11 termination_se */
13863 0, /* termination_lvd */
13864 0xFFE7, /* 12 bios_ctrl */
13865 0x5555, /* 13 sdtr_speed2 */
13866 0x5555, /* 14 sdtr_speed3 */
13867 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
13868 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13869 0, /* 16 dvc_cntl */
13870 0x5555, /* 17 sdtr_speed4 */
13871 0, /* 18 serial_number_word1 */
13872 0, /* 19 serial_number_word2 */
13873 0, /* 20 serial_number_word3 */
13874 0, /* 21 check_sum */
13875 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13876 , /* 22-29 oem_name[16] */
13877 0, /* 30 dvc_err_code */
13878 0, /* 31 adv_err_code */
13879 0, /* 32 adv_err_addr */
13880 0, /* 33 saved_dvc_err_code */
13881 0, /* 34 saved_adv_err_code */
13882 0, /* 35 saved_adv_err_addr */
13883 0, /* 36 reserved */
13884 0, /* 37 reserved */
13885 0, /* 38 reserved */
13886 0, /* 39 reserved */
13887 0, /* 40 reserved */
13888 0, /* 41 reserved */
13889 0, /* 42 reserved */
13890 0, /* 43 reserved */
13891 0, /* 44 reserved */
13892 0, /* 45 reserved */
13893 0, /* 46 reserved */
13894 0, /* 47 reserved */
13895 0, /* 48 reserved */
13896 0, /* 49 reserved */
13897 0, /* 50 reserved */
13898 0, /* 51 reserved */
13899 0, /* 52 reserved */
13900 0, /* 53 reserved */
13901 0, /* 54 reserved */
13902 0, /* 55 reserved */
13903 0, /* 56 cisptr_lsw */
13904 0, /* 57 cisprt_msw */
13905 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
13906 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
13907 0, /* 60 reserved */
13908 0, /* 61 reserved */
13909 0, /* 62 reserved */
13910 0 /* 63 reserved */
13913 static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
13914 0, /* 00 cfg_lsw */
13915 0, /* 01 cfg_msw */
13916 0, /* 02 disc_enable */
13917 0, /* 03 wdtr_able */
13918 0, /* 04 sdtr_speed1 */
13919 0, /* 05 start_motor */
13920 0, /* 06 tagqng_able */
13921 0, /* 07 bios_scan */
13922 0, /* 08 scam_tolerant */
13923 1, /* 09 adapter_scsi_id */
13924 1, /* bios_boot_delay */
13925 1, /* 10 scsi_reset_delay */
13926 1, /* bios_id_lun */
13927 1, /* 11 termination_se */
13928 1, /* termination_lvd */
13929 0, /* 12 bios_ctrl */
13930 0, /* 13 sdtr_speed2 */
13931 0, /* 14 sdtr_speed3 */
13932 1, /* 15 max_host_qng */
13933 1, /* max_dvc_qng */
13934 0, /* 16 dvc_cntl */
13935 0, /* 17 sdtr_speed4 */
13936 0, /* 18 serial_number_word1 */
13937 0, /* 19 serial_number_word2 */
13938 0, /* 20 serial_number_word3 */
13939 0, /* 21 check_sum */
13940 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13941 , /* 22-29 oem_name[16] */
13942 0, /* 30 dvc_err_code */
13943 0, /* 31 adv_err_code */
13944 0, /* 32 adv_err_addr */
13945 0, /* 33 saved_dvc_err_code */
13946 0, /* 34 saved_adv_err_code */
13947 0, /* 35 saved_adv_err_addr */
13948 0, /* 36 reserved */
13949 0, /* 37 reserved */
13950 0, /* 38 reserved */
13951 0, /* 39 reserved */
13952 0, /* 40 reserved */
13953 0, /* 41 reserved */
13954 0, /* 42 reserved */
13955 0, /* 43 reserved */
13956 0, /* 44 reserved */
13957 0, /* 45 reserved */
13958 0, /* 46 reserved */
13959 0, /* 47 reserved */
13960 0, /* 48 reserved */
13961 0, /* 49 reserved */
13962 0, /* 50 reserved */
13963 0, /* 51 reserved */
13964 0, /* 52 reserved */
13965 0, /* 53 reserved */
13966 0, /* 54 reserved */
13967 0, /* 55 reserved */
13968 0, /* 56 cisptr_lsw */
13969 0, /* 57 cisprt_msw */
13970 0, /* 58 subsysvid */
13971 0, /* 59 subsysid */
13972 0, /* 60 reserved */
13973 0, /* 61 reserved */
13974 0, /* 62 reserved */
13975 0 /* 63 reserved */
13979 * Initialize the ADV_DVC_VAR structure.
13981 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13983 * For a non-fatal error return a warning code. If there are no warnings
13984 * then 0 is returned.
13986 static int __devinit AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
13988 ushort warn_code;
13989 AdvPortAddr iop_base;
13990 uchar pci_cmd_reg;
13991 int status;
13993 warn_code = 0;
13994 asc_dvc->err_code = 0;
13995 iop_base = asc_dvc->iop_base;
13998 * PCI Command Register
14000 * Note: AscPCICmdRegBits_BusMastering definition (0x0007) includes
14001 * I/O Space Control, Memory Space Control and Bus Master Control bits.
14004 if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
14005 AscPCIConfigCommandRegister))
14006 & AscPCICmdRegBits_BusMastering)
14007 != AscPCICmdRegBits_BusMastering) {
14008 pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
14010 DvcAdvWritePCIConfigByte(asc_dvc,
14011 AscPCIConfigCommandRegister,
14012 pci_cmd_reg);
14014 if (((DvcAdvReadPCIConfigByte
14015 (asc_dvc, AscPCIConfigCommandRegister))
14016 & AscPCICmdRegBits_BusMastering)
14017 != AscPCICmdRegBits_BusMastering) {
14018 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14023 * PCI Latency Timer
14025 * If the "latency timer" register is 0x20 or above, then we don't need
14026 * to change it. Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
14027 * comes up less than 0x20).
14029 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
14030 DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer,
14031 0x20);
14032 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) <
14033 0x20) {
14034 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14039 * Save the state of the PCI Configuration Command Register
14040 * "Parity Error Response Control" Bit. If the bit is clear (0),
14041 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
14042 * DMA parity errors.
14044 asc_dvc->cfg->control_flag = 0;
14045 if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
14046 & AscPCICmdRegBits_ParErrRespCtrl)) == 0) {
14047 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
14050 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
14051 ADV_LIB_VERSION_MINOR;
14052 asc_dvc->cfg->chip_version =
14053 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
14055 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
14056 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
14057 (ushort)ADV_CHIP_ID_BYTE);
14059 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
14060 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
14061 (ushort)ADV_CHIP_ID_WORD);
14064 * Reset the chip to start and allow register writes.
14066 if (AdvFindSignature(iop_base) == 0) {
14067 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
14068 return ADV_ERROR;
14069 } else {
14071 * The caller must set 'chip_type' to a valid setting.
14073 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
14074 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
14075 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
14076 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14077 return ADV_ERROR;
14081 * Reset Chip.
14083 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14084 ADV_CTRL_REG_CMD_RESET);
14085 DvcSleepMilliSecond(100);
14086 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14087 ADV_CTRL_REG_CMD_WR_IO_REG);
14089 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
14090 if ((status =
14091 AdvInitFrom38C1600EEP(asc_dvc)) == ADV_ERROR) {
14092 return ADV_ERROR;
14094 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
14095 if ((status =
14096 AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR) {
14097 return ADV_ERROR;
14099 } else {
14100 if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR) {
14101 return ADV_ERROR;
14104 warn_code |= status;
14107 return warn_code;
14111 * Initialize the ASC-3550.
14113 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14115 * For a non-fatal error return a warning code. If there are no warnings
14116 * then 0 is returned.
14118 * Needed after initialization for error recovery.
14120 static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
14122 AdvPortAddr iop_base;
14123 ushort warn_code;
14124 ADV_DCNT sum;
14125 int begin_addr;
14126 int end_addr;
14127 ushort code_sum;
14128 int word;
14129 int j;
14130 int adv_asc3550_expanded_size;
14131 ADV_CARR_T *carrp;
14132 ADV_DCNT contig_len;
14133 ADV_SDCNT buf_size;
14134 ADV_PADDR carr_paddr;
14135 int i;
14136 ushort scsi_cfg1;
14137 uchar tid;
14138 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
14139 ushort wdtr_able = 0, sdtr_able, tagqng_able;
14140 uchar max_cmd[ADV_MAX_TID + 1];
14142 /* If there is already an error, don't continue. */
14143 if (asc_dvc->err_code != 0) {
14144 return ADV_ERROR;
14148 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
14150 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
14151 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14152 return ADV_ERROR;
14155 warn_code = 0;
14156 iop_base = asc_dvc->iop_base;
14159 * Save the RISC memory BIOS region before writing the microcode.
14160 * The BIOS may already be loaded and using its RISC LRAM region
14161 * so its region must be saved and restored.
14163 * Note: This code makes the assumption, which is currently true,
14164 * that a chip reset does not clear RISC LRAM.
14166 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14167 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14168 bios_mem[i]);
14172 * Save current per TID negotiated values.
14174 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
14175 ushort bios_version, major, minor;
14177 bios_version =
14178 bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
14179 major = (bios_version >> 12) & 0xF;
14180 minor = (bios_version >> 8) & 0xF;
14181 if (major < 3 || (major == 3 && minor == 1)) {
14182 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
14183 AdvReadWordLram(iop_base, 0x120, wdtr_able);
14184 } else {
14185 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14188 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14189 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14190 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14191 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14192 max_cmd[tid]);
14196 * Load the Microcode
14198 * Write the microcode image to RISC memory starting at address 0.
14200 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14201 /* Assume the following compressed format of the microcode buffer:
14203 * 254 word (508 byte) table indexed by byte code followed
14204 * by the following byte codes:
14206 * 1-Byte Code:
14207 * 00: Emit word 0 in table.
14208 * 01: Emit word 1 in table.
14210 * FD: Emit word 253 in table.
14212 * Multi-Byte Code:
14213 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14214 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14216 word = 0;
14217 for (i = 253 * 2; i < _adv_asc3550_size; i++) {
14218 if (_adv_asc3550_buf[i] == 0xff) {
14219 for (j = 0; j < _adv_asc3550_buf[i + 1]; j++) {
14220 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14221 _adv_asc3550_buf
14222 [i +
14223 3] << 8) |
14224 _adv_asc3550_buf
14225 [i + 2]));
14226 word++;
14228 i += 3;
14229 } else if (_adv_asc3550_buf[i] == 0xfe) {
14230 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14231 _adv_asc3550_buf[i +
14233 << 8) |
14234 _adv_asc3550_buf[i +
14235 1]));
14236 i += 2;
14237 word++;
14238 } else {
14239 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14240 _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) | _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
14241 word++;
14246 * Set 'word' for later use to clear the rest of memory and save
14247 * the expanded mcode size.
14249 word *= 2;
14250 adv_asc3550_expanded_size = word;
14253 * Clear the rest of ASC-3550 Internal RAM (8KB).
14255 for (; word < ADV_3550_MEMSIZE; word += 2) {
14256 AdvWriteWordAutoIncLram(iop_base, 0);
14260 * Verify the microcode checksum.
14262 sum = 0;
14263 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14265 for (word = 0; word < adv_asc3550_expanded_size; word += 2) {
14266 sum += AdvReadWordAutoIncLram(iop_base);
14269 if (sum != _adv_asc3550_chksum) {
14270 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14271 return ADV_ERROR;
14275 * Restore the RISC memory BIOS region.
14277 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14278 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14279 bios_mem[i]);
14283 * Calculate and write the microcode code checksum to the microcode
14284 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14286 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14287 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14288 code_sum = 0;
14289 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14290 for (word = begin_addr; word < end_addr; word += 2) {
14291 code_sum += AdvReadWordAutoIncLram(iop_base);
14293 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14296 * Read and save microcode version and date.
14298 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
14299 asc_dvc->cfg->mcode_date);
14300 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
14301 asc_dvc->cfg->mcode_version);
14304 * Set the chip type to indicate the ASC3550.
14306 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
14309 * If the PCI Configuration Command Register "Parity Error Response
14310 * Control" Bit was clear (0), then set the microcode variable
14311 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14312 * to ignore DMA parity errors.
14314 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
14315 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14316 word |= CONTROL_FLAG_IGNORE_PERR;
14317 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14321 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
14322 * threshold of 128 bytes. This register is only accessible to the host.
14324 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14325 START_CTL_EMFU | READ_CMD_MRM);
14328 * Microcode operating variables for WDTR, SDTR, and command tag
14329 * queuing will be set in AdvInquiryHandling() based on what a
14330 * device reports it is capable of in Inquiry byte 7.
14332 * If SCSI Bus Resets have been disabled, then directly set
14333 * SDTR and WDTR from the EEPROM configuration. This will allow
14334 * the BIOS and warm boot to work without a SCSI bus hang on
14335 * the Inquiry caused by host and target mismatched DTR values.
14336 * Without the SCSI Bus Reset, before an Inquiry a device can't
14337 * be assumed to be in Asynchronous, Narrow mode.
14339 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
14340 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
14341 asc_dvc->wdtr_able);
14342 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
14343 asc_dvc->sdtr_able);
14347 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
14348 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
14349 * bitmask. These values determine the maximum SDTR speed negotiated
14350 * with a device.
14352 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14353 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14354 * without determining here whether the device supports SDTR.
14356 * 4-bit speed SDTR speed name
14357 * =========== ===============
14358 * 0000b (0x0) SDTR disabled
14359 * 0001b (0x1) 5 Mhz
14360 * 0010b (0x2) 10 Mhz
14361 * 0011b (0x3) 20 Mhz (Ultra)
14362 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
14363 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
14364 * 0110b (0x6) Undefined
14366 * 1111b (0xF) Undefined
14368 word = 0;
14369 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14370 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
14371 /* Set Ultra speed for TID 'tid'. */
14372 word |= (0x3 << (4 * (tid % 4)));
14373 } else {
14374 /* Set Fast speed for TID 'tid'. */
14375 word |= (0x2 << (4 * (tid % 4)));
14377 if (tid == 3) { /* Check if done with sdtr_speed1. */
14378 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
14379 word = 0;
14380 } else if (tid == 7) { /* Check if done with sdtr_speed2. */
14381 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
14382 word = 0;
14383 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
14384 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
14385 word = 0;
14386 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
14387 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
14388 /* End of loop. */
14393 * Set microcode operating variable for the disconnect per TID bitmask.
14395 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
14396 asc_dvc->cfg->disc_enable);
14399 * Set SCSI_CFG0 Microcode Default Value.
14401 * The microcode will set the SCSI_CFG0 register using this value
14402 * after it is started below.
14404 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14405 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14406 asc_dvc->chip_scsi_id);
14409 * Determine SCSI_CFG1 Microcode Default Value.
14411 * The microcode will set the SCSI_CFG1 register using this value
14412 * after it is started below.
14415 /* Read current SCSI_CFG1 Register value. */
14416 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14419 * If all three connectors are in use, return an error.
14421 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
14422 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
14423 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
14424 return ADV_ERROR;
14428 * If the internal narrow cable is reversed all of the SCSI_CTRL
14429 * register signals will be set. Check for and return an error if
14430 * this condition is found.
14432 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
14433 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14434 return ADV_ERROR;
14438 * If this is a differential board and a single-ended device
14439 * is attached to one of the connectors, return an error.
14441 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
14442 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
14443 return ADV_ERROR;
14447 * If automatic termination control is enabled, then set the
14448 * termination value based on a table listed in a_condor.h.
14450 * If manual termination was specified with an EEPROM setting
14451 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
14452 * is ready to be 'ored' into SCSI_CFG1.
14454 if (asc_dvc->cfg->termination == 0) {
14456 * The software always controls termination by setting TERM_CTL_SEL.
14457 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
14459 asc_dvc->cfg->termination |= TERM_CTL_SEL;
14461 switch (scsi_cfg1 & CABLE_DETECT) {
14462 /* TERM_CTL_H: on, TERM_CTL_L: on */
14463 case 0x3:
14464 case 0x7:
14465 case 0xB:
14466 case 0xD:
14467 case 0xE:
14468 case 0xF:
14469 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
14470 break;
14472 /* TERM_CTL_H: on, TERM_CTL_L: off */
14473 case 0x1:
14474 case 0x5:
14475 case 0x9:
14476 case 0xA:
14477 case 0xC:
14478 asc_dvc->cfg->termination |= TERM_CTL_H;
14479 break;
14481 /* TERM_CTL_H: off, TERM_CTL_L: off */
14482 case 0x2:
14483 case 0x6:
14484 break;
14489 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
14491 scsi_cfg1 &= ~TERM_CTL;
14494 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
14495 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
14496 * referenced, because the hardware internally inverts
14497 * the Termination High and Low bits if TERM_POL is set.
14499 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
14502 * Set SCSI_CFG1 Microcode Default Value
14504 * Set filter value and possibly modified termination control
14505 * bits in the Microcode SCSI_CFG1 Register Value.
14507 * The microcode will set the SCSI_CFG1 register using this value
14508 * after it is started below.
14510 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
14511 FLTR_DISABLE | scsi_cfg1);
14514 * Set MEM_CFG Microcode Default Value
14516 * The microcode will set the MEM_CFG register using this value
14517 * after it is started below.
14519 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
14520 * are defined.
14522 * ASC-3550 has 8KB internal memory.
14524 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
14525 BIOS_EN | RAM_SZ_8KB);
14528 * Set SEL_MASK Microcode Default Value
14530 * The microcode will set the SEL_MASK register using this value
14531 * after it is started below.
14533 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
14534 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
14537 * Build carrier freelist.
14539 * Driver must have already allocated memory and set 'carrier_buf'.
14541 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
14543 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
14544 asc_dvc->carr_freelist = NULL;
14545 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
14546 buf_size = ADV_CARRIER_BUFSIZE;
14547 } else {
14548 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
14551 do {
14553 * Get physical address of the carrier 'carrp'.
14555 contig_len = sizeof(ADV_CARR_T);
14556 carr_paddr =
14557 cpu_to_le32(DvcGetPhyAddr
14558 (asc_dvc, NULL, (uchar *)carrp,
14559 (ADV_SDCNT *)&contig_len,
14560 ADV_IS_CARRIER_FLAG));
14562 buf_size -= sizeof(ADV_CARR_T);
14565 * If the current carrier is not physically contiguous, then
14566 * maybe there was a page crossing. Try the next carrier aligned
14567 * start address.
14569 if (contig_len < sizeof(ADV_CARR_T)) {
14570 carrp++;
14571 continue;
14574 carrp->carr_pa = carr_paddr;
14575 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
14578 * Insert the carrier at the beginning of the freelist.
14580 carrp->next_vpa =
14581 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
14582 asc_dvc->carr_freelist = carrp;
14584 carrp++;
14586 while (buf_size > 0);
14589 * Set-up the Host->RISC Initiator Command Queue (ICQ).
14592 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
14593 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14594 return ADV_ERROR;
14596 asc_dvc->carr_freelist = (ADV_CARR_T *)
14597 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
14600 * The first command issued will be placed in the stopper carrier.
14602 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14605 * Set RISC ICQ physical address start value.
14607 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
14610 * Set-up the RISC->Host Initiator Response Queue (IRQ).
14612 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
14613 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14614 return ADV_ERROR;
14616 asc_dvc->carr_freelist = (ADV_CARR_T *)
14617 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
14620 * The first command completed by the RISC will be placed in
14621 * the stopper.
14623 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
14624 * completed the RISC will set the ASC_RQ_STOPPER bit.
14626 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14629 * Set RISC IRQ physical address start value.
14631 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
14632 asc_dvc->carr_pending_cnt = 0;
14634 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
14635 (ADV_INTR_ENABLE_HOST_INTR |
14636 ADV_INTR_ENABLE_GLOBAL_INTR));
14638 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
14639 AdvWriteWordRegister(iop_base, IOPW_PC, word);
14641 /* finally, finally, gentlemen, start your engine */
14642 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
14645 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
14646 * Resets should be performed. The RISC has to be running
14647 * to issue a SCSI Bus Reset.
14649 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
14651 * If the BIOS Signature is present in memory, restore the
14652 * BIOS Handshake Configuration Table and do not perform
14653 * a SCSI Bus Reset.
14655 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
14656 0x55AA) {
14658 * Restore per TID negotiated values.
14660 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14661 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14662 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
14663 tagqng_able);
14664 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14665 AdvWriteByteLram(iop_base,
14666 ASC_MC_NUMBER_OF_MAX_CMD + tid,
14667 max_cmd[tid]);
14669 } else {
14670 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
14671 warn_code = ASC_WARN_BUSRESET_ERROR;
14676 return warn_code;
14680 * Initialize the ASC-38C0800.
14682 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14684 * For a non-fatal error return a warning code. If there are no warnings
14685 * then 0 is returned.
14687 * Needed after initialization for error recovery.
14689 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
14691 AdvPortAddr iop_base;
14692 ushort warn_code;
14693 ADV_DCNT sum;
14694 int begin_addr;
14695 int end_addr;
14696 ushort code_sum;
14697 int word;
14698 int j;
14699 int adv_asc38C0800_expanded_size;
14700 ADV_CARR_T *carrp;
14701 ADV_DCNT contig_len;
14702 ADV_SDCNT buf_size;
14703 ADV_PADDR carr_paddr;
14704 int i;
14705 ushort scsi_cfg1;
14706 uchar byte;
14707 uchar tid;
14708 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
14709 ushort wdtr_able, sdtr_able, tagqng_able;
14710 uchar max_cmd[ADV_MAX_TID + 1];
14712 /* If there is already an error, don't continue. */
14713 if (asc_dvc->err_code != 0) {
14714 return ADV_ERROR;
14718 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
14720 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
14721 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
14722 return ADV_ERROR;
14725 warn_code = 0;
14726 iop_base = asc_dvc->iop_base;
14729 * Save the RISC memory BIOS region before writing the microcode.
14730 * The BIOS may already be loaded and using its RISC LRAM region
14731 * so its region must be saved and restored.
14733 * Note: This code makes the assumption, which is currently true,
14734 * that a chip reset does not clear RISC LRAM.
14736 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14737 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14738 bios_mem[i]);
14742 * Save current per TID negotiated values.
14744 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14745 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14746 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14747 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14748 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14749 max_cmd[tid]);
14753 * RAM BIST (RAM Built-In Self Test)
14755 * Address : I/O base + offset 0x38h register (byte).
14756 * Function: Bit 7-6(RW) : RAM mode
14757 * Normal Mode : 0x00
14758 * Pre-test Mode : 0x40
14759 * RAM Test Mode : 0x80
14760 * Bit 5 : unused
14761 * Bit 4(RO) : Done bit
14762 * Bit 3-0(RO) : Status
14763 * Host Error : 0x08
14764 * Int_RAM Error : 0x04
14765 * RISC Error : 0x02
14766 * SCSI Error : 0x01
14767 * No Error : 0x00
14769 * Note: RAM BIST code should be put right here, before loading the
14770 * microcode and after saving the RISC memory BIOS region.
14774 * LRAM Pre-test
14776 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
14777 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
14778 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
14779 * to NORMAL_MODE, return an error too.
14781 for (i = 0; i < 2; i++) {
14782 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
14783 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14784 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14785 if ((byte & RAM_TEST_DONE) == 0
14786 || (byte & 0x0F) != PRE_TEST_VALUE) {
14787 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14788 return ADV_ERROR;
14791 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14792 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14793 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
14794 != NORMAL_VALUE) {
14795 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14796 return ADV_ERROR;
14801 * LRAM Test - It takes about 1.5 ms to run through the test.
14803 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
14804 * If Done bit not set or Status not 0, save register byte, set the
14805 * err_code, and return an error.
14807 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
14808 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
14810 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14811 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
14812 /* Get here if Done bit not set or Status not 0. */
14813 asc_dvc->bist_err_code = byte; /* for BIOS display message */
14814 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
14815 return ADV_ERROR;
14818 /* We need to reset back to normal mode after LRAM test passes. */
14819 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14822 * Load the Microcode
14824 * Write the microcode image to RISC memory starting at address 0.
14827 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14829 /* Assume the following compressed format of the microcode buffer:
14831 * 254 word (508 byte) table indexed by byte code followed
14832 * by the following byte codes:
14834 * 1-Byte Code:
14835 * 00: Emit word 0 in table.
14836 * 01: Emit word 1 in table.
14838 * FD: Emit word 253 in table.
14840 * Multi-Byte Code:
14841 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14842 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14844 word = 0;
14845 for (i = 253 * 2; i < _adv_asc38C0800_size; i++) {
14846 if (_adv_asc38C0800_buf[i] == 0xff) {
14847 for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++) {
14848 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14849 _adv_asc38C0800_buf
14850 [i +
14851 3] << 8) |
14852 _adv_asc38C0800_buf
14853 [i + 2]));
14854 word++;
14856 i += 3;
14857 } else if (_adv_asc38C0800_buf[i] == 0xfe) {
14858 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14859 _adv_asc38C0800_buf
14860 [i +
14861 2] << 8) |
14862 _adv_asc38C0800_buf[i
14864 1]));
14865 i += 2;
14866 word++;
14867 } else {
14868 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14869 _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) | _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
14870 word++;
14875 * Set 'word' for later use to clear the rest of memory and save
14876 * the expanded mcode size.
14878 word *= 2;
14879 adv_asc38C0800_expanded_size = word;
14882 * Clear the rest of ASC-38C0800 Internal RAM (16KB).
14884 for (; word < ADV_38C0800_MEMSIZE; word += 2) {
14885 AdvWriteWordAutoIncLram(iop_base, 0);
14889 * Verify the microcode checksum.
14891 sum = 0;
14892 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14894 for (word = 0; word < adv_asc38C0800_expanded_size; word += 2) {
14895 sum += AdvReadWordAutoIncLram(iop_base);
14897 ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
14899 ASC_DBG2(1,
14900 "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
14901 (ulong)sum, (ulong)_adv_asc38C0800_chksum);
14903 if (sum != _adv_asc38C0800_chksum) {
14904 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14905 return ADV_ERROR;
14909 * Restore the RISC memory BIOS region.
14911 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14912 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14913 bios_mem[i]);
14917 * Calculate and write the microcode code checksum to the microcode
14918 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14920 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14921 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14922 code_sum = 0;
14923 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14924 for (word = begin_addr; word < end_addr; word += 2) {
14925 code_sum += AdvReadWordAutoIncLram(iop_base);
14927 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14930 * Read microcode version and date.
14932 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
14933 asc_dvc->cfg->mcode_date);
14934 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
14935 asc_dvc->cfg->mcode_version);
14938 * Set the chip type to indicate the ASC38C0800.
14940 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
14943 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
14944 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
14945 * cable detection and then we are able to read C_DET[3:0].
14947 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
14948 * Microcode Default Value' section below.
14950 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14951 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
14952 scsi_cfg1 | DIS_TERM_DRV);
14955 * If the PCI Configuration Command Register "Parity Error Response
14956 * Control" Bit was clear (0), then set the microcode variable
14957 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14958 * to ignore DMA parity errors.
14960 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
14961 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14962 word |= CONTROL_FLAG_IGNORE_PERR;
14963 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14967 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
14968 * bits for the default FIFO threshold.
14970 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
14972 * For DMA Errata #4 set the BC_THRESH_ENB bit.
14974 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14975 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
14976 READ_CMD_MRM);
14979 * Microcode operating variables for WDTR, SDTR, and command tag
14980 * queuing will be set in AdvInquiryHandling() based on what a
14981 * device reports it is capable of in Inquiry byte 7.
14983 * If SCSI Bus Resets have been disabled, then directly set
14984 * SDTR and WDTR from the EEPROM configuration. This will allow
14985 * the BIOS and warm boot to work without a SCSI bus hang on
14986 * the Inquiry caused by host and target mismatched DTR values.
14987 * Without the SCSI Bus Reset, before an Inquiry a device can't
14988 * be assumed to be in Asynchronous, Narrow mode.
14990 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
14991 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
14992 asc_dvc->wdtr_able);
14993 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
14994 asc_dvc->sdtr_able);
14998 * Set microcode operating variables for DISC and SDTR_SPEED1,
14999 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15000 * configuration values.
15002 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15003 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15004 * without determining here whether the device supports SDTR.
15006 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
15007 asc_dvc->cfg->disc_enable);
15008 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15009 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15010 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15011 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15014 * Set SCSI_CFG0 Microcode Default Value.
15016 * The microcode will set the SCSI_CFG0 register using this value
15017 * after it is started below.
15019 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15020 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15021 asc_dvc->chip_scsi_id);
15024 * Determine SCSI_CFG1 Microcode Default Value.
15026 * The microcode will set the SCSI_CFG1 register using this value
15027 * after it is started below.
15030 /* Read current SCSI_CFG1 Register value. */
15031 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15034 * If the internal narrow cable is reversed all of the SCSI_CTRL
15035 * register signals will be set. Check for and return an error if
15036 * this condition is found.
15038 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
15039 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15040 return ADV_ERROR;
15044 * All kind of combinations of devices attached to one of four connectors
15045 * are acceptable except HVD device attached. For example, LVD device can
15046 * be attached to SE connector while SE device attached to LVD connector.
15047 * If LVD device attached to SE connector, it only runs up to Ultra speed.
15049 * If an HVD device is attached to one of LVD connectors, return an error.
15050 * However, there is no way to detect HVD device attached to SE connectors.
15052 if (scsi_cfg1 & HVD) {
15053 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15054 return ADV_ERROR;
15058 * If either SE or LVD automatic termination control is enabled, then
15059 * set the termination value based on a table listed in a_condor.h.
15061 * If manual termination was specified with an EEPROM setting then
15062 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
15063 * be 'ored' into SCSI_CFG1.
15065 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
15066 /* SE automatic termination control is enabled. */
15067 switch (scsi_cfg1 & C_DET_SE) {
15068 /* TERM_SE_HI: on, TERM_SE_LO: on */
15069 case 0x1:
15070 case 0x2:
15071 case 0x3:
15072 asc_dvc->cfg->termination |= TERM_SE;
15073 break;
15075 /* TERM_SE_HI: on, TERM_SE_LO: off */
15076 case 0x0:
15077 asc_dvc->cfg->termination |= TERM_SE_HI;
15078 break;
15082 if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
15083 /* LVD automatic termination control is enabled. */
15084 switch (scsi_cfg1 & C_DET_LVD) {
15085 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
15086 case 0x4:
15087 case 0x8:
15088 case 0xC:
15089 asc_dvc->cfg->termination |= TERM_LVD;
15090 break;
15092 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
15093 case 0x0:
15094 break;
15099 * Clear any set TERM_SE and TERM_LVD bits.
15101 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
15104 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
15106 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
15109 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
15110 * and set possibly modified termination control bits in the Microcode
15111 * SCSI_CFG1 Register Value.
15113 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
15116 * Set SCSI_CFG1 Microcode Default Value
15118 * Set possibly modified termination control and reset DIS_TERM_DRV
15119 * bits in the Microcode SCSI_CFG1 Register Value.
15121 * The microcode will set the SCSI_CFG1 register using this value
15122 * after it is started below.
15124 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15127 * Set MEM_CFG Microcode Default Value
15129 * The microcode will set the MEM_CFG register using this value
15130 * after it is started below.
15132 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15133 * are defined.
15135 * ASC-38C0800 has 16KB internal memory.
15137 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15138 BIOS_EN | RAM_SZ_16KB);
15141 * Set SEL_MASK Microcode Default Value
15143 * The microcode will set the SEL_MASK register using this value
15144 * after it is started below.
15146 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15147 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15150 * Build the carrier freelist.
15152 * Driver must have already allocated memory and set 'carrier_buf'.
15154 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15156 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15157 asc_dvc->carr_freelist = NULL;
15158 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
15159 buf_size = ADV_CARRIER_BUFSIZE;
15160 } else {
15161 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15164 do {
15166 * Get physical address for the carrier 'carrp'.
15168 contig_len = sizeof(ADV_CARR_T);
15169 carr_paddr =
15170 cpu_to_le32(DvcGetPhyAddr
15171 (asc_dvc, NULL, (uchar *)carrp,
15172 (ADV_SDCNT *)&contig_len,
15173 ADV_IS_CARRIER_FLAG));
15175 buf_size -= sizeof(ADV_CARR_T);
15178 * If the current carrier is not physically contiguous, then
15179 * maybe there was a page crossing. Try the next carrier aligned
15180 * start address.
15182 if (contig_len < sizeof(ADV_CARR_T)) {
15183 carrp++;
15184 continue;
15187 carrp->carr_pa = carr_paddr;
15188 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15191 * Insert the carrier at the beginning of the freelist.
15193 carrp->next_vpa =
15194 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15195 asc_dvc->carr_freelist = carrp;
15197 carrp++;
15199 while (buf_size > 0);
15202 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15205 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
15206 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15207 return ADV_ERROR;
15209 asc_dvc->carr_freelist = (ADV_CARR_T *)
15210 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15213 * The first command issued will be placed in the stopper carrier.
15215 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15218 * Set RISC ICQ physical address start value.
15219 * carr_pa is LE, must be native before write
15221 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15224 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15226 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
15227 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15228 return ADV_ERROR;
15230 asc_dvc->carr_freelist = (ADV_CARR_T *)
15231 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15234 * The first command completed by the RISC will be placed in
15235 * the stopper.
15237 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15238 * completed the RISC will set the ASC_RQ_STOPPER bit.
15240 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15243 * Set RISC IRQ physical address start value.
15245 * carr_pa is LE, must be native before write *
15247 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15248 asc_dvc->carr_pending_cnt = 0;
15250 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15251 (ADV_INTR_ENABLE_HOST_INTR |
15252 ADV_INTR_ENABLE_GLOBAL_INTR));
15254 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15255 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15257 /* finally, finally, gentlemen, start your engine */
15258 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15261 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15262 * Resets should be performed. The RISC has to be running
15263 * to issue a SCSI Bus Reset.
15265 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
15267 * If the BIOS Signature is present in memory, restore the
15268 * BIOS Handshake Configuration Table and do not perform
15269 * a SCSI Bus Reset.
15271 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
15272 0x55AA) {
15274 * Restore per TID negotiated values.
15276 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15277 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15278 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
15279 tagqng_able);
15280 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
15281 AdvWriteByteLram(iop_base,
15282 ASC_MC_NUMBER_OF_MAX_CMD + tid,
15283 max_cmd[tid]);
15285 } else {
15286 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
15287 warn_code = ASC_WARN_BUSRESET_ERROR;
15292 return warn_code;
15296 * Initialize the ASC-38C1600.
15298 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
15300 * For a non-fatal error return a warning code. If there are no warnings
15301 * then 0 is returned.
15303 * Needed after initialization for error recovery.
15305 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
15307 AdvPortAddr iop_base;
15308 ushort warn_code;
15309 ADV_DCNT sum;
15310 int begin_addr;
15311 int end_addr;
15312 ushort code_sum;
15313 long word;
15314 int j;
15315 int adv_asc38C1600_expanded_size;
15316 ADV_CARR_T *carrp;
15317 ADV_DCNT contig_len;
15318 ADV_SDCNT buf_size;
15319 ADV_PADDR carr_paddr;
15320 int i;
15321 ushort scsi_cfg1;
15322 uchar byte;
15323 uchar tid;
15324 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
15325 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
15326 uchar max_cmd[ASC_MAX_TID + 1];
15328 /* If there is already an error, don't continue. */
15329 if (asc_dvc->err_code != 0) {
15330 return ADV_ERROR;
15334 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
15336 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
15337 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
15338 return ADV_ERROR;
15341 warn_code = 0;
15342 iop_base = asc_dvc->iop_base;
15345 * Save the RISC memory BIOS region before writing the microcode.
15346 * The BIOS may already be loaded and using its RISC LRAM region
15347 * so its region must be saved and restored.
15349 * Note: This code makes the assumption, which is currently true,
15350 * that a chip reset does not clear RISC LRAM.
15352 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15353 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15354 bios_mem[i]);
15358 * Save current per TID negotiated values.
15360 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15361 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15362 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15363 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15364 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15365 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15366 max_cmd[tid]);
15370 * RAM BIST (Built-In Self Test)
15372 * Address : I/O base + offset 0x38h register (byte).
15373 * Function: Bit 7-6(RW) : RAM mode
15374 * Normal Mode : 0x00
15375 * Pre-test Mode : 0x40
15376 * RAM Test Mode : 0x80
15377 * Bit 5 : unused
15378 * Bit 4(RO) : Done bit
15379 * Bit 3-0(RO) : Status
15380 * Host Error : 0x08
15381 * Int_RAM Error : 0x04
15382 * RISC Error : 0x02
15383 * SCSI Error : 0x01
15384 * No Error : 0x00
15386 * Note: RAM BIST code should be put right here, before loading the
15387 * microcode and after saving the RISC memory BIOS region.
15391 * LRAM Pre-test
15393 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15394 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15395 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15396 * to NORMAL_MODE, return an error too.
15398 for (i = 0; i < 2; i++) {
15399 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15400 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15401 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15402 if ((byte & RAM_TEST_DONE) == 0
15403 || (byte & 0x0F) != PRE_TEST_VALUE) {
15404 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15405 return ADV_ERROR;
15408 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15409 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15410 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15411 != NORMAL_VALUE) {
15412 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15413 return ADV_ERROR;
15418 * LRAM Test - It takes about 1.5 ms to run through the test.
15420 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15421 * If Done bit not set or Status not 0, save register byte, set the
15422 * err_code, and return an error.
15424 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15425 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
15427 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15428 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
15429 /* Get here if Done bit not set or Status not 0. */
15430 asc_dvc->bist_err_code = byte; /* for BIOS display message */
15431 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15432 return ADV_ERROR;
15435 /* We need to reset back to normal mode after LRAM test passes. */
15436 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15439 * Load the Microcode
15441 * Write the microcode image to RISC memory starting at address 0.
15444 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15447 * Assume the following compressed format of the microcode buffer:
15449 * 254 word (508 byte) table indexed by byte code followed
15450 * by the following byte codes:
15452 * 1-Byte Code:
15453 * 00: Emit word 0 in table.
15454 * 01: Emit word 1 in table.
15456 * FD: Emit word 253 in table.
15458 * Multi-Byte Code:
15459 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15460 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15462 word = 0;
15463 for (i = 253 * 2; i < _adv_asc38C1600_size; i++) {
15464 if (_adv_asc38C1600_buf[i] == 0xff) {
15465 for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++) {
15466 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15467 _adv_asc38C1600_buf
15468 [i +
15469 3] << 8) |
15470 _adv_asc38C1600_buf
15471 [i + 2]));
15472 word++;
15474 i += 3;
15475 } else if (_adv_asc38C1600_buf[i] == 0xfe) {
15476 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15477 _adv_asc38C1600_buf
15478 [i +
15479 2] << 8) |
15480 _adv_asc38C1600_buf[i
15482 1]));
15483 i += 2;
15484 word++;
15485 } else {
15486 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15487 _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) | _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
15488 word++;
15493 * Set 'word' for later use to clear the rest of memory and save
15494 * the expanded mcode size.
15496 word *= 2;
15497 adv_asc38C1600_expanded_size = word;
15500 * Clear the rest of ASC-38C1600 Internal RAM (32KB).
15502 for (; word < ADV_38C1600_MEMSIZE; word += 2) {
15503 AdvWriteWordAutoIncLram(iop_base, 0);
15507 * Verify the microcode checksum.
15509 sum = 0;
15510 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15512 for (word = 0; word < adv_asc38C1600_expanded_size; word += 2) {
15513 sum += AdvReadWordAutoIncLram(iop_base);
15516 if (sum != _adv_asc38C1600_chksum) {
15517 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15518 return ADV_ERROR;
15522 * Restore the RISC memory BIOS region.
15524 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15525 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15526 bios_mem[i]);
15530 * Calculate and write the microcode code checksum to the microcode
15531 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15533 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15534 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15535 code_sum = 0;
15536 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15537 for (word = begin_addr; word < end_addr; word += 2) {
15538 code_sum += AdvReadWordAutoIncLram(iop_base);
15540 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15543 * Read microcode version and date.
15545 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
15546 asc_dvc->cfg->mcode_date);
15547 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
15548 asc_dvc->cfg->mcode_version);
15551 * Set the chip type to indicate the ASC38C1600.
15553 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
15556 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15557 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15558 * cable detection and then we are able to read C_DET[3:0].
15560 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15561 * Microcode Default Value' section below.
15563 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15564 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
15565 scsi_cfg1 | DIS_TERM_DRV);
15568 * If the PCI Configuration Command Register "Parity Error Response
15569 * Control" Bit was clear (0), then set the microcode variable
15570 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15571 * to ignore DMA parity errors.
15573 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
15574 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15575 word |= CONTROL_FLAG_IGNORE_PERR;
15576 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15580 * If the BIOS control flag AIPP (Asynchronous Information
15581 * Phase Protection) disable bit is not set, then set the firmware
15582 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
15583 * AIPP checking and encoding.
15585 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
15586 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15587 word |= CONTROL_FLAG_ENABLE_AIPP;
15588 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15592 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
15593 * and START_CTL_TH [3:2].
15595 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15596 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
15599 * Microcode operating variables for WDTR, SDTR, and command tag
15600 * queuing will be set in AdvInquiryHandling() based on what a
15601 * device reports it is capable of in Inquiry byte 7.
15603 * If SCSI Bus Resets have been disabled, then directly set
15604 * SDTR and WDTR from the EEPROM configuration. This will allow
15605 * the BIOS and warm boot to work without a SCSI bus hang on
15606 * the Inquiry caused by host and target mismatched DTR values.
15607 * Without the SCSI Bus Reset, before an Inquiry a device can't
15608 * be assumed to be in Asynchronous, Narrow mode.
15610 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
15611 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
15612 asc_dvc->wdtr_able);
15613 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
15614 asc_dvc->sdtr_able);
15618 * Set microcode operating variables for DISC and SDTR_SPEED1,
15619 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15620 * configuration values.
15622 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15623 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15624 * without determining here whether the device supports SDTR.
15626 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
15627 asc_dvc->cfg->disc_enable);
15628 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15629 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15630 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15631 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15634 * Set SCSI_CFG0 Microcode Default Value.
15636 * The microcode will set the SCSI_CFG0 register using this value
15637 * after it is started below.
15639 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15640 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15641 asc_dvc->chip_scsi_id);
15644 * Calculate SCSI_CFG1 Microcode Default Value.
15646 * The microcode will set the SCSI_CFG1 register using this value
15647 * after it is started below.
15649 * Each ASC-38C1600 function has only two cable detect bits.
15650 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
15652 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15655 * If the cable is reversed all of the SCSI_CTRL register signals
15656 * will be set. Check for and return an error if this condition is
15657 * found.
15659 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
15660 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15661 return ADV_ERROR;
15665 * Each ASC-38C1600 function has two connectors. Only an HVD device
15666 * can not be connected to either connector. An LVD device or SE device
15667 * may be connected to either connecor. If an SE device is connected,
15668 * then at most Ultra speed (20 Mhz) can be used on both connectors.
15670 * If an HVD device is attached, return an error.
15672 if (scsi_cfg1 & HVD) {
15673 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15674 return ADV_ERROR;
15678 * Each function in the ASC-38C1600 uses only the SE cable detect and
15679 * termination because there are two connectors for each function. Each
15680 * function may use either LVD or SE mode. Corresponding the SE automatic
15681 * termination control EEPROM bits are used for each function. Each
15682 * function has its own EEPROM. If SE automatic control is enabled for
15683 * the function, then set the termination value based on a table listed
15684 * in a_condor.h.
15686 * If manual termination is specified in the EEPROM for the function,
15687 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
15688 * ready to be 'ored' into SCSI_CFG1.
15690 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
15691 /* SE automatic termination control is enabled. */
15692 switch (scsi_cfg1 & C_DET_SE) {
15693 /* TERM_SE_HI: on, TERM_SE_LO: on */
15694 case 0x1:
15695 case 0x2:
15696 case 0x3:
15697 asc_dvc->cfg->termination |= TERM_SE;
15698 break;
15700 case 0x0:
15701 if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0) {
15702 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
15703 } else {
15704 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
15705 asc_dvc->cfg->termination |= TERM_SE_HI;
15707 break;
15712 * Clear any set TERM_SE bits.
15714 scsi_cfg1 &= ~TERM_SE;
15717 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
15719 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
15722 * Clear Big Endian and Terminator Polarity bits and set possibly
15723 * modified termination control bits in the Microcode SCSI_CFG1
15724 * Register Value.
15726 * Big Endian bit is not used even on big endian machines.
15728 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
15731 * Set SCSI_CFG1 Microcode Default Value
15733 * Set possibly modified termination control bits in the Microcode
15734 * SCSI_CFG1 Register Value.
15736 * The microcode will set the SCSI_CFG1 register using this value
15737 * after it is started below.
15739 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15742 * Set MEM_CFG Microcode Default Value
15744 * The microcode will set the MEM_CFG register using this value
15745 * after it is started below.
15747 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15748 * are defined.
15750 * ASC-38C1600 has 32KB internal memory.
15752 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
15753 * out a special 16K Adv Library and Microcode version. After the issue
15754 * resolved, we should turn back to the 32K support. Both a_condor.h and
15755 * mcode.sas files also need to be updated.
15757 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15758 * BIOS_EN | RAM_SZ_32KB);
15760 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15761 BIOS_EN | RAM_SZ_16KB);
15764 * Set SEL_MASK Microcode Default Value
15766 * The microcode will set the SEL_MASK register using this value
15767 * after it is started below.
15769 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15770 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15773 * Build the carrier freelist.
15775 * Driver must have already allocated memory and set 'carrier_buf'.
15778 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15780 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15781 asc_dvc->carr_freelist = NULL;
15782 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
15783 buf_size = ADV_CARRIER_BUFSIZE;
15784 } else {
15785 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15788 do {
15790 * Get physical address for the carrier 'carrp'.
15792 contig_len = sizeof(ADV_CARR_T);
15793 carr_paddr =
15794 cpu_to_le32(DvcGetPhyAddr
15795 (asc_dvc, NULL, (uchar *)carrp,
15796 (ADV_SDCNT *)&contig_len,
15797 ADV_IS_CARRIER_FLAG));
15799 buf_size -= sizeof(ADV_CARR_T);
15802 * If the current carrier is not physically contiguous, then
15803 * maybe there was a page crossing. Try the next carrier aligned
15804 * start address.
15806 if (contig_len < sizeof(ADV_CARR_T)) {
15807 carrp++;
15808 continue;
15811 carrp->carr_pa = carr_paddr;
15812 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15815 * Insert the carrier at the beginning of the freelist.
15817 carrp->next_vpa =
15818 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15819 asc_dvc->carr_freelist = carrp;
15821 carrp++;
15823 while (buf_size > 0);
15826 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15828 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
15829 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15830 return ADV_ERROR;
15832 asc_dvc->carr_freelist = (ADV_CARR_T *)
15833 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15836 * The first command issued will be placed in the stopper carrier.
15838 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15841 * Set RISC ICQ physical address start value. Initialize the
15842 * COMMA register to the same value otherwise the RISC will
15843 * prematurely detect a command is available.
15845 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15846 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
15847 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
15850 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15852 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
15853 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15854 return ADV_ERROR;
15856 asc_dvc->carr_freelist = (ADV_CARR_T *)
15857 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15860 * The first command completed by the RISC will be placed in
15861 * the stopper.
15863 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15864 * completed the RISC will set the ASC_RQ_STOPPER bit.
15866 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15869 * Set RISC IRQ physical address start value.
15871 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15872 asc_dvc->carr_pending_cnt = 0;
15874 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15875 (ADV_INTR_ENABLE_HOST_INTR |
15876 ADV_INTR_ENABLE_GLOBAL_INTR));
15877 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15878 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15880 /* finally, finally, gentlemen, start your engine */
15881 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15884 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15885 * Resets should be performed. The RISC has to be running
15886 * to issue a SCSI Bus Reset.
15888 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
15890 * If the BIOS Signature is present in memory, restore the
15891 * per TID microcode operating variables.
15893 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
15894 0x55AA) {
15896 * Restore per TID negotiated values.
15898 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15899 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15900 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15901 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
15902 tagqng_able);
15903 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15904 AdvWriteByteLram(iop_base,
15905 ASC_MC_NUMBER_OF_MAX_CMD + tid,
15906 max_cmd[tid]);
15908 } else {
15909 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
15910 warn_code = ASC_WARN_BUSRESET_ERROR;
15915 return warn_code;
15919 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
15920 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
15921 * all of this is done.
15923 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15925 * For a non-fatal error return a warning code. If there are no warnings
15926 * then 0 is returned.
15928 * Note: Chip is stopped on entry.
15930 static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
15932 AdvPortAddr iop_base;
15933 ushort warn_code;
15934 ADVEEP_3550_CONFIG eep_config;
15935 int i;
15937 iop_base = asc_dvc->iop_base;
15939 warn_code = 0;
15942 * Read the board's EEPROM configuration.
15944 * Set default values if a bad checksum is found.
15946 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
15947 warn_code |= ASC_WARN_EEPROM_CHKSUM;
15950 * Set EEPROM default values.
15952 for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++) {
15953 *((uchar *)&eep_config + i) =
15954 *((uchar *)&Default_3550_EEPROM_Config + i);
15958 * Assume the 6 byte board serial number that was read
15959 * from EEPROM is correct even if the EEPROM checksum
15960 * failed.
15962 eep_config.serial_number_word3 =
15963 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
15965 eep_config.serial_number_word2 =
15966 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
15968 eep_config.serial_number_word1 =
15969 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
15971 AdvSet3550EEPConfig(iop_base, &eep_config);
15974 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
15975 * EEPROM configuration that was read.
15977 * This is the mapping of EEPROM fields to Adv Library fields.
15979 asc_dvc->wdtr_able = eep_config.wdtr_able;
15980 asc_dvc->sdtr_able = eep_config.sdtr_able;
15981 asc_dvc->ultra_able = eep_config.ultra_able;
15982 asc_dvc->tagqng_able = eep_config.tagqng_able;
15983 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
15984 asc_dvc->max_host_qng = eep_config.max_host_qng;
15985 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15986 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
15987 asc_dvc->start_motor = eep_config.start_motor;
15988 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
15989 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
15990 asc_dvc->no_scam = eep_config.scam_tolerant;
15991 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
15992 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
15993 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
15996 * Set the host maximum queuing (max. 253, min. 16) and the per device
15997 * maximum queuing (max. 63, min. 4).
15999 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
16000 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16001 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
16002 /* If the value is zero, assume it is uninitialized. */
16003 if (eep_config.max_host_qng == 0) {
16004 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16005 } else {
16006 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16010 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
16011 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16012 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
16013 /* If the value is zero, assume it is uninitialized. */
16014 if (eep_config.max_dvc_qng == 0) {
16015 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16016 } else {
16017 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16022 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16023 * set 'max_dvc_qng' to 'max_host_qng'.
16025 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
16026 eep_config.max_dvc_qng = eep_config.max_host_qng;
16030 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16031 * values based on possibly adjusted EEPROM values.
16033 asc_dvc->max_host_qng = eep_config.max_host_qng;
16034 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16037 * If the EEPROM 'termination' field is set to automatic (0), then set
16038 * the ADV_DVC_CFG 'termination' field to automatic also.
16040 * If the termination is specified with a non-zero 'termination'
16041 * value check that a legal value is set and set the ADV_DVC_CFG
16042 * 'termination' field appropriately.
16044 if (eep_config.termination == 0) {
16045 asc_dvc->cfg->termination = 0; /* auto termination */
16046 } else {
16047 /* Enable manual control with low off / high off. */
16048 if (eep_config.termination == 1) {
16049 asc_dvc->cfg->termination = TERM_CTL_SEL;
16051 /* Enable manual control with low off / high on. */
16052 } else if (eep_config.termination == 2) {
16053 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
16055 /* Enable manual control with low on / high on. */
16056 } else if (eep_config.termination == 3) {
16057 asc_dvc->cfg->termination =
16058 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
16059 } else {
16061 * The EEPROM 'termination' field contains a bad value. Use
16062 * automatic termination instead.
16064 asc_dvc->cfg->termination = 0;
16065 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16069 return warn_code;
16073 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16074 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16075 * all of this is done.
16077 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16079 * For a non-fatal error return a warning code. If there are no warnings
16080 * then 0 is returned.
16082 * Note: Chip is stopped on entry.
16084 static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
16086 AdvPortAddr iop_base;
16087 ushort warn_code;
16088 ADVEEP_38C0800_CONFIG eep_config;
16089 int i;
16090 uchar tid, termination;
16091 ushort sdtr_speed = 0;
16093 iop_base = asc_dvc->iop_base;
16095 warn_code = 0;
16098 * Read the board's EEPROM configuration.
16100 * Set default values if a bad checksum is found.
16102 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
16103 eep_config.check_sum) {
16104 warn_code |= ASC_WARN_EEPROM_CHKSUM;
16107 * Set EEPROM default values.
16109 for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++) {
16110 *((uchar *)&eep_config + i) =
16111 *((uchar *)&Default_38C0800_EEPROM_Config + i);
16115 * Assume the 6 byte board serial number that was read
16116 * from EEPROM is correct even if the EEPROM checksum
16117 * failed.
16119 eep_config.serial_number_word3 =
16120 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16122 eep_config.serial_number_word2 =
16123 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16125 eep_config.serial_number_word1 =
16126 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16128 AdvSet38C0800EEPConfig(iop_base, &eep_config);
16131 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
16132 * EEPROM configuration that was read.
16134 * This is the mapping of EEPROM fields to Adv Library fields.
16136 asc_dvc->wdtr_able = eep_config.wdtr_able;
16137 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16138 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16139 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16140 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16141 asc_dvc->tagqng_able = eep_config.tagqng_able;
16142 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16143 asc_dvc->max_host_qng = eep_config.max_host_qng;
16144 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16145 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16146 asc_dvc->start_motor = eep_config.start_motor;
16147 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16148 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16149 asc_dvc->no_scam = eep_config.scam_tolerant;
16150 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16151 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16152 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16155 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16156 * are set, then set an 'sdtr_able' bit for it.
16158 asc_dvc->sdtr_able = 0;
16159 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
16160 if (tid == 0) {
16161 sdtr_speed = asc_dvc->sdtr_speed1;
16162 } else if (tid == 4) {
16163 sdtr_speed = asc_dvc->sdtr_speed2;
16164 } else if (tid == 8) {
16165 sdtr_speed = asc_dvc->sdtr_speed3;
16166 } else if (tid == 12) {
16167 sdtr_speed = asc_dvc->sdtr_speed4;
16169 if (sdtr_speed & ADV_MAX_TID) {
16170 asc_dvc->sdtr_able |= (1 << tid);
16172 sdtr_speed >>= 4;
16176 * Set the host maximum queuing (max. 253, min. 16) and the per device
16177 * maximum queuing (max. 63, min. 4).
16179 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
16180 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16181 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
16182 /* If the value is zero, assume it is uninitialized. */
16183 if (eep_config.max_host_qng == 0) {
16184 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16185 } else {
16186 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16190 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
16191 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16192 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
16193 /* If the value is zero, assume it is uninitialized. */
16194 if (eep_config.max_dvc_qng == 0) {
16195 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16196 } else {
16197 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16202 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16203 * set 'max_dvc_qng' to 'max_host_qng'.
16205 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
16206 eep_config.max_dvc_qng = eep_config.max_host_qng;
16210 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16211 * values based on possibly adjusted EEPROM values.
16213 asc_dvc->max_host_qng = eep_config.max_host_qng;
16214 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16217 * If the EEPROM 'termination' field is set to automatic (0), then set
16218 * the ADV_DVC_CFG 'termination' field to automatic also.
16220 * If the termination is specified with a non-zero 'termination'
16221 * value check that a legal value is set and set the ADV_DVC_CFG
16222 * 'termination' field appropriately.
16224 if (eep_config.termination_se == 0) {
16225 termination = 0; /* auto termination for SE */
16226 } else {
16227 /* Enable manual control with low off / high off. */
16228 if (eep_config.termination_se == 1) {
16229 termination = 0;
16231 /* Enable manual control with low off / high on. */
16232 } else if (eep_config.termination_se == 2) {
16233 termination = TERM_SE_HI;
16235 /* Enable manual control with low on / high on. */
16236 } else if (eep_config.termination_se == 3) {
16237 termination = TERM_SE;
16238 } else {
16240 * The EEPROM 'termination_se' field contains a bad value.
16241 * Use automatic termination instead.
16243 termination = 0;
16244 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16248 if (eep_config.termination_lvd == 0) {
16249 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
16250 } else {
16251 /* Enable manual control with low off / high off. */
16252 if (eep_config.termination_lvd == 1) {
16253 asc_dvc->cfg->termination = termination;
16255 /* Enable manual control with low off / high on. */
16256 } else if (eep_config.termination_lvd == 2) {
16257 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16259 /* Enable manual control with low on / high on. */
16260 } else if (eep_config.termination_lvd == 3) {
16261 asc_dvc->cfg->termination = termination | TERM_LVD;
16262 } else {
16264 * The EEPROM 'termination_lvd' field contains a bad value.
16265 * Use automatic termination instead.
16267 asc_dvc->cfg->termination = termination;
16268 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16272 return warn_code;
16276 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
16277 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
16278 * all of this is done.
16280 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
16282 * For a non-fatal error return a warning code. If there are no warnings
16283 * then 0 is returned.
16285 * Note: Chip is stopped on entry.
16287 static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
16289 AdvPortAddr iop_base;
16290 ushort warn_code;
16291 ADVEEP_38C1600_CONFIG eep_config;
16292 int i;
16293 uchar tid, termination;
16294 ushort sdtr_speed = 0;
16296 iop_base = asc_dvc->iop_base;
16298 warn_code = 0;
16301 * Read the board's EEPROM configuration.
16303 * Set default values if a bad checksum is found.
16305 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
16306 eep_config.check_sum) {
16307 warn_code |= ASC_WARN_EEPROM_CHKSUM;
16310 * Set EEPROM default values.
16312 for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++) {
16313 if (i == 1
16314 && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) !=
16315 0) {
16317 * Set Function 1 EEPROM Word 0 MSB
16319 * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11)
16320 * EEPROM bits.
16322 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and
16323 * old Mac system booting problem. The Expansion ROM must
16324 * be disabled in Function 1 for these systems.
16327 *((uchar *)&eep_config + i) =
16329 ((uchar *)&Default_38C1600_EEPROM_Config
16331 i)) &
16333 (((ADV_EEPROM_BIOS_ENABLE |
16334 ADV_EEPROM_INTAB) >> 8) & 0xFF)));
16337 * Set the INTAB (bit 11) if the GPIO 0 input indicates
16338 * the Function 1 interrupt line is wired to INTA.
16340 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
16341 * 1 - Function 1 interrupt line wired to INT A.
16342 * 0 - Function 1 interrupt line wired to INT B.
16344 * Note: Adapter boards always have Function 0 wired to INTA.
16345 * Put all 5 GPIO bits in input mode and then read
16346 * their input values.
16348 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL,
16350 if (AdvReadByteRegister
16351 (iop_base, IOPB_GPIO_DATA) & 0x01) {
16352 /* Function 1 interrupt wired to INTA; Set EEPROM bit. */
16353 *((uchar *)&eep_config + i) |=
16354 ((ADV_EEPROM_INTAB >> 8) & 0xFF);
16356 } else {
16357 *((uchar *)&eep_config + i) =
16358 *((uchar *)&Default_38C1600_EEPROM_Config
16359 + i);
16364 * Assume the 6 byte board serial number that was read
16365 * from EEPROM is correct even if the EEPROM checksum
16366 * failed.
16368 eep_config.serial_number_word3 =
16369 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16371 eep_config.serial_number_word2 =
16372 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16374 eep_config.serial_number_word1 =
16375 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16377 AdvSet38C1600EEPConfig(iop_base, &eep_config);
16381 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16382 * EEPROM configuration that was read.
16384 * This is the mapping of EEPROM fields to Adv Library fields.
16386 asc_dvc->wdtr_able = eep_config.wdtr_able;
16387 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16388 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16389 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16390 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16391 asc_dvc->ppr_able = 0;
16392 asc_dvc->tagqng_able = eep_config.tagqng_able;
16393 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16394 asc_dvc->max_host_qng = eep_config.max_host_qng;
16395 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16396 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
16397 asc_dvc->start_motor = eep_config.start_motor;
16398 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16399 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16400 asc_dvc->no_scam = eep_config.scam_tolerant;
16403 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16404 * are set, then set an 'sdtr_able' bit for it.
16406 asc_dvc->sdtr_able = 0;
16407 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
16408 if (tid == 0) {
16409 sdtr_speed = asc_dvc->sdtr_speed1;
16410 } else if (tid == 4) {
16411 sdtr_speed = asc_dvc->sdtr_speed2;
16412 } else if (tid == 8) {
16413 sdtr_speed = asc_dvc->sdtr_speed3;
16414 } else if (tid == 12) {
16415 sdtr_speed = asc_dvc->sdtr_speed4;
16417 if (sdtr_speed & ASC_MAX_TID) {
16418 asc_dvc->sdtr_able |= (1 << tid);
16420 sdtr_speed >>= 4;
16424 * Set the host maximum queuing (max. 253, min. 16) and the per device
16425 * maximum queuing (max. 63, min. 4).
16427 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
16428 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16429 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
16430 /* If the value is zero, assume it is uninitialized. */
16431 if (eep_config.max_host_qng == 0) {
16432 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16433 } else {
16434 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16438 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
16439 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16440 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
16441 /* If the value is zero, assume it is uninitialized. */
16442 if (eep_config.max_dvc_qng == 0) {
16443 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16444 } else {
16445 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16450 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16451 * set 'max_dvc_qng' to 'max_host_qng'.
16453 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
16454 eep_config.max_dvc_qng = eep_config.max_host_qng;
16458 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
16459 * values based on possibly adjusted EEPROM values.
16461 asc_dvc->max_host_qng = eep_config.max_host_qng;
16462 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16465 * If the EEPROM 'termination' field is set to automatic (0), then set
16466 * the ASC_DVC_CFG 'termination' field to automatic also.
16468 * If the termination is specified with a non-zero 'termination'
16469 * value check that a legal value is set and set the ASC_DVC_CFG
16470 * 'termination' field appropriately.
16472 if (eep_config.termination_se == 0) {
16473 termination = 0; /* auto termination for SE */
16474 } else {
16475 /* Enable manual control with low off / high off. */
16476 if (eep_config.termination_se == 1) {
16477 termination = 0;
16479 /* Enable manual control with low off / high on. */
16480 } else if (eep_config.termination_se == 2) {
16481 termination = TERM_SE_HI;
16483 /* Enable manual control with low on / high on. */
16484 } else if (eep_config.termination_se == 3) {
16485 termination = TERM_SE;
16486 } else {
16488 * The EEPROM 'termination_se' field contains a bad value.
16489 * Use automatic termination instead.
16491 termination = 0;
16492 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16496 if (eep_config.termination_lvd == 0) {
16497 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
16498 } else {
16499 /* Enable manual control with low off / high off. */
16500 if (eep_config.termination_lvd == 1) {
16501 asc_dvc->cfg->termination = termination;
16503 /* Enable manual control with low off / high on. */
16504 } else if (eep_config.termination_lvd == 2) {
16505 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16507 /* Enable manual control with low on / high on. */
16508 } else if (eep_config.termination_lvd == 3) {
16509 asc_dvc->cfg->termination = termination | TERM_LVD;
16510 } else {
16512 * The EEPROM 'termination_lvd' field contains a bad value.
16513 * Use automatic termination instead.
16515 asc_dvc->cfg->termination = termination;
16516 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16520 return warn_code;
16524 * Read EEPROM configuration into the specified buffer.
16526 * Return a checksum based on the EEPROM configuration read.
16528 static ushort __devinit
16529 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16531 ushort wval, chksum;
16532 ushort *wbuf;
16533 int eep_addr;
16534 ushort *charfields;
16536 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16537 wbuf = (ushort *)cfg_buf;
16538 chksum = 0;
16540 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16541 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16542 wval = AdvReadEEPWord(iop_base, eep_addr);
16543 chksum += wval; /* Checksum is calculated from word values. */
16544 if (*charfields++) {
16545 *wbuf = le16_to_cpu(wval);
16546 } else {
16547 *wbuf = wval;
16550 /* Read checksum word. */
16551 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16552 wbuf++;
16553 charfields++;
16555 /* Read rest of EEPROM not covered by the checksum. */
16556 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16557 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16558 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16559 if (*charfields++) {
16560 *wbuf = le16_to_cpu(*wbuf);
16563 return chksum;
16567 * Read EEPROM configuration into the specified buffer.
16569 * Return a checksum based on the EEPROM configuration read.
16571 static ushort __devinit
16572 AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
16574 ushort wval, chksum;
16575 ushort *wbuf;
16576 int eep_addr;
16577 ushort *charfields;
16579 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16580 wbuf = (ushort *)cfg_buf;
16581 chksum = 0;
16583 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16584 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16585 wval = AdvReadEEPWord(iop_base, eep_addr);
16586 chksum += wval; /* Checksum is calculated from word values. */
16587 if (*charfields++) {
16588 *wbuf = le16_to_cpu(wval);
16589 } else {
16590 *wbuf = wval;
16593 /* Read checksum word. */
16594 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16595 wbuf++;
16596 charfields++;
16598 /* Read rest of EEPROM not covered by the checksum. */
16599 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16600 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16601 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16602 if (*charfields++) {
16603 *wbuf = le16_to_cpu(*wbuf);
16606 return chksum;
16610 * Read EEPROM configuration into the specified buffer.
16612 * Return a checksum based on the EEPROM configuration read.
16614 static ushort __devinit
16615 AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
16617 ushort wval, chksum;
16618 ushort *wbuf;
16619 int eep_addr;
16620 ushort *charfields;
16622 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16623 wbuf = (ushort *)cfg_buf;
16624 chksum = 0;
16626 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16627 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16628 wval = AdvReadEEPWord(iop_base, eep_addr);
16629 chksum += wval; /* Checksum is calculated from word values. */
16630 if (*charfields++) {
16631 *wbuf = le16_to_cpu(wval);
16632 } else {
16633 *wbuf = wval;
16636 /* Read checksum word. */
16637 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16638 wbuf++;
16639 charfields++;
16641 /* Read rest of EEPROM not covered by the checksum. */
16642 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16643 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16644 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16645 if (*charfields++) {
16646 *wbuf = le16_to_cpu(*wbuf);
16649 return chksum;
16653 * Read the EEPROM from specified location
16655 static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
16657 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16658 ASC_EEP_CMD_READ | eep_word_addr);
16659 AdvWaitEEPCmd(iop_base);
16660 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
16664 * Wait for EEPROM command to complete
16666 static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
16668 int eep_delay_ms;
16670 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
16671 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
16672 ASC_EEP_CMD_DONE) {
16673 break;
16675 DvcSleepMilliSecond(1);
16677 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
16678 0) {
16679 ASC_ASSERT(0);
16681 return;
16685 * Write the EEPROM from 'cfg_buf'.
16687 void __devinit
16688 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16690 ushort *wbuf;
16691 ushort addr, chksum;
16692 ushort *charfields;
16694 wbuf = (ushort *)cfg_buf;
16695 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16696 chksum = 0;
16698 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16699 AdvWaitEEPCmd(iop_base);
16702 * Write EEPROM from word 0 to word 20.
16704 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16705 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16706 ushort word;
16708 if (*charfields++) {
16709 word = cpu_to_le16(*wbuf);
16710 } else {
16711 word = *wbuf;
16713 chksum += *wbuf; /* Checksum is calculated from word values. */
16714 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16715 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16716 ASC_EEP_CMD_WRITE | addr);
16717 AdvWaitEEPCmd(iop_base);
16718 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16722 * Write EEPROM checksum at word 21.
16724 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16725 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16726 AdvWaitEEPCmd(iop_base);
16727 wbuf++;
16728 charfields++;
16731 * Write EEPROM OEM name at words 22 to 29.
16733 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16734 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16735 ushort word;
16737 if (*charfields++) {
16738 word = cpu_to_le16(*wbuf);
16739 } else {
16740 word = *wbuf;
16742 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16743 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16744 ASC_EEP_CMD_WRITE | addr);
16745 AdvWaitEEPCmd(iop_base);
16747 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16748 AdvWaitEEPCmd(iop_base);
16749 return;
16753 * Write the EEPROM from 'cfg_buf'.
16755 void __devinit
16756 AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
16758 ushort *wbuf;
16759 ushort *charfields;
16760 ushort addr, chksum;
16762 wbuf = (ushort *)cfg_buf;
16763 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16764 chksum = 0;
16766 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16767 AdvWaitEEPCmd(iop_base);
16770 * Write EEPROM from word 0 to word 20.
16772 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16773 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16774 ushort word;
16776 if (*charfields++) {
16777 word = cpu_to_le16(*wbuf);
16778 } else {
16779 word = *wbuf;
16781 chksum += *wbuf; /* Checksum is calculated from word values. */
16782 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16783 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16784 ASC_EEP_CMD_WRITE | addr);
16785 AdvWaitEEPCmd(iop_base);
16786 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16790 * Write EEPROM checksum at word 21.
16792 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16793 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16794 AdvWaitEEPCmd(iop_base);
16795 wbuf++;
16796 charfields++;
16799 * Write EEPROM OEM name at words 22 to 29.
16801 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16802 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16803 ushort word;
16805 if (*charfields++) {
16806 word = cpu_to_le16(*wbuf);
16807 } else {
16808 word = *wbuf;
16810 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16811 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16812 ASC_EEP_CMD_WRITE | addr);
16813 AdvWaitEEPCmd(iop_base);
16815 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16816 AdvWaitEEPCmd(iop_base);
16817 return;
16821 * Write the EEPROM from 'cfg_buf'.
16823 void __devinit
16824 AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
16826 ushort *wbuf;
16827 ushort *charfields;
16828 ushort addr, chksum;
16830 wbuf = (ushort *)cfg_buf;
16831 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16832 chksum = 0;
16834 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16835 AdvWaitEEPCmd(iop_base);
16838 * Write EEPROM from word 0 to word 20.
16840 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16841 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16842 ushort word;
16844 if (*charfields++) {
16845 word = cpu_to_le16(*wbuf);
16846 } else {
16847 word = *wbuf;
16849 chksum += *wbuf; /* Checksum is calculated from word values. */
16850 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16851 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16852 ASC_EEP_CMD_WRITE | addr);
16853 AdvWaitEEPCmd(iop_base);
16854 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16858 * Write EEPROM checksum at word 21.
16860 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16861 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16862 AdvWaitEEPCmd(iop_base);
16863 wbuf++;
16864 charfields++;
16867 * Write EEPROM OEM name at words 22 to 29.
16869 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16870 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16871 ushort word;
16873 if (*charfields++) {
16874 word = cpu_to_le16(*wbuf);
16875 } else {
16876 word = *wbuf;
16878 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16879 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16880 ASC_EEP_CMD_WRITE | addr);
16881 AdvWaitEEPCmd(iop_base);
16883 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16884 AdvWaitEEPCmd(iop_base);
16885 return;
16888 /* a_advlib.c */
16890 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
16892 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
16893 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
16894 * RISC to notify it a new command is ready to be executed.
16896 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
16897 * set to SCSI_MAX_RETRY.
16899 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
16900 * for DMA addresses or math operations are byte swapped to little-endian
16901 * order.
16903 * Return:
16904 * ADV_SUCCESS(1) - The request was successfully queued.
16905 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
16906 * request completes.
16907 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
16908 * host IC error.
16910 static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
16912 ulong last_int_level;
16913 AdvPortAddr iop_base;
16914 ADV_DCNT req_size;
16915 ADV_PADDR req_paddr;
16916 ADV_CARR_T *new_carrp;
16918 ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
16921 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
16923 if (scsiq->target_id > ADV_MAX_TID) {
16924 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
16925 scsiq->done_status = QD_WITH_ERROR;
16926 return ADV_ERROR;
16929 iop_base = asc_dvc->iop_base;
16931 last_int_level = DvcEnterCritical();
16934 * Allocate a carrier ensuring at least one carrier always
16935 * remains on the freelist and initialize fields.
16937 if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
16938 DvcLeaveCritical(last_int_level);
16939 return ADV_BUSY;
16941 asc_dvc->carr_freelist = (ADV_CARR_T *)
16942 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
16943 asc_dvc->carr_pending_cnt++;
16946 * Set the carrier to be a stopper by setting 'next_vpa'
16947 * to the stopper value. The current stopper will be changed
16948 * below to point to the new stopper.
16950 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16953 * Clear the ADV_SCSI_REQ_Q done flag.
16955 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
16957 req_size = sizeof(ADV_SCSI_REQ_Q);
16958 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
16959 (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
16961 ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
16962 ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
16964 /* Wait for assertion before making little-endian */
16965 req_paddr = cpu_to_le32(req_paddr);
16967 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
16968 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
16969 scsiq->scsiq_rptr = req_paddr;
16971 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
16973 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
16974 * order during initialization.
16976 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
16979 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
16980 * the microcode. The newly allocated stopper will become the new
16981 * stopper.
16983 asc_dvc->icq_sp->areq_vpa = req_paddr;
16986 * Set the 'next_vpa' pointer for the old stopper to be the
16987 * physical address of the new stopper. The RISC can only
16988 * follow physical addresses.
16990 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
16993 * Set the host adapter stopper pointer to point to the new carrier.
16995 asc_dvc->icq_sp = new_carrp;
16997 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
16998 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
17000 * Tickle the RISC to tell it to read its Command Queue Head pointer.
17002 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
17003 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
17005 * Clear the tickle value. In the ASC-3550 the RISC flag
17006 * command 'clr_tickle_a' does not work unless the host
17007 * value is cleared.
17009 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
17010 ADV_TICKLE_NOP);
17012 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17014 * Notify the RISC a carrier is ready by writing the physical
17015 * address of the new carrier stopper to the COMMA register.
17017 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
17018 le32_to_cpu(new_carrp->carr_pa));
17021 DvcLeaveCritical(last_int_level);
17023 return ADV_SUCCESS;
17027 * Reset SCSI Bus and purge all outstanding requests.
17029 * Return Value:
17030 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
17031 * ADV_FALSE(0) - Microcode command failed.
17032 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
17033 * may be hung which requires driver recovery.
17035 static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
17037 int status;
17040 * Send the SCSI Bus Reset idle start idle command which asserts
17041 * the SCSI Bus Reset signal.
17043 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
17044 if (status != ADV_TRUE) {
17045 return status;
17049 * Delay for the specified SCSI Bus Reset hold time.
17051 * The hold time delay is done on the host because the RISC has no
17052 * microsecond accurate timer.
17054 DvcDelayMicroSecond(asc_dvc, (ushort)ASC_SCSI_RESET_HOLD_TIME_US);
17057 * Send the SCSI Bus Reset end idle command which de-asserts
17058 * the SCSI Bus Reset signal and purges any pending requests.
17060 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
17061 if (status != ADV_TRUE) {
17062 return status;
17065 DvcSleepMilliSecond((ADV_DCNT)asc_dvc->scsi_reset_wait * 1000);
17067 return status;
17071 * Reset chip and SCSI Bus.
17073 * Return Value:
17074 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
17075 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
17077 static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
17079 int status;
17080 ushort wdtr_able, sdtr_able, tagqng_able;
17081 ushort ppr_able = 0;
17082 uchar tid, max_cmd[ADV_MAX_TID + 1];
17083 AdvPortAddr iop_base;
17084 ushort bios_sig;
17086 iop_base = asc_dvc->iop_base;
17089 * Save current per TID negotiated values.
17091 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17092 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17093 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17094 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17096 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17097 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
17098 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17099 max_cmd[tid]);
17103 * Force the AdvInitAsc3550/38C0800Driver() function to
17104 * perform a SCSI Bus Reset by clearing the BIOS signature word.
17105 * The initialization functions assumes a SCSI Bus Reset is not
17106 * needed if the BIOS signature word is present.
17108 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17109 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
17112 * Stop chip and reset it.
17114 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
17115 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
17116 DvcSleepMilliSecond(100);
17117 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
17118 ADV_CTRL_REG_CMD_WR_IO_REG);
17121 * Reset Adv Library error code, if any, and try
17122 * re-initializing the chip.
17124 asc_dvc->err_code = 0;
17125 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17126 status = AdvInitAsc38C1600Driver(asc_dvc);
17127 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
17128 status = AdvInitAsc38C0800Driver(asc_dvc);
17129 } else {
17130 status = AdvInitAsc3550Driver(asc_dvc);
17133 /* Translate initialization return value to status value. */
17134 if (status == 0) {
17135 status = ADV_TRUE;
17136 } else {
17137 status = ADV_FALSE;
17141 * Restore the BIOS signature word.
17143 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17146 * Restore per TID negotiated values.
17148 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17149 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17150 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17151 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17153 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17154 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
17155 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17156 max_cmd[tid]);
17159 return status;
17163 * Adv Library Interrupt Service Routine
17165 * This function is called by a driver's interrupt service routine.
17166 * The function disables and re-enables interrupts.
17168 * When a microcode idle command is completed, the ADV_DVC_VAR
17169 * 'idle_cmd_done' field is set to ADV_TRUE.
17171 * Note: AdvISR() can be called when interrupts are disabled or even
17172 * when there is no hardware interrupt condition present. It will
17173 * always check for completed idle commands and microcode requests.
17174 * This is an important feature that shouldn't be changed because it
17175 * allows commands to be completed from polling mode loops.
17177 * Return:
17178 * ADV_TRUE(1) - interrupt was pending
17179 * ADV_FALSE(0) - no interrupt was pending
17181 static int AdvISR(ADV_DVC_VAR *asc_dvc)
17183 AdvPortAddr iop_base;
17184 uchar int_stat;
17185 ushort target_bit;
17186 ADV_CARR_T *free_carrp;
17187 ADV_VADDR irq_next_vpa;
17188 int flags;
17189 ADV_SCSI_REQ_Q *scsiq;
17191 flags = DvcEnterCritical();
17193 iop_base = asc_dvc->iop_base;
17195 /* Reading the register clears the interrupt. */
17196 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
17198 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
17199 ADV_INTR_STATUS_INTRC)) == 0) {
17200 DvcLeaveCritical(flags);
17201 return ADV_FALSE;
17205 * Notify the driver of an asynchronous microcode condition by
17206 * calling the ADV_DVC_VAR.async_callback function. The function
17207 * is passed the microcode ASC_MC_INTRB_CODE byte value.
17209 if (int_stat & ADV_INTR_STATUS_INTRB) {
17210 uchar intrb_code;
17212 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
17214 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17215 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
17216 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
17217 asc_dvc->carr_pending_cnt != 0) {
17218 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
17219 ADV_TICKLE_A);
17220 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
17221 AdvWriteByteRegister(iop_base,
17222 IOPB_TICKLE,
17223 ADV_TICKLE_NOP);
17228 if (asc_dvc->async_callback != 0) {
17229 (*asc_dvc->async_callback) (asc_dvc, intrb_code);
17234 * Check if the IRQ stopper carrier contains a completed request.
17236 while (((irq_next_vpa =
17237 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
17239 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
17240 * The RISC will have set 'areq_vpa' to a virtual address.
17242 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
17243 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
17244 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
17245 * in AdvExeScsiQueue().
17247 scsiq = (ADV_SCSI_REQ_Q *)
17248 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
17251 * Request finished with good status and the queue was not
17252 * DMAed to host memory by the firmware. Set all status fields
17253 * to indicate good status.
17255 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
17256 scsiq->done_status = QD_NO_ERROR;
17257 scsiq->host_status = scsiq->scsi_status = 0;
17258 scsiq->data_cnt = 0L;
17262 * Advance the stopper pointer to the next carrier
17263 * ignoring the lower four bits. Free the previous
17264 * stopper carrier.
17266 free_carrp = asc_dvc->irq_sp;
17267 asc_dvc->irq_sp = (ADV_CARR_T *)
17268 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
17270 free_carrp->next_vpa =
17271 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
17272 asc_dvc->carr_freelist = free_carrp;
17273 asc_dvc->carr_pending_cnt--;
17275 ASC_ASSERT(scsiq != NULL);
17276 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
17279 * Clear request microcode control flag.
17281 scsiq->cntl = 0;
17284 * If the command that completed was a SCSI INQUIRY and
17285 * LUN 0 was sent the command, then process the INQUIRY
17286 * command information for the device.
17288 * Note: If data returned were either VPD or CmdDt data,
17289 * don't process the INQUIRY command information for
17290 * the device, otherwise may erroneously set *_able bits.
17292 if (scsiq->done_status == QD_NO_ERROR &&
17293 scsiq->cdb[0] == INQUIRY &&
17294 scsiq->target_lun == 0 &&
17295 (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
17296 == ADV_INQ_RTN_STD_INQUIRY_DATA) {
17297 AdvInquiryHandling(asc_dvc, scsiq);
17301 * Notify the driver of the completed request by passing
17302 * the ADV_SCSI_REQ_Q pointer to its callback function.
17304 scsiq->a_flag |= ADV_SCSIQ_DONE;
17305 (*asc_dvc->isr_callback) (asc_dvc, scsiq);
17307 * Note: After the driver callback function is called, 'scsiq'
17308 * can no longer be referenced.
17310 * Fall through and continue processing other completed
17311 * requests...
17315 * Disable interrupts again in case the driver inadvertently
17316 * enabled interrupts in its callback function.
17318 * The DvcEnterCritical() return value is ignored, because
17319 * the 'flags' saved when AdvISR() was first entered will be
17320 * used to restore the interrupt flag on exit.
17322 (void)DvcEnterCritical();
17324 DvcLeaveCritical(flags);
17325 return ADV_TRUE;
17329 * Send an idle command to the chip and wait for completion.
17331 * Command completion is polled for once per microsecond.
17333 * The function can be called from anywhere including an interrupt handler.
17334 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
17335 * functions to prevent reentrancy.
17337 * Return Values:
17338 * ADV_TRUE - command completed successfully
17339 * ADV_FALSE - command failed
17340 * ADV_ERROR - command timed out
17342 static int
17343 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
17344 ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
17346 ulong last_int_level;
17347 int result;
17348 ADV_DCNT i, j;
17349 AdvPortAddr iop_base;
17351 last_int_level = DvcEnterCritical();
17353 iop_base = asc_dvc->iop_base;
17356 * Clear the idle command status which is set by the microcode
17357 * to a non-zero value to indicate when the command is completed.
17358 * The non-zero result is one of the IDLE_CMD_STATUS_* values
17359 * defined in a_advlib.h.
17361 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
17364 * Write the idle command value after the idle command parameter
17365 * has been written to avoid a race condition. If the order is not
17366 * followed, the microcode may process the idle command before the
17367 * parameters have been written to LRAM.
17369 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
17370 cpu_to_le32(idle_cmd_parameter));
17371 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
17374 * Tickle the RISC to tell it to process the idle command.
17376 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
17377 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
17379 * Clear the tickle value. In the ASC-3550 the RISC flag
17380 * command 'clr_tickle_b' does not work unless the host
17381 * value is cleared.
17383 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17386 /* Wait for up to 100 millisecond for the idle command to timeout. */
17387 for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
17388 /* Poll once each microsecond for command completion. */
17389 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
17390 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
17391 result);
17392 if (result != 0) {
17393 DvcLeaveCritical(last_int_level);
17394 return result;
17396 DvcDelayMicroSecond(asc_dvc, (ushort)1);
17400 ASC_ASSERT(0); /* The idle command should never timeout. */
17401 DvcLeaveCritical(last_int_level);
17402 return ADV_ERROR;
17406 * Inquiry Information Byte 7 Handling
17408 * Handle SCSI Inquiry Command information for a device by setting
17409 * microcode operating variables that affect WDTR, SDTR, and Tag
17410 * Queuing.
17412 static void AdvInquiryHandling(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
17414 AdvPortAddr iop_base;
17415 uchar tid;
17416 ADV_SCSI_INQUIRY *inq;
17417 ushort tidmask;
17418 ushort cfg_word;
17421 * AdvInquiryHandling() requires up to INQUIRY information Byte 7
17422 * to be available.
17424 * If less than 8 bytes of INQUIRY information were requested or less
17425 * than 8 bytes were transferred, then return. cdb[4] is the request
17426 * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
17427 * microcode to the transfer residual count.
17430 if (scsiq->cdb[4] < 8 ||
17431 (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8) {
17432 return;
17435 iop_base = asc_dvc->iop_base;
17436 tid = scsiq->target_id;
17438 inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr;
17441 * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
17443 if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2) {
17444 return;
17445 } else {
17447 * INQUIRY Byte 7 Handling
17449 * Use a device's INQUIRY byte 7 to determine whether it
17450 * supports WDTR, SDTR, and Tag Queuing. If the feature
17451 * is enabled in the EEPROM and the device supports the
17452 * feature, then enable it in the microcode.
17455 tidmask = ADV_TID_TO_TIDMASK(tid);
17458 * Wide Transfers
17460 * If the EEPROM enabled WDTR for the device and the device
17461 * supports wide bus (16 bit) transfers, then turn on the
17462 * device's 'wdtr_able' bit and write the new value to the
17463 * microcode.
17465 if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq)) {
17466 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
17467 if ((cfg_word & tidmask) == 0) {
17468 cfg_word |= tidmask;
17469 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
17470 cfg_word);
17473 * Clear the microcode "SDTR negotiation" and "WDTR
17474 * negotiation" done indicators for the target to cause
17475 * it to negotiate with the new setting set above.
17476 * WDTR when accepted causes the target to enter
17477 * asynchronous mode, so SDTR must be negotiated.
17479 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE,
17480 cfg_word);
17481 cfg_word &= ~tidmask;
17482 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE,
17483 cfg_word);
17484 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE,
17485 cfg_word);
17486 cfg_word &= ~tidmask;
17487 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE,
17488 cfg_word);
17493 * Synchronous Transfers
17495 * If the EEPROM enabled SDTR for the device and the device
17496 * supports synchronous transfers, then turn on the device's
17497 * 'sdtr_able' bit. Write the new value to the microcode.
17499 if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq)) {
17500 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
17501 if ((cfg_word & tidmask) == 0) {
17502 cfg_word |= tidmask;
17503 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
17504 cfg_word);
17507 * Clear the microcode "SDTR negotiation" done indicator
17508 * for the target to cause it to negotiate with the new
17509 * setting set above.
17511 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE,
17512 cfg_word);
17513 cfg_word &= ~tidmask;
17514 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE,
17515 cfg_word);
17519 * If the Inquiry data included enough space for the SPI-3
17520 * Clocking field, then check if DT mode is supported.
17522 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 &&
17523 (scsiq->cdb[4] >= 57 ||
17524 (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57)) {
17526 * PPR (Parallel Protocol Request) Capable
17528 * If the device supports DT mode, then it must be PPR capable.
17529 * The PPR message will be used in place of the SDTR and WDTR
17530 * messages to negotiate synchronous speed and offset, transfer
17531 * width, and protocol options.
17533 if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY) {
17534 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE,
17535 asc_dvc->ppr_able);
17536 asc_dvc->ppr_able |= tidmask;
17537 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE,
17538 asc_dvc->ppr_able);
17543 * If the EEPROM enabled Tag Queuing for the device and the
17544 * device supports Tag Queueing, then turn on the device's
17545 * 'tagqng_enable' bit in the microcode and set the microcode
17546 * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
17547 * value.
17549 * Tag Queuing is disabled for the BIOS which runs in polled
17550 * mode and would see no benefit from Tag Queuing. Also by
17551 * disabling Tag Queuing in the BIOS devices with Tag Queuing
17552 * bugs will at least work with the BIOS.
17554 if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq)) {
17555 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
17556 cfg_word |= tidmask;
17557 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
17558 cfg_word);
17560 AdvWriteByteLram(iop_base,
17561 ASC_MC_NUMBER_OF_MAX_CMD + tid,
17562 asc_dvc->max_dvc_qng);
17567 static int __devinit
17568 advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
17570 int req_cnt = 0;
17571 adv_req_t *reqp = NULL;
17572 int sg_cnt = 0;
17573 adv_sgblk_t *sgp;
17574 int warn_code, err_code;
17577 * Allocate buffer carrier structures. The total size
17578 * is about 4 KB, so allocate all at once.
17580 boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
17581 ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp);
17583 if (!boardp->carrp)
17584 goto kmalloc_failed;
17587 * Allocate up to 'max_host_qng' request structures for the Wide
17588 * board. The total size is about 16 KB, so allocate all at once.
17589 * If the allocation fails decrement and try again.
17591 for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
17592 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
17594 ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, "
17595 "bytes %lu\n", reqp, req_cnt,
17596 (ulong)sizeof(adv_req_t) * req_cnt);
17598 if (reqp)
17599 break;
17602 if (!reqp)
17603 goto kmalloc_failed;
17605 boardp->orig_reqp = reqp;
17608 * Allocate up to ADV_TOT_SG_BLOCK request structures for
17609 * the Wide board. Each structure is about 136 bytes.
17611 boardp->adv_sgblkp = NULL;
17612 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
17613 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
17615 if (!sgp)
17616 break;
17618 sgp->next_sgblkp = boardp->adv_sgblkp;
17619 boardp->adv_sgblkp = sgp;
17623 ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n",
17624 sg_cnt, sizeof(adv_sgblk_t),
17625 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
17627 if (!boardp->adv_sgblkp)
17628 goto kmalloc_failed;
17630 adv_dvc_varp->carrier_buf = boardp->carrp;
17633 * Point 'adv_reqp' to the request structures and
17634 * link them together.
17636 req_cnt--;
17637 reqp[req_cnt].next_reqp = NULL;
17638 for (; req_cnt > 0; req_cnt--) {
17639 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
17641 boardp->adv_reqp = &reqp[0];
17643 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17644 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n");
17645 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
17646 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17647 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()"
17648 "\n");
17649 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
17650 } else {
17651 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()"
17652 "\n");
17653 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
17655 err_code = adv_dvc_varp->err_code;
17657 if (warn_code || err_code) {
17658 ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
17659 " error 0x%x\n", boardp->id, warn_code, err_code);
17662 goto exit;
17664 kmalloc_failed:
17665 ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
17666 "failed\n", boardp->id);
17667 err_code = ADV_ERROR;
17668 exit:
17669 return err_code;
17672 static void advansys_wide_free_mem(asc_board_t *boardp)
17674 kfree(boardp->carrp);
17675 boardp->carrp = NULL;
17676 kfree(boardp->orig_reqp);
17677 boardp->orig_reqp = boardp->adv_reqp = NULL;
17678 while (boardp->adv_sgblkp) {
17679 adv_sgblk_t *sgp = boardp->adv_sgblkp;
17680 boardp->adv_sgblkp = sgp->next_sgblkp;
17681 kfree(sgp);
17685 static struct Scsi_Host *__devinit
17686 advansys_board_found(int iop, struct device *dev, int bus_type)
17688 struct Scsi_Host *shost;
17689 struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL;
17690 asc_board_t *boardp;
17691 ASC_DVC_VAR *asc_dvc_varp = NULL;
17692 ADV_DVC_VAR *adv_dvc_varp = NULL;
17693 int share_irq;
17694 int iolen = 0;
17695 ADV_PADDR pci_memory_address;
17696 int warn_code, err_code;
17697 int ret;
17700 * Adapter found.
17702 * Register the adapter, get its configuration, and
17703 * initialize it.
17705 ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n");
17706 shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t));
17708 if (!shost)
17709 return NULL;
17711 /* Initialize private per board data */
17712 boardp = ASC_BOARDP(shost);
17713 memset(boardp, 0, sizeof(asc_board_t));
17714 boardp->id = asc_board_count++;
17716 /* Initialize spinlock. */
17717 spin_lock_init(&boardp->lock);
17720 * Handle both narrow and wide boards.
17722 * If a Wide board was detected, set the board structure
17723 * wide board flag. Set-up the board structure based on
17724 * the board type.
17726 #ifdef CONFIG_PCI
17727 if (bus_type == ASC_IS_PCI &&
17728 (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
17729 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
17730 pdev->device == PCI_DEVICE_ID_38C1600_REV1)) {
17731 boardp->flags |= ASC_IS_WIDE_BOARD;
17733 #endif /* CONFIG_PCI */
17735 if (ASC_NARROW_BOARD(boardp)) {
17736 ASC_DBG(1, "advansys_board_found: narrow board\n");
17737 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
17738 asc_dvc_varp->bus_type = bus_type;
17739 asc_dvc_varp->drv_ptr = boardp;
17740 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
17741 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
17742 asc_dvc_varp->iop_base = iop;
17743 asc_dvc_varp->isr_callback = asc_isr_callback;
17744 } else {
17745 ASC_DBG(1, "advansys_board_found: wide board\n");
17746 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
17747 adv_dvc_varp->drv_ptr = boardp;
17748 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
17749 adv_dvc_varp->isr_callback = adv_isr_callback;
17750 adv_dvc_varp->async_callback = adv_async_callback;
17751 #ifdef CONFIG_PCI
17752 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
17753 ASC_DBG(1, "advansys_board_found: ASC-3550\n");
17754 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
17755 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
17756 ASC_DBG(1, "advansys_board_found: ASC-38C0800\n");
17757 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
17758 } else {
17759 ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
17760 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
17762 #endif /* CONFIG_PCI */
17765 * Map the board's registers into virtual memory for
17766 * PCI slave access. Only memory accesses are used to
17767 * access the board's registers.
17769 * Note: The PCI register base address is not always
17770 * page aligned, but the address passed to ioremap()
17771 * must be page aligned. It is guaranteed that the
17772 * PCI register base address will not cross a page
17773 * boundary.
17775 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17776 iolen = ADV_3550_IOLEN;
17777 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17778 iolen = ADV_38C0800_IOLEN;
17779 } else {
17780 iolen = ADV_38C1600_IOLEN;
17782 #ifdef CONFIG_PCI
17783 pci_memory_address = pci_resource_start(pdev, 1);
17784 ASC_DBG1(1,
17785 "advansys_board_found: pci_memory_address: 0x%lx\n",
17786 (ulong)pci_memory_address);
17787 if ((boardp->ioremap_addr =
17788 ioremap(pci_memory_address & PAGE_MASK, PAGE_SIZE)) == 0) {
17789 ASC_PRINT3
17790 ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
17791 boardp->id, pci_memory_address, iolen);
17792 goto err_shost;
17794 ASC_DBG1(1,
17795 "advansys_board_found: ioremap_addr: 0x%lx\n",
17796 (ulong)boardp->ioremap_addr);
17797 adv_dvc_varp->iop_base = (AdvPortAddr)
17798 (boardp->ioremap_addr +
17799 (pci_memory_address - (pci_memory_address & PAGE_MASK)));
17800 ASC_DBG1(1,
17801 "advansys_board_found: iop_base: 0x%lx\n",
17802 adv_dvc_varp->iop_base);
17803 #endif /* CONFIG_PCI */
17806 * Even though it isn't used to access wide boards, other
17807 * than for the debug line below, save I/O Port address so
17808 * that it can be reported.
17810 boardp->ioport = iop;
17812 ASC_DBG2(1,
17813 "advansys_board_found: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
17814 (ushort)inp(iop + 1), (ushort)inpw(iop));
17817 #ifdef CONFIG_PROC_FS
17819 * Allocate buffer for printing information from
17820 * /proc/scsi/advansys/[0...].
17822 boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
17823 if (!boardp->prtbuf) {
17824 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
17825 "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
17826 goto err_unmap;
17828 #endif /* CONFIG_PROC_FS */
17830 if (ASC_NARROW_BOARD(boardp)) {
17831 asc_dvc_varp->cfg->dev = dev;
17833 * Set the board bus type and PCI IRQ before
17834 * calling AscInitGetConfig().
17836 switch (asc_dvc_varp->bus_type) {
17837 #ifdef CONFIG_ISA
17838 case ASC_IS_ISA:
17839 shost->unchecked_isa_dma = TRUE;
17840 share_irq = 0;
17841 break;
17842 case ASC_IS_VL:
17843 shost->unchecked_isa_dma = FALSE;
17844 share_irq = 0;
17845 break;
17846 case ASC_IS_EISA:
17847 shost->unchecked_isa_dma = FALSE;
17848 share_irq = IRQF_SHARED;
17849 break;
17850 #endif /* CONFIG_ISA */
17851 #ifdef CONFIG_PCI
17852 case ASC_IS_PCI:
17853 shost->irq = asc_dvc_varp->irq_no = pdev->irq;
17854 asc_dvc_varp->cfg->pci_slot_info =
17855 ASC_PCI_MKID(pdev->bus->number,
17856 PCI_SLOT(pdev->devfn),
17857 PCI_FUNC(pdev->devfn));
17858 shost->unchecked_isa_dma = FALSE;
17859 share_irq = IRQF_SHARED;
17860 break;
17861 #endif /* CONFIG_PCI */
17862 default:
17863 ASC_PRINT2
17864 ("advansys_board_found: board %d: unknown adapter type: %d\n",
17865 boardp->id, asc_dvc_varp->bus_type);
17866 shost->unchecked_isa_dma = TRUE;
17867 share_irq = 0;
17868 break;
17870 } else {
17871 adv_dvc_varp->cfg->dev = dev;
17873 * For Wide boards set PCI information before calling
17874 * AdvInitGetConfig().
17876 #ifdef CONFIG_PCI
17877 shost->irq = adv_dvc_varp->irq_no = pdev->irq;
17878 adv_dvc_varp->cfg->pci_slot_info =
17879 ASC_PCI_MKID(pdev->bus->number,
17880 PCI_SLOT(pdev->devfn),
17881 PCI_FUNC(pdev->devfn));
17882 shost->unchecked_isa_dma = FALSE;
17883 share_irq = IRQF_SHARED;
17884 #endif /* CONFIG_PCI */
17888 * Read the board configuration.
17890 if (ASC_NARROW_BOARD(boardp)) {
17892 * NOTE: AscInitGetConfig() may change the board's
17893 * bus_type value. The bus_type value should no
17894 * longer be used. If the bus_type field must be
17895 * referenced only use the bit-wise AND operator "&".
17897 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
17898 switch (ret = AscInitGetConfig(asc_dvc_varp)) {
17899 case 0: /* No error */
17900 break;
17901 case ASC_WARN_IO_PORT_ROTATE:
17902 ASC_PRINT1
17903 ("AscInitGetConfig: board %d: I/O port address modified\n",
17904 boardp->id);
17905 break;
17906 case ASC_WARN_AUTO_CONFIG:
17907 ASC_PRINT1
17908 ("AscInitGetConfig: board %d: I/O port increment switch enabled\n",
17909 boardp->id);
17910 break;
17911 case ASC_WARN_EEPROM_CHKSUM:
17912 ASC_PRINT1
17913 ("AscInitGetConfig: board %d: EEPROM checksum error\n",
17914 boardp->id);
17915 break;
17916 case ASC_WARN_IRQ_MODIFIED:
17917 ASC_PRINT1
17918 ("AscInitGetConfig: board %d: IRQ modified\n",
17919 boardp->id);
17920 break;
17921 case ASC_WARN_CMD_QNG_CONFLICT:
17922 ASC_PRINT1
17923 ("AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
17924 boardp->id);
17925 break;
17926 default:
17927 ASC_PRINT2
17928 ("AscInitGetConfig: board %d: unknown warning: 0x%x\n",
17929 boardp->id, ret);
17930 break;
17932 if ((err_code = asc_dvc_varp->err_code) != 0) {
17933 ASC_PRINT3
17934 ("AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
17935 boardp->id,
17936 asc_dvc_varp->init_state, asc_dvc_varp->err_code);
17938 } else {
17939 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
17940 if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
17941 ASC_PRINT2
17942 ("AdvInitGetConfig: board %d: warning: 0x%x\n",
17943 boardp->id, ret);
17945 if ((err_code = adv_dvc_varp->err_code) != 0) {
17946 ASC_PRINT2
17947 ("AdvInitGetConfig: board %d error: err_code 0x%x\n",
17948 boardp->id, adv_dvc_varp->err_code);
17952 if (err_code != 0)
17953 goto err_free_proc;
17956 * Save the EEPROM configuration so that it can be displayed
17957 * from /proc/scsi/advansys/[0...].
17959 if (ASC_NARROW_BOARD(boardp)) {
17961 ASCEEP_CONFIG *ep;
17964 * Set the adapter's target id bit in the 'init_tidmask' field.
17966 boardp->init_tidmask |=
17967 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
17970 * Save EEPROM settings for the board.
17972 ep = &boardp->eep_config.asc_eep;
17974 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
17975 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
17976 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
17977 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
17978 ep->start_motor = asc_dvc_varp->start_motor;
17979 ep->cntl = asc_dvc_varp->dvc_cntl;
17980 ep->no_scam = asc_dvc_varp->no_scam;
17981 ep->max_total_qng = asc_dvc_varp->max_total_qng;
17982 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
17983 /* 'max_tag_qng' is set to the same value for every device. */
17984 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
17985 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
17986 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
17987 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
17988 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
17989 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
17990 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
17993 * Modify board configuration.
17995 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
17996 switch (ret = AscInitSetConfig(asc_dvc_varp)) {
17997 case 0: /* No error. */
17998 break;
17999 case ASC_WARN_IO_PORT_ROTATE:
18000 ASC_PRINT1
18001 ("AscInitSetConfig: board %d: I/O port address modified\n",
18002 boardp->id);
18003 break;
18004 case ASC_WARN_AUTO_CONFIG:
18005 ASC_PRINT1
18006 ("AscInitSetConfig: board %d: I/O port increment switch enabled\n",
18007 boardp->id);
18008 break;
18009 case ASC_WARN_EEPROM_CHKSUM:
18010 ASC_PRINT1
18011 ("AscInitSetConfig: board %d: EEPROM checksum error\n",
18012 boardp->id);
18013 break;
18014 case ASC_WARN_IRQ_MODIFIED:
18015 ASC_PRINT1
18016 ("AscInitSetConfig: board %d: IRQ modified\n",
18017 boardp->id);
18018 break;
18019 case ASC_WARN_CMD_QNG_CONFLICT:
18020 ASC_PRINT1
18021 ("AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
18022 boardp->id);
18023 break;
18024 default:
18025 ASC_PRINT2
18026 ("AscInitSetConfig: board %d: unknown warning: 0x%x\n",
18027 boardp->id, ret);
18028 break;
18030 if (asc_dvc_varp->err_code != 0) {
18031 ASC_PRINT3
18032 ("AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
18033 boardp->id,
18034 asc_dvc_varp->init_state, asc_dvc_varp->err_code);
18035 goto err_free_proc;
18039 * Finish initializing the 'Scsi_Host' structure.
18041 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
18042 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
18043 shost->irq = asc_dvc_varp->irq_no;
18045 } else {
18046 ADVEEP_3550_CONFIG *ep_3550;
18047 ADVEEP_38C0800_CONFIG *ep_38C0800;
18048 ADVEEP_38C1600_CONFIG *ep_38C1600;
18051 * Save Wide EEP Configuration Information.
18053 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
18054 ep_3550 = &boardp->eep_config.adv_3550_eep;
18056 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
18057 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
18058 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
18059 ep_3550->termination = adv_dvc_varp->cfg->termination;
18060 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
18061 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
18062 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
18063 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
18064 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
18065 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
18066 ep_3550->start_motor = adv_dvc_varp->start_motor;
18067 ep_3550->scsi_reset_delay =
18068 adv_dvc_varp->scsi_reset_wait;
18069 ep_3550->serial_number_word1 =
18070 adv_dvc_varp->cfg->serial1;
18071 ep_3550->serial_number_word2 =
18072 adv_dvc_varp->cfg->serial2;
18073 ep_3550->serial_number_word3 =
18074 adv_dvc_varp->cfg->serial3;
18075 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
18076 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
18078 ep_38C0800->adapter_scsi_id =
18079 adv_dvc_varp->chip_scsi_id;
18080 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
18081 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
18082 ep_38C0800->termination_lvd =
18083 adv_dvc_varp->cfg->termination;
18084 ep_38C0800->disc_enable =
18085 adv_dvc_varp->cfg->disc_enable;
18086 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
18087 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
18088 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
18089 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
18090 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
18091 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
18092 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
18093 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
18094 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
18095 ep_38C0800->scsi_reset_delay =
18096 adv_dvc_varp->scsi_reset_wait;
18097 ep_38C0800->serial_number_word1 =
18098 adv_dvc_varp->cfg->serial1;
18099 ep_38C0800->serial_number_word2 =
18100 adv_dvc_varp->cfg->serial2;
18101 ep_38C0800->serial_number_word3 =
18102 adv_dvc_varp->cfg->serial3;
18103 } else {
18104 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
18106 ep_38C1600->adapter_scsi_id =
18107 adv_dvc_varp->chip_scsi_id;
18108 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
18109 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
18110 ep_38C1600->termination_lvd =
18111 adv_dvc_varp->cfg->termination;
18112 ep_38C1600->disc_enable =
18113 adv_dvc_varp->cfg->disc_enable;
18114 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
18115 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
18116 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
18117 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
18118 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
18119 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
18120 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
18121 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
18122 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
18123 ep_38C1600->scsi_reset_delay =
18124 adv_dvc_varp->scsi_reset_wait;
18125 ep_38C1600->serial_number_word1 =
18126 adv_dvc_varp->cfg->serial1;
18127 ep_38C1600->serial_number_word2 =
18128 adv_dvc_varp->cfg->serial2;
18129 ep_38C1600->serial_number_word3 =
18130 adv_dvc_varp->cfg->serial3;
18134 * Set the adapter's target id bit in the 'init_tidmask' field.
18136 boardp->init_tidmask |=
18137 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
18140 * Finish initializing the 'Scsi_Host' structure.
18142 shost->irq = adv_dvc_varp->irq_no;
18146 * Channels are numbered beginning with 0. For AdvanSys one host
18147 * structure supports one channel. Multi-channel boards have a
18148 * separate host structure for each channel.
18150 shost->max_channel = 0;
18151 if (ASC_NARROW_BOARD(boardp)) {
18152 shost->max_id = ASC_MAX_TID + 1;
18153 shost->max_lun = ASC_MAX_LUN + 1;
18155 shost->io_port = asc_dvc_varp->iop_base;
18156 boardp->asc_n_io_port = ASC_IOADR_GAP;
18157 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
18159 /* Set maximum number of queues the adapter can handle. */
18160 shost->can_queue = asc_dvc_varp->max_total_qng;
18161 } else {
18162 shost->max_id = ADV_MAX_TID + 1;
18163 shost->max_lun = ADV_MAX_LUN + 1;
18166 * Save the I/O Port address and length even though
18167 * I/O ports are not used to access Wide boards.
18168 * Instead the Wide boards are accessed with
18169 * PCI Memory Mapped I/O.
18171 shost->io_port = iop;
18172 boardp->asc_n_io_port = iolen;
18174 shost->this_id = adv_dvc_varp->chip_scsi_id;
18176 /* Set maximum number of queues the adapter can handle. */
18177 shost->can_queue = adv_dvc_varp->max_host_qng;
18181 * 'n_io_port' currently is one byte.
18183 * Set a value to 'n_io_port', but never referenced it because
18184 * it may be truncated.
18186 shost->n_io_port = boardp->asc_n_io_port <= 255 ?
18187 boardp->asc_n_io_port : 255;
18190 * Following v1.3.89, 'cmd_per_lun' is no longer needed
18191 * and should be set to zero.
18193 * But because of a bug introduced in v1.3.89 if the driver is
18194 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
18195 * SCSI function 'allocate_device' will panic. To allow the driver
18196 * to work as a module in these kernels set 'cmd_per_lun' to 1.
18198 * Note: This is wrong. cmd_per_lun should be set to the depth
18199 * you want on untagged devices always.
18200 #ifdef MODULE
18202 shost->cmd_per_lun = 1;
18203 /* #else
18204 shost->cmd_per_lun = 0;
18205 #endif */
18208 * Set the maximum number of scatter-gather elements the
18209 * adapter can handle.
18211 if (ASC_NARROW_BOARD(boardp)) {
18213 * Allow two commands with 'sg_tablesize' scatter-gather
18214 * elements to be executed simultaneously. This value is
18215 * the theoretical hardware limit. It may be decreased
18216 * below.
18218 shost->sg_tablesize =
18219 (((asc_dvc_varp->max_total_qng - 2) / 2) *
18220 ASC_SG_LIST_PER_Q) + 1;
18221 } else {
18222 shost->sg_tablesize = ADV_MAX_SG_LIST;
18226 * The value of 'sg_tablesize' can not exceed the SCSI
18227 * mid-level driver definition of SG_ALL. SG_ALL also
18228 * must not be exceeded, because it is used to define the
18229 * size of the scatter-gather table in 'struct asc_sg_head'.
18231 if (shost->sg_tablesize > SG_ALL) {
18232 shost->sg_tablesize = SG_ALL;
18235 ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize);
18237 /* BIOS start address. */
18238 if (ASC_NARROW_BOARD(boardp)) {
18239 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
18240 asc_dvc_varp->bus_type);
18241 } else {
18243 * Fill-in BIOS board variables. The Wide BIOS saves
18244 * information in LRAM that is used by the driver.
18246 AdvReadWordLram(adv_dvc_varp->iop_base,
18247 BIOS_SIGNATURE, boardp->bios_signature);
18248 AdvReadWordLram(adv_dvc_varp->iop_base,
18249 BIOS_VERSION, boardp->bios_version);
18250 AdvReadWordLram(adv_dvc_varp->iop_base,
18251 BIOS_CODESEG, boardp->bios_codeseg);
18252 AdvReadWordLram(adv_dvc_varp->iop_base,
18253 BIOS_CODELEN, boardp->bios_codelen);
18255 ASC_DBG2(1,
18256 "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n",
18257 boardp->bios_signature, boardp->bios_version);
18259 ASC_DBG2(1,
18260 "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n",
18261 boardp->bios_codeseg, boardp->bios_codelen);
18264 * If the BIOS saved a valid signature, then fill in
18265 * the BIOS code segment base address.
18267 if (boardp->bios_signature == 0x55AA) {
18269 * Convert x86 realmode code segment to a linear
18270 * address by shifting left 4.
18272 shost->base = ((ulong)boardp->bios_codeseg << 4);
18273 } else {
18274 shost->base = 0;
18279 * Register Board Resources - I/O Port, DMA, IRQ
18283 * Register I/O port range.
18285 * For Wide boards the I/O ports are not used to access
18286 * the board, but request the region anyway.
18288 * 'shost->n_io_port' is not referenced, because it may be truncated.
18290 ASC_DBG2(2,
18291 "advansys_board_found: request_region port 0x%lx, len 0x%x\n",
18292 (ulong)shost->io_port, boardp->asc_n_io_port);
18293 if (request_region(shost->io_port, boardp->asc_n_io_port,
18294 "advansys") == NULL) {
18295 ASC_PRINT3
18296 ("advansys_board_found: board %d: request_region() failed, port 0x%lx, len 0x%x\n",
18297 boardp->id, (ulong)shost->io_port, boardp->asc_n_io_port);
18298 goto err_free_proc;
18301 /* Register DMA Channel for Narrow boards. */
18302 shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
18303 #ifdef CONFIG_ISA
18304 if (ASC_NARROW_BOARD(boardp)) {
18305 /* Register DMA channel for ISA bus. */
18306 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
18307 shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
18308 ret = request_dma(shost->dma_channel, "advansys");
18309 if (ret) {
18310 ASC_PRINT3
18311 ("advansys_board_found: board %d: request_dma() %d failed %d\n",
18312 boardp->id, shost->dma_channel, ret);
18313 goto err_free_region;
18315 AscEnableIsaDma(shost->dma_channel);
18318 #endif /* CONFIG_ISA */
18320 /* Register IRQ Number. */
18321 ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq);
18323 ret = request_irq(shost->irq, advansys_interrupt, share_irq,
18324 "advansys", shost);
18326 if (ret) {
18327 if (ret == -EBUSY) {
18328 ASC_PRINT2
18329 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
18330 boardp->id, shost->irq);
18331 } else if (ret == -EINVAL) {
18332 ASC_PRINT2
18333 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
18334 boardp->id, shost->irq);
18335 } else {
18336 ASC_PRINT3
18337 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
18338 boardp->id, shost->irq, ret);
18340 goto err_free_dma;
18344 * Initialize board RISC chip and enable interrupts.
18346 if (ASC_NARROW_BOARD(boardp)) {
18347 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
18348 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
18349 err_code = asc_dvc_varp->err_code;
18351 if (warn_code || err_code) {
18352 ASC_PRINT4
18353 ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
18354 boardp->id,
18355 asc_dvc_varp->init_state, warn_code, err_code);
18357 } else {
18358 err_code = advansys_wide_init_chip(boardp, adv_dvc_varp);
18361 if (err_code != 0)
18362 goto err_free_wide_mem;
18364 ASC_DBG_PRT_SCSI_HOST(2, shost);
18366 ret = scsi_add_host(shost, dev);
18367 if (ret)
18368 goto err_free_wide_mem;
18370 scsi_scan_host(shost);
18371 return shost;
18373 err_free_wide_mem:
18374 advansys_wide_free_mem(boardp);
18375 free_irq(shost->irq, shost);
18376 err_free_dma:
18377 if (shost->dma_channel != NO_ISA_DMA)
18378 free_dma(shost->dma_channel);
18379 err_free_region:
18380 release_region(shost->io_port, boardp->asc_n_io_port);
18381 err_free_proc:
18382 kfree(boardp->prtbuf);
18383 err_unmap:
18384 if (boardp->ioremap_addr)
18385 iounmap(boardp->ioremap_addr);
18386 err_shost:
18387 scsi_host_put(shost);
18388 return NULL;
18392 * advansys_detect()
18394 * Detect function for AdvanSys adapters.
18396 * Argument is a pointer to the host driver's scsi_hosts entry.
18398 * Return number of adapters found.
18400 * Note: Because this function is called during system initialization
18401 * it must not call SCSI mid-level functions including scsi_malloc()
18402 * and scsi_free().
18404 static int __init advansys_detect(void)
18406 int iop;
18407 int bus;
18408 int ioport = 0;
18409 struct Scsi_Host *shost;
18411 ASC_DBG(1, "advansys_detect: begin\n");
18413 asc_legacy_count = 0;
18416 * If I/O port probing has been modified, then verify and
18417 * clean-up the 'asc_ioport' list.
18419 if (asc_iopflag == ASC_TRUE) {
18420 for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
18421 ASC_DBG2(1, "advansys_detect: asc_ioport[%d] 0x%x\n",
18422 ioport, asc_ioport[ioport]);
18423 if (asc_ioport[ioport] != 0) {
18424 for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX;
18425 iop++) {
18426 if (_asc_def_iop_base[iop] ==
18427 asc_ioport[ioport]) {
18428 break;
18431 if (iop == ASC_IOADR_TABLE_MAX_IX) {
18432 printk
18433 ("AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
18434 asc_ioport[ioport]);
18435 asc_ioport[ioport] = 0;
18439 ioport = 0;
18442 for (bus = 0; bus < ASC_NUM_BUS; bus++) {
18444 ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
18445 bus, asc_bus_name[bus]);
18446 iop = 0;
18448 while (asc_legacy_count < ASC_NUM_BOARD_SUPPORTED) {
18450 ASC_DBG1(2, "advansys_detect: asc_legacy_count %d\n",
18451 asc_legacy_count);
18453 switch (asc_bus[bus]) {
18454 case ASC_IS_ISA:
18455 case ASC_IS_VL:
18456 #ifdef CONFIG_ISA
18457 if (asc_iopflag == ASC_FALSE) {
18458 iop =
18459 AscSearchIOPortAddr(iop,
18460 asc_bus[bus]);
18461 } else {
18463 * ISA and VL I/O port scanning has either been
18464 * eliminated or limited to selected ports on
18465 * the LILO command line, /etc/lilo.conf, or
18466 * by setting variables when the module was loaded.
18468 ASC_DBG(1,
18469 "advansys_detect: I/O port scanning modified\n");
18470 ioport_try_again:
18471 iop = 0;
18472 for (; ioport < ASC_NUM_IOPORT_PROBE;
18473 ioport++) {
18474 if ((iop =
18475 asc_ioport[ioport]) != 0) {
18476 break;
18479 if (iop) {
18480 ASC_DBG1(1,
18481 "advansys_detect: probing I/O port 0x%x...\n",
18482 iop);
18483 if (!request_region
18484 (iop, ASC_IOADR_GAP,
18485 "advansys")) {
18486 printk
18487 ("AdvanSys SCSI: specified I/O Port 0x%X is busy\n",
18488 iop);
18489 /* Don't try this I/O port twice. */
18490 asc_ioport[ioport] = 0;
18491 goto ioport_try_again;
18492 } else if (AscFindSignature(iop)
18493 == ASC_FALSE) {
18494 printk
18495 ("AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n",
18496 iop);
18497 /* Don't try this I/O port twice. */
18498 release_region(iop,
18499 ASC_IOADR_GAP);
18500 asc_ioport[ioport] = 0;
18501 goto ioport_try_again;
18502 } else {
18504 * If this isn't an ISA board, then it must be
18505 * a VL board. If currently looking an ISA
18506 * board is being looked for then try for
18507 * another ISA board in 'asc_ioport'.
18509 if (asc_bus[bus] ==
18510 ASC_IS_ISA
18512 (AscGetChipVersion
18513 (iop,
18514 ASC_IS_ISA) &
18515 ASC_CHIP_VER_ISA_BIT)
18516 == 0) {
18518 * Don't clear 'asc_ioport[ioport]'. Try
18519 * this board again for VL. Increment
18520 * 'ioport' past this board.
18522 ioport++;
18523 release_region
18524 (iop,
18525 ASC_IOADR_GAP);
18526 goto ioport_try_again;
18530 * This board appears good, don't try the I/O port
18531 * again by clearing its value. Increment 'ioport'
18532 * for the next iteration.
18534 asc_ioport[ioport++] = 0;
18537 #endif /* CONFIG_ISA */
18538 break;
18540 default:
18541 ASC_PRINT1
18542 ("advansys_detect: unknown bus type: %d\n",
18543 asc_bus[bus]);
18544 break;
18546 ASC_DBG1(1, "advansys_detect: iop 0x%x\n", iop);
18549 * Adapter not found, try next bus type.
18551 if (iop == 0)
18552 break;
18554 shost = advansys_board_found(iop, NULL, asc_bus[bus]);
18555 if (shost) {
18556 asc_host[asc_legacy_count++] = shost;
18561 ASC_DBG1(1, "advansys_detect: done: asc_legacy_count %d\n",
18562 asc_legacy_count);
18563 return asc_legacy_count;
18567 * advansys_release()
18569 * Release resources allocated for a single AdvanSys adapter.
18571 static int advansys_release(struct Scsi_Host *shost)
18573 asc_board_t *boardp;
18575 ASC_DBG(1, "advansys_release: begin\n");
18576 scsi_remove_host(shost);
18577 boardp = ASC_BOARDP(shost);
18578 free_irq(shost->irq, shost);
18579 if (shost->dma_channel != NO_ISA_DMA) {
18580 ASC_DBG(1, "advansys_release: free_dma()\n");
18581 free_dma(shost->dma_channel);
18583 release_region(shost->io_port, boardp->asc_n_io_port);
18584 if (ASC_WIDE_BOARD(boardp)) {
18585 iounmap(boardp->ioremap_addr);
18586 advansys_wide_free_mem(boardp);
18588 kfree(boardp->prtbuf);
18589 scsi_host_put(shost);
18590 ASC_DBG(1, "advansys_release: end\n");
18591 return 0;
18594 static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
18595 { "ABP7401" },
18596 { "ABP7501" },
18597 { "" }
18600 MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
18603 * EISA is a little more tricky than PCI; each EISA device may have two
18604 * channels, and this driver is written to make each channel its own Scsi_Host
18606 struct eisa_scsi_data {
18607 struct Scsi_Host *host[2];
18610 static int __devinit advansys_eisa_probe(struct device *dev)
18612 int i, ioport;
18613 int err;
18614 struct eisa_device *edev = to_eisa_device(dev);
18615 struct eisa_scsi_data *data;
18617 err = -ENOMEM;
18618 data = kzalloc(sizeof(*data), GFP_KERNEL);
18619 if (!data)
18620 goto fail;
18621 ioport = edev->base_addr + 0xc30;
18623 err = -ENODEV;
18624 for (i = 0; i < 2; i++, ioport += 0x20) {
18625 if (!AscFindSignature(ioport))
18626 continue;
18628 * I don't know why we need to do this for EISA chips, but
18629 * not for any others. It looks to be equivalent to
18630 * AscGetChipCfgMsw, but I may have overlooked something,
18631 * so I'm not converting it until I get an EISA board to
18632 * test with.
18634 inw(ioport + 4);
18635 data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA);
18636 if (data->host[i])
18637 err = 0;
18640 if (err) {
18641 kfree(data);
18642 } else {
18643 dev_set_drvdata(dev, data);
18646 fail:
18647 return err;
18650 static __devexit int advansys_eisa_remove(struct device *dev)
18652 int i;
18653 struct eisa_scsi_data *data = dev_get_drvdata(dev);
18655 for (i = 0; i < 2; i++) {
18656 struct Scsi_Host *shost = data->host[i];
18657 if (!shost)
18658 continue;
18659 advansys_release(shost);
18662 kfree(data);
18663 return 0;
18666 static struct eisa_driver advansys_eisa_driver = {
18667 .id_table = advansys_eisa_table,
18668 .driver = {
18669 .name = "advansys",
18670 .probe = advansys_eisa_probe,
18671 .remove = __devexit_p(advansys_eisa_remove),
18675 /* PCI Devices supported by this driver */
18676 static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
18677 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
18678 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18679 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
18680 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18681 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
18682 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18683 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
18684 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18685 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
18686 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18687 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
18688 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18692 MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
18694 static int __devinit
18695 advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
18697 int err, ioport;
18698 struct Scsi_Host *shost;
18700 err = pci_enable_device(pdev);
18701 if (err)
18702 goto fail;
18704 if (pci_resource_len(pdev, 0) == 0)
18705 goto nodev;
18707 ioport = pci_resource_start(pdev, 0);
18708 shost = advansys_board_found(ioport, &pdev->dev, ASC_IS_PCI);
18710 if (!shost)
18711 goto nodev;
18713 pci_set_drvdata(pdev, shost);
18714 return 0;
18716 nodev:
18717 err = -ENODEV;
18718 pci_disable_device(pdev);
18719 fail:
18720 return err;
18723 static void __devexit advansys_pci_remove(struct pci_dev *pdev)
18725 advansys_release(pci_get_drvdata(pdev));
18726 pci_disable_device(pdev);
18729 static struct pci_driver advansys_pci_driver = {
18730 .name = "advansys",
18731 .id_table = advansys_pci_tbl,
18732 .probe = advansys_pci_probe,
18733 .remove = __devexit_p(advansys_pci_remove),
18736 static int __init advansys_init(void)
18738 int i, error;
18739 advansys_detect();
18741 error = eisa_driver_register(&advansys_eisa_driver);
18742 if (error)
18743 goto fail;
18745 error = pci_register_driver(&advansys_pci_driver);
18746 if (error)
18747 goto unregister_eisa;
18749 return 0;
18751 unregister_eisa:
18752 eisa_driver_unregister(&advansys_eisa_driver);
18753 fail:
18754 for (i = 0; i < asc_legacy_count; i++)
18755 advansys_release(asc_host[i]);
18757 return error;
18760 static void __exit advansys_exit(void)
18762 int i;
18764 pci_unregister_driver(&advansys_pci_driver);
18765 eisa_driver_unregister(&advansys_eisa_driver);
18767 for (i = 0; i < asc_legacy_count; i++)
18768 advansys_release(asc_host[i]);
18771 module_init(advansys_init);
18772 module_exit(advansys_exit);
18774 MODULE_LICENSE("GPL");