[SCSI] advansys: Convert to ISA driver model
[linux-2.6/libata-dev.git] / drivers / scsi / advansys.c
blobeda41f245bb433b0dbc5a0f00e8dffe814dc37ff
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,1,2,3,...}
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/isa.h>
773 #include <linux/eisa.h>
774 #include <linux/pci.h>
775 #include <linux/spinlock.h>
776 #include <linux/dma-mapping.h>
778 #include <asm/io.h>
779 #include <asm/system.h>
780 #include <asm/dma.h>
782 #include <scsi/scsi_cmnd.h>
783 #include <scsi/scsi_device.h>
784 #include <scsi/scsi_tcq.h>
785 #include <scsi/scsi.h>
786 #include <scsi/scsi_host.h>
788 /* FIXME: (by jejb@steeleye.com)
790 * Although all of the necessary command mapping places have the
791 * appropriate dma_map.. APIs, the driver still processes its internal
792 * queue using bus_to_virt() and virt_to_bus() which are illegal under
793 * the API. The entire queue processing structure will need to be
794 * altered to fix this.
796 #warning this driver is still not properly converted to the DMA API
799 * --- Driver Options
802 /* Enable driver assertions. */
803 #define ADVANSYS_ASSERT
805 /* Enable driver /proc statistics. */
806 #define ADVANSYS_STATS
808 /* Enable driver tracing. */
809 /* #define ADVANSYS_DEBUG */
812 * --- Asc Library Constants and Macros
815 #define ASC_LIB_VERSION_MAJOR 1
816 #define ASC_LIB_VERSION_MINOR 24
817 #define ASC_LIB_SERIAL_NUMBER 123
820 * Portable Data Types
822 * Any instance where a 32-bit long or pointer type is assumed
823 * for precision or HW defined structures, the following define
824 * types must be used. In Linux the char, short, and int types
825 * are all consistent at 8, 16, and 32 bits respectively. Pointers
826 * and long types are 64 bits on Alpha and UltraSPARC.
828 #define ASC_PADDR __u32 /* Physical/Bus address data type. */
829 #define ASC_VADDR __u32 /* Virtual address data type. */
830 #define ASC_DCNT __u32 /* Unsigned Data count type. */
831 #define ASC_SDCNT __s32 /* Signed Data count type. */
834 * These macros are used to convert a virtual address to a
835 * 32-bit value. This currently can be used on Linux Alpha
836 * which uses 64-bit virtual address but a 32-bit bus address.
837 * This is likely to break in the future, but doing this now
838 * will give us time to change the HW and FW to handle 64-bit
839 * addresses.
841 #define ASC_VADDR_TO_U32 virt_to_bus
842 #define ASC_U32_TO_VADDR bus_to_virt
844 typedef unsigned char uchar;
846 #ifndef TRUE
847 #define TRUE (1)
848 #endif
849 #ifndef FALSE
850 #define FALSE (0)
851 #endif
853 #define EOF (-1)
854 #define ERR (-1)
855 #define UW_ERR (uint)(0xFFFF)
856 #define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
857 #define AscPCIConfigVendorIDRegister 0x0000
858 #define AscPCIConfigDeviceIDRegister 0x0002
859 #define AscPCIConfigCommandRegister 0x0004
860 #define AscPCIConfigStatusRegister 0x0006
861 #define AscPCIConfigRevisionIDRegister 0x0008
862 #define AscPCIConfigCacheSize 0x000C
863 #define AscPCIConfigLatencyTimer 0x000D
864 #define AscPCIIOBaseRegister 0x0010
865 #define AscPCICmdRegBits_IOMemBusMaster 0x0007
866 #define ASC_PCI_ID2FUNC(id) (((id) >> 8) & 0x7)
867 #define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
869 #define ASC_DVCLIB_CALL_DONE (1)
870 #define ASC_DVCLIB_CALL_FAILED (0)
871 #define ASC_DVCLIB_CALL_ERROR (-1)
873 #define PCI_VENDOR_ID_ASP 0x10cd
874 #define PCI_DEVICE_ID_ASP_1200A 0x1100
875 #define PCI_DEVICE_ID_ASP_ABP940 0x1200
876 #define PCI_DEVICE_ID_ASP_ABP940U 0x1300
877 #define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
878 #define PCI_DEVICE_ID_38C0800_REV1 0x2500
879 #define PCI_DEVICE_ID_38C1600_REV1 0x2700
882 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
883 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
884 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
885 * SRB structure.
887 #define CC_VERY_LONG_SG_LIST 0
888 #define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
890 #define PortAddr unsigned short /* port address size */
891 #define inp(port) inb(port)
892 #define outp(port, byte) outb((byte), (port))
894 #define inpw(port) inw(port)
895 #define outpw(port, word) outw((word), (port))
897 #define ASC_MAX_SG_QUEUE 7
898 #define ASC_MAX_SG_LIST 255
900 #define ASC_CS_TYPE unsigned short
902 #define ASC_IS_ISA (0x0001)
903 #define ASC_IS_ISAPNP (0x0081)
904 #define ASC_IS_EISA (0x0002)
905 #define ASC_IS_PCI (0x0004)
906 #define ASC_IS_PCI_ULTRA (0x0104)
907 #define ASC_IS_PCMCIA (0x0008)
908 #define ASC_IS_MCA (0x0020)
909 #define ASC_IS_VL (0x0040)
910 #define ASC_ISA_PNP_PORT_ADDR (0x279)
911 #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
912 #define ASC_IS_WIDESCSI_16 (0x0100)
913 #define ASC_IS_WIDESCSI_32 (0x0200)
914 #define ASC_IS_BIG_ENDIAN (0x8000)
915 #define ASC_CHIP_MIN_VER_VL (0x01)
916 #define ASC_CHIP_MAX_VER_VL (0x07)
917 #define ASC_CHIP_MIN_VER_PCI (0x09)
918 #define ASC_CHIP_MAX_VER_PCI (0x0F)
919 #define ASC_CHIP_VER_PCI_BIT (0x08)
920 #define ASC_CHIP_MIN_VER_ISA (0x11)
921 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
922 #define ASC_CHIP_MAX_VER_ISA (0x27)
923 #define ASC_CHIP_VER_ISA_BIT (0x30)
924 #define ASC_CHIP_VER_ISAPNP_BIT (0x20)
925 #define ASC_CHIP_VER_ASYN_BUG (0x21)
926 #define ASC_CHIP_VER_PCI 0x08
927 #define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
928 #define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
929 #define ASC_CHIP_MIN_VER_EISA (0x41)
930 #define ASC_CHIP_MAX_VER_EISA (0x47)
931 #define ASC_CHIP_VER_EISA_BIT (0x40)
932 #define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
933 #define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER 0x21
934 #define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER 0x0A
935 #define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL)
936 #define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
937 #define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL)
938 #define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
939 #define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL)
940 #define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
941 #define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL)
942 #define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL)
944 #define ASC_SCSI_ID_BITS 3
945 #define ASC_SCSI_TIX_TYPE uchar
946 #define ASC_ALL_DEVICE_BIT_SET 0xFF
947 #define ASC_SCSI_BIT_ID_TYPE uchar
948 #define ASC_MAX_TID 7
949 #define ASC_MAX_LUN 7
950 #define ASC_SCSI_WIDTH_BIT_SET 0xFF
951 #define ASC_MAX_SENSE_LEN 32
952 #define ASC_MIN_SENSE_LEN 14
953 #define ASC_MAX_CDB_LEN 12
954 #define ASC_SCSI_RESET_HOLD_TIME_US 60
956 #define ADV_INQ_CLOCKING_ST_ONLY 0x0
957 #define ADV_INQ_CLOCKING_DT_ONLY 0x1
958 #define ADV_INQ_CLOCKING_ST_AND_DT 0x3
961 * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
962 * and CmdDt (Command Support Data) field bit definitions.
964 #define ADV_INQ_RTN_VPD_AND_CMDDT 0x3
965 #define ADV_INQ_RTN_CMDDT_FOR_OP_CODE 0x2
966 #define ADV_INQ_RTN_VPD_FOR_PG_CODE 0x1
967 #define ADV_INQ_RTN_STD_INQUIRY_DATA 0x0
969 #define ASC_SCSIDIR_NOCHK 0x00
970 #define ASC_SCSIDIR_T2H 0x08
971 #define ASC_SCSIDIR_H2T 0x10
972 #define ASC_SCSIDIR_NODATA 0x18
973 #define SCSI_ASC_NOMEDIA 0x3A
974 #define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4))
975 #define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F))
976 #define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13))
977 #define PUT_CDB1(x) ((uchar)((uint)(x) >> 8))
978 #define MS_CMD_DONE 0x00
979 #define MS_EXTEND 0x01
980 #define MS_SDTR_LEN 0x03
981 #define MS_SDTR_CODE 0x01
982 #define MS_WDTR_LEN 0x02
983 #define MS_WDTR_CODE 0x03
984 #define MS_MDP_LEN 0x05
985 #define MS_MDP_CODE 0x00
988 * Inquiry data structure and bitfield macros
990 * Only quantities of more than 1 bit are shifted, since the others are
991 * just tested for true or false. C bitfields aren't portable between big
992 * and little-endian platforms so they are not used.
995 #define ASC_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f)
996 #define ASC_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5)
997 #define ASC_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f)
998 #define ASC_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80)
999 #define ASC_INQ_ANSI_VER(inq) ((inq)->ver & 0x07)
1000 #define ASC_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3)
1001 #define ASC_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6)
1002 #define ASC_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f)
1003 #define ASC_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40)
1004 #define ASC_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80)
1005 #define ASC_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01)
1006 #define ASC_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02)
1007 #define ASC_INQ_LINK_CMD(inq) ((inq)->flags & 0x08)
1008 #define ASC_INQ_SYNC(inq) ((inq)->flags & 0x10)
1009 #define ASC_INQ_WIDE16(inq) ((inq)->flags & 0x20)
1010 #define ASC_INQ_WIDE32(inq) ((inq)->flags & 0x40)
1011 #define ASC_INQ_REL_ADDR(inq) ((inq)->flags & 0x80)
1012 #define ASC_INQ_INFO_UNIT(inq) ((inq)->info & 0x01)
1013 #define ASC_INQ_QUICK_ARB(inq) ((inq)->info & 0x02)
1014 #define ASC_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2)
1016 typedef struct {
1017 uchar periph;
1018 uchar devtype;
1019 uchar ver;
1020 uchar byte3;
1021 uchar add_len;
1022 uchar res1;
1023 uchar res2;
1024 uchar flags;
1025 uchar vendor_id[8];
1026 uchar product_id[16];
1027 uchar product_rev_level[4];
1028 } ASC_SCSI_INQUIRY;
1030 #define ASC_SG_LIST_PER_Q 7
1031 #define QS_FREE 0x00
1032 #define QS_READY 0x01
1033 #define QS_DISC1 0x02
1034 #define QS_DISC2 0x04
1035 #define QS_BUSY 0x08
1036 #define QS_ABORTED 0x40
1037 #define QS_DONE 0x80
1038 #define QC_NO_CALLBACK 0x01
1039 #define QC_SG_SWAP_QUEUE 0x02
1040 #define QC_SG_HEAD 0x04
1041 #define QC_DATA_IN 0x08
1042 #define QC_DATA_OUT 0x10
1043 #define QC_URGENT 0x20
1044 #define QC_MSG_OUT 0x40
1045 #define QC_REQ_SENSE 0x80
1046 #define QCSG_SG_XFER_LIST 0x02
1047 #define QCSG_SG_XFER_MORE 0x04
1048 #define QCSG_SG_XFER_END 0x08
1049 #define QD_IN_PROGRESS 0x00
1050 #define QD_NO_ERROR 0x01
1051 #define QD_ABORTED_BY_HOST 0x02
1052 #define QD_WITH_ERROR 0x04
1053 #define QD_INVALID_REQUEST 0x80
1054 #define QD_INVALID_HOST_NUM 0x81
1055 #define QD_INVALID_DEVICE 0x82
1056 #define QD_ERR_INTERNAL 0xFF
1057 #define QHSTA_NO_ERROR 0x00
1058 #define QHSTA_M_SEL_TIMEOUT 0x11
1059 #define QHSTA_M_DATA_OVER_RUN 0x12
1060 #define QHSTA_M_DATA_UNDER_RUN 0x12
1061 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
1062 #define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
1063 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1064 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
1065 #define QHSTA_D_HOST_ABORT_FAILED 0x23
1066 #define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
1067 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1068 #define QHSTA_D_ASPI_NO_BUF_POOL 0x26
1069 #define QHSTA_M_WTM_TIMEOUT 0x41
1070 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
1071 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
1072 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1073 #define QHSTA_M_TARGET_STATUS_BUSY 0x45
1074 #define QHSTA_M_BAD_TAG_CODE 0x46
1075 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
1076 #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1077 #define QHSTA_D_LRAM_CMP_ERROR 0x81
1078 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1079 #define ASC_FLAG_SCSIQ_REQ 0x01
1080 #define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
1081 #define ASC_FLAG_BIOS_ASYNC_IO 0x04
1082 #define ASC_FLAG_SRB_LINEAR_ADDR 0x08
1083 #define ASC_FLAG_WIN16 0x10
1084 #define ASC_FLAG_WIN32 0x20
1085 #define ASC_FLAG_ISA_OVER_16MB 0x40
1086 #define ASC_FLAG_DOS_VM_CALLBACK 0x80
1087 #define ASC_TAG_FLAG_EXTRA_BYTES 0x10
1088 #define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
1089 #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
1090 #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1091 #define ASC_SCSIQ_CPY_BEG 4
1092 #define ASC_SCSIQ_SGHD_CPY_BEG 2
1093 #define ASC_SCSIQ_B_FWD 0
1094 #define ASC_SCSIQ_B_BWD 1
1095 #define ASC_SCSIQ_B_STATUS 2
1096 #define ASC_SCSIQ_B_QNO 3
1097 #define ASC_SCSIQ_B_CNTL 4
1098 #define ASC_SCSIQ_B_SG_QUEUE_CNT 5
1099 #define ASC_SCSIQ_D_DATA_ADDR 8
1100 #define ASC_SCSIQ_D_DATA_CNT 12
1101 #define ASC_SCSIQ_B_SENSE_LEN 20
1102 #define ASC_SCSIQ_DONE_INFO_BEG 22
1103 #define ASC_SCSIQ_D_SRBPTR 22
1104 #define ASC_SCSIQ_B_TARGET_IX 26
1105 #define ASC_SCSIQ_B_CDB_LEN 28
1106 #define ASC_SCSIQ_B_TAG_CODE 29
1107 #define ASC_SCSIQ_W_VM_ID 30
1108 #define ASC_SCSIQ_DONE_STATUS 32
1109 #define ASC_SCSIQ_HOST_STATUS 33
1110 #define ASC_SCSIQ_SCSI_STATUS 34
1111 #define ASC_SCSIQ_CDB_BEG 36
1112 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1113 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
1114 #define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
1115 #define ASC_SCSIQ_B_SG_WK_QP 49
1116 #define ASC_SCSIQ_B_SG_WK_IX 50
1117 #define ASC_SCSIQ_W_ALT_DC1 52
1118 #define ASC_SCSIQ_B_LIST_CNT 6
1119 #define ASC_SCSIQ_B_CUR_LIST_CNT 7
1120 #define ASC_SGQ_B_SG_CNTL 4
1121 #define ASC_SGQ_B_SG_HEAD_QP 5
1122 #define ASC_SGQ_B_SG_LIST_CNT 6
1123 #define ASC_SGQ_B_SG_CUR_LIST_CNT 7
1124 #define ASC_SGQ_LIST_BEG 8
1125 #define ASC_DEF_SCSI1_QNG 4
1126 #define ASC_MAX_SCSI1_QNG 4
1127 #define ASC_DEF_SCSI2_QNG 16
1128 #define ASC_MAX_SCSI2_QNG 32
1129 #define ASC_TAG_CODE_MASK 0x23
1130 #define ASC_STOP_REQ_RISC_STOP 0x01
1131 #define ASC_STOP_ACK_RISC_STOP 0x03
1132 #define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
1133 #define ASC_STOP_CLEAN_UP_DISC_Q 0x20
1134 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1135 #define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1136 #define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1137 #define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
1138 #define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
1139 #define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
1140 #define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1141 #define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
1143 typedef struct asc_scsiq_1 {
1144 uchar status;
1145 uchar q_no;
1146 uchar cntl;
1147 uchar sg_queue_cnt;
1148 uchar target_id;
1149 uchar target_lun;
1150 ASC_PADDR data_addr;
1151 ASC_DCNT data_cnt;
1152 ASC_PADDR sense_addr;
1153 uchar sense_len;
1154 uchar extra_bytes;
1155 } ASC_SCSIQ_1;
1157 typedef struct asc_scsiq_2 {
1158 ASC_VADDR srb_ptr;
1159 uchar target_ix;
1160 uchar flag;
1161 uchar cdb_len;
1162 uchar tag_code;
1163 ushort vm_id;
1164 } ASC_SCSIQ_2;
1166 typedef struct asc_scsiq_3 {
1167 uchar done_stat;
1168 uchar host_stat;
1169 uchar scsi_stat;
1170 uchar scsi_msg;
1171 } ASC_SCSIQ_3;
1173 typedef struct asc_scsiq_4 {
1174 uchar cdb[ASC_MAX_CDB_LEN];
1175 uchar y_first_sg_list_qp;
1176 uchar y_working_sg_qp;
1177 uchar y_working_sg_ix;
1178 uchar y_res;
1179 ushort x_req_count;
1180 ushort x_reconnect_rtn;
1181 ASC_PADDR x_saved_data_addr;
1182 ASC_DCNT x_saved_data_cnt;
1183 } ASC_SCSIQ_4;
1185 typedef struct asc_q_done_info {
1186 ASC_SCSIQ_2 d2;
1187 ASC_SCSIQ_3 d3;
1188 uchar q_status;
1189 uchar q_no;
1190 uchar cntl;
1191 uchar sense_len;
1192 uchar extra_bytes;
1193 uchar res;
1194 ASC_DCNT remain_bytes;
1195 } ASC_QDONE_INFO;
1197 typedef struct asc_sg_list {
1198 ASC_PADDR addr;
1199 ASC_DCNT bytes;
1200 } ASC_SG_LIST;
1202 typedef struct asc_sg_head {
1203 ushort entry_cnt;
1204 ushort queue_cnt;
1205 ushort entry_to_copy;
1206 ushort res;
1207 ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1208 } ASC_SG_HEAD;
1210 #define ASC_MIN_SG_LIST 2
1212 typedef struct asc_min_sg_head {
1213 ushort entry_cnt;
1214 ushort queue_cnt;
1215 ushort entry_to_copy;
1216 ushort res;
1217 ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
1218 } ASC_MIN_SG_HEAD;
1220 #define QCX_SORT (0x0001)
1221 #define QCX_COALEASE (0x0002)
1223 typedef struct asc_scsi_q {
1224 ASC_SCSIQ_1 q1;
1225 ASC_SCSIQ_2 q2;
1226 uchar *cdbptr;
1227 ASC_SG_HEAD *sg_head;
1228 ushort remain_sg_entry_cnt;
1229 ushort next_sg_index;
1230 } ASC_SCSI_Q;
1232 typedef struct asc_scsi_req_q {
1233 ASC_SCSIQ_1 r1;
1234 ASC_SCSIQ_2 r2;
1235 uchar *cdbptr;
1236 ASC_SG_HEAD *sg_head;
1237 uchar *sense_ptr;
1238 ASC_SCSIQ_3 r3;
1239 uchar cdb[ASC_MAX_CDB_LEN];
1240 uchar sense[ASC_MIN_SENSE_LEN];
1241 } ASC_SCSI_REQ_Q;
1243 typedef struct asc_scsi_bios_req_q {
1244 ASC_SCSIQ_1 r1;
1245 ASC_SCSIQ_2 r2;
1246 uchar *cdbptr;
1247 ASC_SG_HEAD *sg_head;
1248 uchar *sense_ptr;
1249 ASC_SCSIQ_3 r3;
1250 uchar cdb[ASC_MAX_CDB_LEN];
1251 uchar sense[ASC_MIN_SENSE_LEN];
1252 } ASC_SCSI_BIOS_REQ_Q;
1254 typedef struct asc_risc_q {
1255 uchar fwd;
1256 uchar bwd;
1257 ASC_SCSIQ_1 i1;
1258 ASC_SCSIQ_2 i2;
1259 ASC_SCSIQ_3 i3;
1260 ASC_SCSIQ_4 i4;
1261 } ASC_RISC_Q;
1263 typedef struct asc_sg_list_q {
1264 uchar seq_no;
1265 uchar q_no;
1266 uchar cntl;
1267 uchar sg_head_qp;
1268 uchar sg_list_cnt;
1269 uchar sg_cur_list_cnt;
1270 } ASC_SG_LIST_Q;
1272 typedef struct asc_risc_sg_list_q {
1273 uchar fwd;
1274 uchar bwd;
1275 ASC_SG_LIST_Q sg;
1276 ASC_SG_LIST sg_list[7];
1277 } ASC_RISC_SG_LIST_Q;
1279 #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL
1280 #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024
1281 #define ASCQ_ERR_NO_ERROR 0
1282 #define ASCQ_ERR_IO_NOT_FOUND 1
1283 #define ASCQ_ERR_LOCAL_MEM 2
1284 #define ASCQ_ERR_CHKSUM 3
1285 #define ASCQ_ERR_START_CHIP 4
1286 #define ASCQ_ERR_INT_TARGET_ID 5
1287 #define ASCQ_ERR_INT_LOCAL_MEM 6
1288 #define ASCQ_ERR_HALT_RISC 7
1289 #define ASCQ_ERR_GET_ASPI_ENTRY 8
1290 #define ASCQ_ERR_CLOSE_ASPI 9
1291 #define ASCQ_ERR_HOST_INQUIRY 0x0A
1292 #define ASCQ_ERR_SAVED_SRB_BAD 0x0B
1293 #define ASCQ_ERR_QCNTL_SG_LIST 0x0C
1294 #define ASCQ_ERR_Q_STATUS 0x0D
1295 #define ASCQ_ERR_WR_SCSIQ 0x0E
1296 #define ASCQ_ERR_PC_ADDR 0x0F
1297 #define ASCQ_ERR_SYN_OFFSET 0x10
1298 #define ASCQ_ERR_SYN_XFER_TIME 0x11
1299 #define ASCQ_ERR_LOCK_DMA 0x12
1300 #define ASCQ_ERR_UNLOCK_DMA 0x13
1301 #define ASCQ_ERR_VDS_CHK_INSTALL 0x14
1302 #define ASCQ_ERR_MICRO_CODE_HALT 0x15
1303 #define ASCQ_ERR_SET_LRAM_ADDR 0x16
1304 #define ASCQ_ERR_CUR_QNG 0x17
1305 #define ASCQ_ERR_SG_Q_LINKS 0x18
1306 #define ASCQ_ERR_SCSIQ_PTR 0x19
1307 #define ASCQ_ERR_ISR_RE_ENTRY 0x1A
1308 #define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
1309 #define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
1310 #define ASCQ_ERR_SG_LIST_ODD_ADDRESS 0x1D
1311 #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1312 #define ASCQ_ERR_SCSIQ_NULL_PTR 0x1F
1313 #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR 0x20
1314 #define ASCQ_ERR_GET_NUM_OF_FREE_Q 0x21
1315 #define ASCQ_ERR_SEND_SCSI_Q 0x22
1316 #define ASCQ_ERR_HOST_REQ_RISC_HALT 0x23
1317 #define ASCQ_ERR_RESET_SDTR 0x24
1320 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
1322 #define ASC_WARN_NO_ERROR 0x0000
1323 #define ASC_WARN_IO_PORT_ROTATE 0x0001
1324 #define ASC_WARN_EEPROM_CHKSUM 0x0002
1325 #define ASC_WARN_IRQ_MODIFIED 0x0004
1326 #define ASC_WARN_AUTO_CONFIG 0x0008
1327 #define ASC_WARN_CMD_QNG_CONFLICT 0x0010
1328 #define ASC_WARN_EEPROM_RECOVER 0x0020
1329 #define ASC_WARN_CFG_MSW_RECOVER 0x0040
1330 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1333 * Error code values are set in ASC_DVC_VAR 'err_code'.
1335 #define ASC_IERR_WRITE_EEPROM 0x0001
1336 #define ASC_IERR_MCODE_CHKSUM 0x0002
1337 #define ASC_IERR_SET_PC_ADDR 0x0004
1338 #define ASC_IERR_START_STOP_CHIP 0x0008
1339 #define ASC_IERR_IRQ_NO 0x0010
1340 #define ASC_IERR_SET_IRQ_NO 0x0020
1341 #define ASC_IERR_CHIP_VERSION 0x0040
1342 #define ASC_IERR_SET_SCSI_ID 0x0080
1343 #define ASC_IERR_GET_PHY_ADDR 0x0100
1344 #define ASC_IERR_BAD_SIGNATURE 0x0200
1345 #define ASC_IERR_NO_BUS_TYPE 0x0400
1346 #define ASC_IERR_SCAM 0x0800
1347 #define ASC_IERR_SET_SDTR 0x1000
1348 #define ASC_IERR_RW_LRAM 0x8000
1350 #define ASC_DEF_IRQ_NO 10
1351 #define ASC_MAX_IRQ_NO 15
1352 #define ASC_MIN_IRQ_NO 10
1353 #define ASC_MIN_REMAIN_Q (0x02)
1354 #define ASC_DEF_MAX_TOTAL_QNG (0xF0)
1355 #define ASC_MIN_TAG_Q_PER_DVC (0x04)
1356 #define ASC_DEF_TAG_Q_PER_DVC (0x04)
1357 #define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q
1358 #define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1359 #define ASC_MAX_TOTAL_QNG 240
1360 #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1361 #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
1362 #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
1363 #define ASC_MAX_INRAM_TAG_QNG 16
1364 #define ASC_IOADR_TABLE_MAX_IX 11
1365 #define ASC_IOADR_GAP 0x10
1366 #define ASC_LIB_SCSIQ_WK_SP 256
1367 #define ASC_MAX_SYN_XFER_NO 16
1368 #define ASC_SYN_MAX_OFFSET 0x0F
1369 #define ASC_DEF_SDTR_OFFSET 0x0F
1370 #define ASC_DEF_SDTR_INDEX 0x00
1371 #define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
1372 #define SYN_XFER_NS_0 25
1373 #define SYN_XFER_NS_1 30
1374 #define SYN_XFER_NS_2 35
1375 #define SYN_XFER_NS_3 40
1376 #define SYN_XFER_NS_4 50
1377 #define SYN_XFER_NS_5 60
1378 #define SYN_XFER_NS_6 70
1379 #define SYN_XFER_NS_7 85
1380 #define SYN_ULTRA_XFER_NS_0 12
1381 #define SYN_ULTRA_XFER_NS_1 19
1382 #define SYN_ULTRA_XFER_NS_2 25
1383 #define SYN_ULTRA_XFER_NS_3 32
1384 #define SYN_ULTRA_XFER_NS_4 38
1385 #define SYN_ULTRA_XFER_NS_5 44
1386 #define SYN_ULTRA_XFER_NS_6 50
1387 #define SYN_ULTRA_XFER_NS_7 57
1388 #define SYN_ULTRA_XFER_NS_8 63
1389 #define SYN_ULTRA_XFER_NS_9 69
1390 #define SYN_ULTRA_XFER_NS_10 75
1391 #define SYN_ULTRA_XFER_NS_11 82
1392 #define SYN_ULTRA_XFER_NS_12 88
1393 #define SYN_ULTRA_XFER_NS_13 94
1394 #define SYN_ULTRA_XFER_NS_14 100
1395 #define SYN_ULTRA_XFER_NS_15 107
1397 typedef struct ext_msg {
1398 uchar msg_type;
1399 uchar msg_len;
1400 uchar msg_req;
1401 union {
1402 struct {
1403 uchar sdtr_xfer_period;
1404 uchar sdtr_req_ack_offset;
1405 } sdtr;
1406 struct {
1407 uchar wdtr_width;
1408 } wdtr;
1409 struct {
1410 uchar mdp_b3;
1411 uchar mdp_b2;
1412 uchar mdp_b1;
1413 uchar mdp_b0;
1414 } mdp;
1415 } u_ext_msg;
1416 uchar res;
1417 } EXT_MSG;
1419 #define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
1420 #define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
1421 #define wdtr_width u_ext_msg.wdtr.wdtr_width
1422 #define mdp_b3 u_ext_msg.mdp_b3
1423 #define mdp_b2 u_ext_msg.mdp_b2
1424 #define mdp_b1 u_ext_msg.mdp_b1
1425 #define mdp_b0 u_ext_msg.mdp_b0
1427 typedef struct asc_dvc_cfg {
1428 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1429 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1430 ASC_SCSI_BIT_ID_TYPE disc_enable;
1431 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1432 uchar chip_scsi_id;
1433 uchar isa_dma_speed;
1434 uchar isa_dma_channel;
1435 uchar chip_version;
1436 ushort lib_serial_no;
1437 ushort lib_version;
1438 ushort mcode_date;
1439 ushort mcode_version;
1440 uchar max_tag_qng[ASC_MAX_TID + 1];
1441 uchar *overrun_buf;
1442 uchar sdtr_period_offset[ASC_MAX_TID + 1];
1443 ushort pci_slot_info;
1444 uchar adapter_info[6];
1445 struct device *dev;
1446 } ASC_DVC_CFG;
1448 #define ASC_DEF_DVC_CNTL 0xFFFF
1449 #define ASC_DEF_CHIP_SCSI_ID 7
1450 #define ASC_DEF_ISA_DMA_SPEED 4
1451 #define ASC_INIT_STATE_NULL 0x0000
1452 #define ASC_INIT_STATE_BEG_GET_CFG 0x0001
1453 #define ASC_INIT_STATE_END_GET_CFG 0x0002
1454 #define ASC_INIT_STATE_BEG_SET_CFG 0x0004
1455 #define ASC_INIT_STATE_END_SET_CFG 0x0008
1456 #define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
1457 #define ASC_INIT_STATE_END_LOAD_MC 0x0020
1458 #define ASC_INIT_STATE_BEG_INQUIRY 0x0040
1459 #define ASC_INIT_STATE_END_INQUIRY 0x0080
1460 #define ASC_INIT_RESET_SCSI_DONE 0x0100
1461 #define ASC_INIT_STATE_WITHOUT_EEP 0x8000
1462 #define ASC_BUG_FIX_IF_NOT_DWB 0x0001
1463 #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
1464 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1465 #define ASC_MIN_TAGGED_CMD 7
1466 #define ASC_MAX_SCSI_RESET_WAIT 30
1468 struct asc_dvc_var; /* Forward Declaration. */
1470 typedef void (*ASC_ISR_CALLBACK) (struct asc_dvc_var *, ASC_QDONE_INFO *);
1471 typedef int (*ASC_EXE_CALLBACK) (struct asc_dvc_var *, ASC_SCSI_Q *);
1473 typedef struct asc_dvc_var {
1474 PortAddr iop_base;
1475 ushort err_code;
1476 ushort dvc_cntl;
1477 ushort bug_fix_cntl;
1478 ushort bus_type;
1479 ASC_ISR_CALLBACK isr_callback;
1480 ASC_EXE_CALLBACK exe_callback;
1481 ASC_SCSI_BIT_ID_TYPE init_sdtr;
1482 ASC_SCSI_BIT_ID_TYPE sdtr_done;
1483 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1484 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1485 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1486 ASC_SCSI_BIT_ID_TYPE start_motor;
1487 uchar scsi_reset_wait;
1488 uchar chip_no;
1489 char is_in_int;
1490 uchar max_total_qng;
1491 uchar cur_total_qng;
1492 uchar in_critical_cnt;
1493 uchar irq_no;
1494 uchar last_q_shortage;
1495 ushort init_state;
1496 uchar cur_dvc_qng[ASC_MAX_TID + 1];
1497 uchar max_dvc_qng[ASC_MAX_TID + 1];
1498 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
1499 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
1500 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1501 ASC_DVC_CFG *cfg;
1502 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1503 char redo_scam;
1504 ushort res2;
1505 uchar dos_int13_table[ASC_MAX_TID + 1];
1506 ASC_DCNT max_dma_count;
1507 ASC_SCSI_BIT_ID_TYPE no_scam;
1508 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1509 uchar max_sdtr_index;
1510 uchar host_init_sdtr_index;
1511 struct asc_board *drv_ptr;
1512 ASC_DCNT uc_break;
1513 } ASC_DVC_VAR;
1515 typedef struct asc_dvc_inq_info {
1516 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1517 } ASC_DVC_INQ_INFO;
1519 typedef struct asc_cap_info {
1520 ASC_DCNT lba;
1521 ASC_DCNT blk_size;
1522 } ASC_CAP_INFO;
1524 typedef struct asc_cap_info_array {
1525 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1526 } ASC_CAP_INFO_ARRAY;
1528 #define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
1529 #define ASC_MCNTL_NULL_TARGET (ushort)0x0002
1530 #define ASC_CNTL_INITIATOR (ushort)0x0001
1531 #define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
1532 #define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
1533 #define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
1534 #define ASC_CNTL_NO_SCAM (ushort)0x0010
1535 #define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
1536 #define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
1537 #define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
1538 #define ASC_CNTL_RESET_SCSI (ushort)0x0200
1539 #define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
1540 #define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
1541 #define ASC_CNTL_SCSI_PARITY (ushort)0x1000
1542 #define ASC_CNTL_BURST_MODE (ushort)0x2000
1543 #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1544 #define ASC_EEP_DVC_CFG_BEG_VL 2
1545 #define ASC_EEP_MAX_DVC_ADDR_VL 15
1546 #define ASC_EEP_DVC_CFG_BEG 32
1547 #define ASC_EEP_MAX_DVC_ADDR 45
1548 #define ASC_EEP_DEFINED_WORDS 10
1549 #define ASC_EEP_MAX_ADDR 63
1550 #define ASC_EEP_RES_WORDS 0
1551 #define ASC_EEP_MAX_RETRY 20
1552 #define ASC_MAX_INIT_BUSY_RETRY 8
1553 #define ASC_EEP_ISA_PNP_WSIZE 16
1556 * These macros keep the chip SCSI id and ISA DMA speed
1557 * bitfields in board order. C bitfields aren't portable
1558 * between big and little-endian platforms so they are
1559 * not used.
1562 #define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
1563 #define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
1564 #define ASC_EEP_SET_CHIP_ID(cfg, sid) \
1565 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
1566 #define ASC_EEP_SET_DMA_SPD(cfg, spd) \
1567 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
1569 typedef struct asceep_config {
1570 ushort cfg_lsw;
1571 ushort cfg_msw;
1572 uchar init_sdtr;
1573 uchar disc_enable;
1574 uchar use_cmd_qng;
1575 uchar start_motor;
1576 uchar max_total_qng;
1577 uchar max_tag_qng;
1578 uchar bios_scan;
1579 uchar power_up_wait;
1580 uchar no_scam;
1581 uchar id_speed; /* low order 4 bits is chip scsi id */
1582 /* high order 4 bits is isa dma speed */
1583 uchar dos_int13_table[ASC_MAX_TID + 1];
1584 uchar adapter_info[6];
1585 ushort cntl;
1586 ushort chksum;
1587 } ASCEEP_CONFIG;
1589 #define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800
1590 #define ASC_PCI_CFG_LSW_BURST_MODE 0x0080
1591 #define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020
1593 #define ASC_EEP_CMD_READ 0x80
1594 #define ASC_EEP_CMD_WRITE 0x40
1595 #define ASC_EEP_CMD_WRITE_ABLE 0x30
1596 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
1597 #define ASC_OVERRUN_BSIZE 0x00000048UL
1598 #define ASC_CTRL_BREAK_ONCE 0x0001
1599 #define ASC_CTRL_BREAK_STAY_IDLE 0x0002
1600 #define ASCV_MSGOUT_BEG 0x0000
1601 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1602 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1603 #define ASCV_BREAK_SAVED_CODE (ushort)0x0006
1604 #define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
1605 #define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
1606 #define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
1607 #define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
1608 #define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
1609 #define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
1610 #define ASCV_BREAK_ADDR (ushort)0x0028
1611 #define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
1612 #define ASCV_BREAK_CONTROL (ushort)0x002C
1613 #define ASCV_BREAK_HIT_COUNT (ushort)0x002E
1615 #define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
1616 #define ASCV_MCODE_CHKSUM_W (ushort)0x0032
1617 #define ASCV_MCODE_SIZE_W (ushort)0x0034
1618 #define ASCV_STOP_CODE_B (ushort)0x0036
1619 #define ASCV_DVC_ERR_CODE_B (ushort)0x0037
1620 #define ASCV_OVERRUN_PADDR_D (ushort)0x0038
1621 #define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
1622 #define ASCV_HALTCODE_W (ushort)0x0040
1623 #define ASCV_CHKSUM_W (ushort)0x0042
1624 #define ASCV_MC_DATE_W (ushort)0x0044
1625 #define ASCV_MC_VER_W (ushort)0x0046
1626 #define ASCV_NEXTRDY_B (ushort)0x0048
1627 #define ASCV_DONENEXT_B (ushort)0x0049
1628 #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1629 #define ASCV_SCSIBUSY_B (ushort)0x004B
1630 #define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
1631 #define ASCV_CURCDB_B (ushort)0x004D
1632 #define ASCV_RCLUN_B (ushort)0x004E
1633 #define ASCV_BUSY_QHEAD_B (ushort)0x004F
1634 #define ASCV_DISC1_QHEAD_B (ushort)0x0050
1635 #define ASCV_DISC_ENABLE_B (ushort)0x0052
1636 #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1637 #define ASCV_HOSTSCSI_ID_B (ushort)0x0055
1638 #define ASCV_MCODE_CNTL_B (ushort)0x0056
1639 #define ASCV_NULL_TARGET_B (ushort)0x0057
1640 #define ASCV_FREE_Q_HEAD_W (ushort)0x0058
1641 #define ASCV_DONE_Q_TAIL_W (ushort)0x005A
1642 #define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
1643 #define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
1644 #define ASCV_HOST_FLAG_B (ushort)0x005D
1645 #define ASCV_TOTAL_READY_Q_B (ushort)0x0064
1646 #define ASCV_VER_SERIAL_B (ushort)0x0065
1647 #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1648 #define ASCV_WTM_FLAG_B (ushort)0x0068
1649 #define ASCV_RISC_FLAG_B (ushort)0x006A
1650 #define ASCV_REQ_SG_LIST_QP (ushort)0x006B
1651 #define ASC_HOST_FLAG_IN_ISR 0x01
1652 #define ASC_HOST_FLAG_ACK_INT 0x02
1653 #define ASC_RISC_FLAG_GEN_INT 0x01
1654 #define ASC_RISC_FLAG_REQ_SG_LIST 0x02
1655 #define IOP_CTRL (0x0F)
1656 #define IOP_STATUS (0x0E)
1657 #define IOP_INT_ACK IOP_STATUS
1658 #define IOP_REG_IFC (0x0D)
1659 #define IOP_SYN_OFFSET (0x0B)
1660 #define IOP_EXTRA_CONTROL (0x0D)
1661 #define IOP_REG_PC (0x0C)
1662 #define IOP_RAM_ADDR (0x0A)
1663 #define IOP_RAM_DATA (0x08)
1664 #define IOP_EEP_DATA (0x06)
1665 #define IOP_EEP_CMD (0x07)
1666 #define IOP_VERSION (0x03)
1667 #define IOP_CONFIG_HIGH (0x04)
1668 #define IOP_CONFIG_LOW (0x02)
1669 #define IOP_SIG_BYTE (0x01)
1670 #define IOP_SIG_WORD (0x00)
1671 #define IOP_REG_DC1 (0x0E)
1672 #define IOP_REG_DC0 (0x0C)
1673 #define IOP_REG_SB (0x0B)
1674 #define IOP_REG_DA1 (0x0A)
1675 #define IOP_REG_DA0 (0x08)
1676 #define IOP_REG_SC (0x09)
1677 #define IOP_DMA_SPEED (0x07)
1678 #define IOP_REG_FLAG (0x07)
1679 #define IOP_FIFO_H (0x06)
1680 #define IOP_FIFO_L (0x04)
1681 #define IOP_REG_ID (0x05)
1682 #define IOP_REG_QP (0x03)
1683 #define IOP_REG_IH (0x02)
1684 #define IOP_REG_IX (0x01)
1685 #define IOP_REG_AX (0x00)
1686 #define IFC_REG_LOCK (0x00)
1687 #define IFC_REG_UNLOCK (0x09)
1688 #define IFC_WR_EN_FILTER (0x10)
1689 #define IFC_RD_NO_EEPROM (0x10)
1690 #define IFC_SLEW_RATE (0x20)
1691 #define IFC_ACT_NEG (0x40)
1692 #define IFC_INP_FILTER (0x80)
1693 #define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
1694 #define SC_SEL (uchar)(0x80)
1695 #define SC_BSY (uchar)(0x40)
1696 #define SC_ACK (uchar)(0x20)
1697 #define SC_REQ (uchar)(0x10)
1698 #define SC_ATN (uchar)(0x08)
1699 #define SC_IO (uchar)(0x04)
1700 #define SC_CD (uchar)(0x02)
1701 #define SC_MSG (uchar)(0x01)
1702 #define SEC_SCSI_CTL (uchar)(0x80)
1703 #define SEC_ACTIVE_NEGATE (uchar)(0x40)
1704 #define SEC_SLEW_RATE (uchar)(0x20)
1705 #define SEC_ENABLE_FILTER (uchar)(0x10)
1706 #define ASC_HALT_EXTMSG_IN (ushort)0x8000
1707 #define ASC_HALT_CHK_CONDITION (ushort)0x8100
1708 #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1709 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
1710 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
1711 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1712 #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1713 #define ASC_MAX_QNO 0xF8
1714 #define ASC_DATA_SEC_BEG (ushort)0x0080
1715 #define ASC_DATA_SEC_END (ushort)0x0080
1716 #define ASC_CODE_SEC_BEG (ushort)0x0080
1717 #define ASC_CODE_SEC_END (ushort)0x0080
1718 #define ASC_QADR_BEG (0x4000)
1719 #define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
1720 #define ASC_QADR_END (ushort)0x7FFF
1721 #define ASC_QLAST_ADR (ushort)0x7FC0
1722 #define ASC_QBLK_SIZE 0x40
1723 #define ASC_BIOS_DATA_QBEG 0xF8
1724 #define ASC_MIN_ACTIVE_QNO 0x01
1725 #define ASC_QLINK_END 0xFF
1726 #define ASC_EEPROM_WORDS 0x10
1727 #define ASC_MAX_MGS_LEN 0x10
1728 #define ASC_BIOS_ADDR_DEF 0xDC00
1729 #define ASC_BIOS_SIZE 0x3800
1730 #define ASC_BIOS_RAM_OFF 0x3800
1731 #define ASC_BIOS_RAM_SIZE 0x800
1732 #define ASC_BIOS_MIN_ADDR 0xC000
1733 #define ASC_BIOS_MAX_ADDR 0xEC00
1734 #define ASC_BIOS_BANK_SIZE 0x0400
1735 #define ASC_MCODE_START_ADDR 0x0080
1736 #define ASC_CFG0_HOST_INT_ON 0x0020
1737 #define ASC_CFG0_BIOS_ON 0x0040
1738 #define ASC_CFG0_VERA_BURST_ON 0x0080
1739 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
1740 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
1741 #define ASC_CFG1_LRAM_8BITS_ON 0x0800
1742 #define ASC_CFG_MSW_CLR_MASK 0x3080
1743 #define CSW_TEST1 (ASC_CS_TYPE)0x8000
1744 #define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
1745 #define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
1746 #define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
1747 #define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
1748 #define CSW_TEST2 (ASC_CS_TYPE)0x0400
1749 #define CSW_TEST3 (ASC_CS_TYPE)0x0200
1750 #define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
1751 #define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
1752 #define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
1753 #define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
1754 #define CSW_HALTED (ASC_CS_TYPE)0x0010
1755 #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1756 #define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
1757 #define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
1758 #define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
1759 #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1760 #define CIW_INT_ACK (ASC_CS_TYPE)0x0100
1761 #define CIW_TEST1 (ASC_CS_TYPE)0x0200
1762 #define CIW_TEST2 (ASC_CS_TYPE)0x0400
1763 #define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
1764 #define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
1765 #define CC_CHIP_RESET (uchar)0x80
1766 #define CC_SCSI_RESET (uchar)0x40
1767 #define CC_HALT (uchar)0x20
1768 #define CC_SINGLE_STEP (uchar)0x10
1769 #define CC_DMA_ABLE (uchar)0x08
1770 #define CC_TEST (uchar)0x04
1771 #define CC_BANK_ONE (uchar)0x02
1772 #define CC_DIAG (uchar)0x01
1773 #define ASC_1000_ID0W 0x04C1
1774 #define ASC_1000_ID0W_FIX 0x00C1
1775 #define ASC_1000_ID1B 0x25
1776 #define ASC_EISA_REV_IOP_MASK (0x0C83)
1777 #define ASC_EISA_PID_IOP_MASK (0x0C80)
1778 #define ASC_EISA_CFG_IOP_MASK (0x0C86)
1779 #define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
1780 #define INS_HALTINT (ushort)0x6281
1781 #define INS_HALT (ushort)0x6280
1782 #define INS_SINT (ushort)0x6200
1783 #define INS_RFLAG_WTM (ushort)0x7380
1784 #define ASC_MC_SAVE_CODE_WSIZE 0x500
1785 #define ASC_MC_SAVE_DATA_WSIZE 0x40
1787 typedef struct asc_mc_saved {
1788 ushort data[ASC_MC_SAVE_DATA_WSIZE];
1789 ushort code[ASC_MC_SAVE_CODE_WSIZE];
1790 } ASC_MC_SAVED;
1792 #define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1793 #define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1794 #define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1795 #define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1796 #define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1797 #define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1798 #define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
1799 #define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
1800 #define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1801 #define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1802 #define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1803 #define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1804 #define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1805 #define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1806 #define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1807 #define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
1808 #define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
1809 #define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
1810 #define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
1811 #define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
1812 #define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
1813 #define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
1814 #define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
1815 #define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
1816 #define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
1817 #define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
1818 #define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1819 #define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1820 #define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
1821 #define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
1822 #define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
1823 #define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
1824 #define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1825 #define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
1826 #define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
1827 #define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
1828 #define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
1829 #define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
1830 #define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
1831 #define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
1832 #define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1833 #define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1834 #define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
1835 #define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
1836 #define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
1837 #define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
1838 #define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
1839 #define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
1840 #define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
1841 #define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
1842 #define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
1843 #define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
1844 #define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
1845 #define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
1846 #define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
1847 #define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
1848 #define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
1849 #define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
1850 #define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
1851 #define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
1852 #define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
1853 #define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
1854 #define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
1855 #define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
1856 #define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
1857 #define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
1858 #define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
1859 #define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
1861 static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1862 static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1863 static void AscWaitEEPRead(void);
1864 static void AscWaitEEPWrite(void);
1865 static ushort AscReadEEPWord(PortAddr, uchar);
1866 static ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1867 static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1868 static int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1869 static int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1870 static int AscStartChip(PortAddr);
1871 static int AscStopChip(PortAddr);
1872 static void AscSetChipIH(PortAddr, ushort);
1873 static int AscIsChipHalted(PortAddr);
1874 static void AscAckInterrupt(PortAddr);
1875 static void AscDisableInterrupt(PortAddr);
1876 static void AscEnableInterrupt(PortAddr);
1877 static void AscSetBank(PortAddr, uchar);
1878 static int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1879 #ifdef CONFIG_ISA
1880 static ushort AscGetIsaDmaChannel(PortAddr);
1881 static ushort AscSetIsaDmaChannel(PortAddr, ushort);
1882 static uchar AscSetIsaDmaSpeed(PortAddr, uchar);
1883 static uchar AscGetIsaDmaSpeed(PortAddr);
1884 #endif /* CONFIG_ISA */
1885 static uchar AscReadLramByte(PortAddr, ushort);
1886 static ushort AscReadLramWord(PortAddr, ushort);
1887 #if CC_VERY_LONG_SG_LIST
1888 static ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1889 #endif /* CC_VERY_LONG_SG_LIST */
1890 static void AscWriteLramWord(PortAddr, ushort, ushort);
1891 static void AscWriteLramByte(PortAddr, ushort, uchar);
1892 static ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
1893 static void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1894 static void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1895 static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1896 static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
1897 static ushort AscInitAscDvcVar(ASC_DVC_VAR *);
1898 static ushort AscInitFromEEP(ASC_DVC_VAR *);
1899 static ushort AscInitFromAscDvcVar(ASC_DVC_VAR *);
1900 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1901 static int AscTestExternalLram(ASC_DVC_VAR *);
1902 static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1903 static uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1904 static void AscSetChipSDTR(PortAddr, uchar, uchar);
1905 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1906 static uchar AscAllocFreeQueue(PortAddr, uchar);
1907 static uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1908 static int AscHostReqRiscHalt(PortAddr);
1909 static int AscStopQueueExe(PortAddr);
1910 static int AscSendScsiQueue(ASC_DVC_VAR *,
1911 ASC_SCSI_Q *scsiq, uchar n_q_required);
1912 static int AscPutReadyQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1913 static int AscPutReadySgListQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar);
1914 static int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1915 static int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1916 static ushort AscInitLram(ASC_DVC_VAR *);
1917 static ushort AscInitQLinkVar(ASC_DVC_VAR *);
1918 static int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1919 static int AscIsrChipHalted(ASC_DVC_VAR *);
1920 static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1921 ASC_QDONE_INFO *, ASC_DCNT);
1922 static int AscIsrQDone(ASC_DVC_VAR *);
1923 static int AscCompareString(uchar *, uchar *, int);
1924 #ifdef CONFIG_ISA
1925 static ushort AscGetEisaChipCfg(PortAddr);
1926 #endif /* CONFIG_ISA */
1927 static uchar AscGetChipScsiCtrl(PortAddr);
1928 static uchar AscSetChipScsiID(PortAddr, uchar);
1929 static uchar AscGetChipVersion(PortAddr, ushort);
1930 static ushort AscGetChipBusType(PortAddr);
1931 static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
1932 static int AscFindSignature(PortAddr);
1933 static void AscToggleIRQAct(PortAddr);
1934 static uchar AscGetChipIRQ(PortAddr, ushort);
1935 static uchar AscSetChipIRQ(PortAddr, uchar, ushort);
1936 static ushort AscGetChipBiosAddress(PortAddr, ushort);
1937 static inline ulong DvcEnterCritical(void);
1938 static inline void DvcLeaveCritical(ulong);
1939 #ifdef CONFIG_PCI
1940 static uchar DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort);
1941 static void DvcWritePCIConfigByte(ASC_DVC_VAR *, ushort, uchar);
1942 #endif /* CONFIG_PCI */
1943 static ushort AscGetChipBiosAddress(PortAddr, ushort);
1944 static void DvcSleepMilliSecond(ASC_DCNT);
1945 static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
1946 static void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1947 static void DvcGetQinfo(PortAddr, ushort, uchar *, int);
1948 static ushort AscInitGetConfig(ASC_DVC_VAR *);
1949 static ushort AscInitSetConfig(ASC_DVC_VAR *);
1950 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
1951 static void AscAsyncFix(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *);
1952 static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
1953 static void AscInquiryHandling(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *);
1954 static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
1955 static int AscISR(ASC_DVC_VAR *);
1956 static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar);
1957 static int AscSgListToQueue(int);
1958 #ifdef CONFIG_ISA
1959 static void AscEnableIsaDma(uchar);
1960 #endif /* CONFIG_ISA */
1961 static ASC_DCNT AscGetMaxDmaCount(ushort);
1962 static const char *advansys_info(struct Scsi_Host *shost);
1965 * --- Adv Library Constants and Macros
1968 #define ADV_LIB_VERSION_MAJOR 5
1969 #define ADV_LIB_VERSION_MINOR 14
1972 * Define Adv Library required special types.
1976 * Portable Data Types
1978 * Any instance where a 32-bit long or pointer type is assumed
1979 * for precision or HW defined structures, the following define
1980 * types must be used. In Linux the char, short, and int types
1981 * are all consistent at 8, 16, and 32 bits respectively. Pointers
1982 * and long types are 64 bits on Alpha and UltraSPARC.
1984 #define ADV_PADDR __u32 /* Physical address data type. */
1985 #define ADV_VADDR __u32 /* Virtual address data type. */
1986 #define ADV_DCNT __u32 /* Unsigned Data count type. */
1987 #define ADV_SDCNT __s32 /* Signed Data count type. */
1990 * These macros are used to convert a virtual address to a
1991 * 32-bit value. This currently can be used on Linux Alpha
1992 * which uses 64-bit virtual address but a 32-bit bus address.
1993 * This is likely to break in the future, but doing this now
1994 * will give us time to change the HW and FW to handle 64-bit
1995 * addresses.
1997 #define ADV_VADDR_TO_U32 virt_to_bus
1998 #define ADV_U32_TO_VADDR bus_to_virt
2000 #define AdvPortAddr void __iomem * /* Virtual memory address size */
2003 * Define Adv Library required memory access macros.
2005 #define ADV_MEM_READB(addr) readb(addr)
2006 #define ADV_MEM_READW(addr) readw(addr)
2007 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
2008 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
2009 #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
2011 #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
2014 * For wide boards a CDB length maximum of 16 bytes
2015 * is supported.
2017 #define ADV_MAX_CDB_LEN 16
2020 * Define total number of simultaneous maximum element scatter-gather
2021 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
2022 * maximum number of outstanding commands per wide host adapter. Each
2023 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
2024 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
2025 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
2026 * structures or 255 scatter-gather elements.
2029 #define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
2032 * Define Adv Library required maximum number of scatter-gather
2033 * elements per request.
2035 #define ADV_MAX_SG_LIST 255
2037 /* Number of SG blocks needed. */
2038 #define ADV_NUM_SG_BLOCK \
2039 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
2041 /* Total contiguous memory needed for SG blocks. */
2042 #define ADV_SG_TOTAL_MEM_SIZE \
2043 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
2045 #define ADV_PAGE_SIZE PAGE_SIZE
2047 #define ADV_NUM_PAGE_CROSSING \
2048 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2050 #define ADV_EEP_DVC_CFG_BEGIN (0x00)
2051 #define ADV_EEP_DVC_CFG_END (0x15)
2052 #define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
2053 #define ADV_EEP_MAX_WORD_ADDR (0x1E)
2055 #define ADV_EEP_DELAY_MS 100
2057 #define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
2058 #define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
2060 * For the ASC3550 Bit 13 is Termination Polarity control bit.
2061 * For later ICs Bit 13 controls whether the CIS (Card Information
2062 * Service Section) is loaded from EEPROM.
2064 #define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
2065 #define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
2067 * ASC38C1600 Bit 11
2069 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
2070 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
2071 * Function 0 will specify INT B.
2073 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
2074 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
2075 * Function 1 will specify INT A.
2077 #define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
2079 typedef struct adveep_3550_config {
2080 /* Word Offset, Description */
2082 ushort cfg_lsw; /* 00 power up initialization */
2083 /* bit 13 set - Term Polarity Control */
2084 /* bit 14 set - BIOS Enable */
2085 /* bit 15 set - Big Endian Mode */
2086 ushort cfg_msw; /* 01 unused */
2087 ushort disc_enable; /* 02 disconnect enable */
2088 ushort wdtr_able; /* 03 Wide DTR able */
2089 ushort sdtr_able; /* 04 Synchronous DTR able */
2090 ushort start_motor; /* 05 send start up motor */
2091 ushort tagqng_able; /* 06 tag queuing able */
2092 ushort bios_scan; /* 07 BIOS device control */
2093 ushort scam_tolerant; /* 08 no scam */
2095 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2096 uchar bios_boot_delay; /* power up wait */
2098 uchar scsi_reset_delay; /* 10 reset delay */
2099 uchar bios_id_lun; /* first boot device scsi id & lun */
2100 /* high nibble is lun */
2101 /* low nibble is scsi id */
2103 uchar termination; /* 11 0 - automatic */
2104 /* 1 - low off / high off */
2105 /* 2 - low off / high on */
2106 /* 3 - low on / high on */
2107 /* There is no low on / high off */
2109 uchar reserved1; /* reserved byte (not used) */
2111 ushort bios_ctrl; /* 12 BIOS control bits */
2112 /* bit 0 BIOS don't act as initiator. */
2113 /* bit 1 BIOS > 1 GB support */
2114 /* bit 2 BIOS > 2 Disk Support */
2115 /* bit 3 BIOS don't support removables */
2116 /* bit 4 BIOS support bootable CD */
2117 /* bit 5 BIOS scan enabled */
2118 /* bit 6 BIOS support multiple LUNs */
2119 /* bit 7 BIOS display of message */
2120 /* bit 8 SCAM disabled */
2121 /* bit 9 Reset SCSI bus during init. */
2122 /* bit 10 */
2123 /* bit 11 No verbose initialization. */
2124 /* bit 12 SCSI parity enabled */
2125 /* bit 13 */
2126 /* bit 14 */
2127 /* bit 15 */
2128 ushort ultra_able; /* 13 ULTRA speed able */
2129 ushort reserved2; /* 14 reserved */
2130 uchar max_host_qng; /* 15 maximum host queuing */
2131 uchar max_dvc_qng; /* maximum per device queuing */
2132 ushort dvc_cntl; /* 16 control bit for driver */
2133 ushort bug_fix; /* 17 control bit for bug fix */
2134 ushort serial_number_word1; /* 18 Board serial number word 1 */
2135 ushort serial_number_word2; /* 19 Board serial number word 2 */
2136 ushort serial_number_word3; /* 20 Board serial number word 3 */
2137 ushort check_sum; /* 21 EEP check sum */
2138 uchar oem_name[16]; /* 22 OEM name */
2139 ushort dvc_err_code; /* 30 last device driver error code */
2140 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2141 ushort adv_err_addr; /* 32 last uc error address */
2142 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2143 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2144 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2145 ushort num_of_err; /* 36 number of error */
2146 } ADVEEP_3550_CONFIG;
2148 typedef struct adveep_38C0800_config {
2149 /* Word Offset, Description */
2151 ushort cfg_lsw; /* 00 power up initialization */
2152 /* bit 13 set - Load CIS */
2153 /* bit 14 set - BIOS Enable */
2154 /* bit 15 set - Big Endian Mode */
2155 ushort cfg_msw; /* 01 unused */
2156 ushort disc_enable; /* 02 disconnect enable */
2157 ushort wdtr_able; /* 03 Wide DTR able */
2158 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2159 ushort start_motor; /* 05 send start up motor */
2160 ushort tagqng_able; /* 06 tag queuing able */
2161 ushort bios_scan; /* 07 BIOS device control */
2162 ushort scam_tolerant; /* 08 no scam */
2164 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2165 uchar bios_boot_delay; /* power up wait */
2167 uchar scsi_reset_delay; /* 10 reset delay */
2168 uchar bios_id_lun; /* first boot device scsi id & lun */
2169 /* high nibble is lun */
2170 /* low nibble is scsi id */
2172 uchar termination_se; /* 11 0 - automatic */
2173 /* 1 - low off / high off */
2174 /* 2 - low off / high on */
2175 /* 3 - low on / high on */
2176 /* There is no low on / high off */
2178 uchar termination_lvd; /* 11 0 - automatic */
2179 /* 1 - low off / high off */
2180 /* 2 - low off / high on */
2181 /* 3 - low on / high on */
2182 /* There is no low on / high off */
2184 ushort bios_ctrl; /* 12 BIOS control bits */
2185 /* bit 0 BIOS don't act as initiator. */
2186 /* bit 1 BIOS > 1 GB support */
2187 /* bit 2 BIOS > 2 Disk Support */
2188 /* bit 3 BIOS don't support removables */
2189 /* bit 4 BIOS support bootable CD */
2190 /* bit 5 BIOS scan enabled */
2191 /* bit 6 BIOS support multiple LUNs */
2192 /* bit 7 BIOS display of message */
2193 /* bit 8 SCAM disabled */
2194 /* bit 9 Reset SCSI bus during init. */
2195 /* bit 10 */
2196 /* bit 11 No verbose initialization. */
2197 /* bit 12 SCSI parity enabled */
2198 /* bit 13 */
2199 /* bit 14 */
2200 /* bit 15 */
2201 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2202 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2203 uchar max_host_qng; /* 15 maximum host queueing */
2204 uchar max_dvc_qng; /* maximum per device queuing */
2205 ushort dvc_cntl; /* 16 control bit for driver */
2206 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2207 ushort serial_number_word1; /* 18 Board serial number word 1 */
2208 ushort serial_number_word2; /* 19 Board serial number word 2 */
2209 ushort serial_number_word3; /* 20 Board serial number word 3 */
2210 ushort check_sum; /* 21 EEP check sum */
2211 uchar oem_name[16]; /* 22 OEM name */
2212 ushort dvc_err_code; /* 30 last device driver error code */
2213 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2214 ushort adv_err_addr; /* 32 last uc error address */
2215 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2216 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2217 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2218 ushort reserved36; /* 36 reserved */
2219 ushort reserved37; /* 37 reserved */
2220 ushort reserved38; /* 38 reserved */
2221 ushort reserved39; /* 39 reserved */
2222 ushort reserved40; /* 40 reserved */
2223 ushort reserved41; /* 41 reserved */
2224 ushort reserved42; /* 42 reserved */
2225 ushort reserved43; /* 43 reserved */
2226 ushort reserved44; /* 44 reserved */
2227 ushort reserved45; /* 45 reserved */
2228 ushort reserved46; /* 46 reserved */
2229 ushort reserved47; /* 47 reserved */
2230 ushort reserved48; /* 48 reserved */
2231 ushort reserved49; /* 49 reserved */
2232 ushort reserved50; /* 50 reserved */
2233 ushort reserved51; /* 51 reserved */
2234 ushort reserved52; /* 52 reserved */
2235 ushort reserved53; /* 53 reserved */
2236 ushort reserved54; /* 54 reserved */
2237 ushort reserved55; /* 55 reserved */
2238 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2239 ushort cisprt_msw; /* 57 CIS PTR MSW */
2240 ushort subsysvid; /* 58 SubSystem Vendor ID */
2241 ushort subsysid; /* 59 SubSystem ID */
2242 ushort reserved60; /* 60 reserved */
2243 ushort reserved61; /* 61 reserved */
2244 ushort reserved62; /* 62 reserved */
2245 ushort reserved63; /* 63 reserved */
2246 } ADVEEP_38C0800_CONFIG;
2248 typedef struct adveep_38C1600_config {
2249 /* Word Offset, Description */
2251 ushort cfg_lsw; /* 00 power up initialization */
2252 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
2253 /* clear - Func. 0 INTA, Func. 1 INTB */
2254 /* bit 13 set - Load CIS */
2255 /* bit 14 set - BIOS Enable */
2256 /* bit 15 set - Big Endian Mode */
2257 ushort cfg_msw; /* 01 unused */
2258 ushort disc_enable; /* 02 disconnect enable */
2259 ushort wdtr_able; /* 03 Wide DTR able */
2260 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2261 ushort start_motor; /* 05 send start up motor */
2262 ushort tagqng_able; /* 06 tag queuing able */
2263 ushort bios_scan; /* 07 BIOS device control */
2264 ushort scam_tolerant; /* 08 no scam */
2266 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2267 uchar bios_boot_delay; /* power up wait */
2269 uchar scsi_reset_delay; /* 10 reset delay */
2270 uchar bios_id_lun; /* first boot device scsi id & lun */
2271 /* high nibble is lun */
2272 /* low nibble is scsi id */
2274 uchar termination_se; /* 11 0 - automatic */
2275 /* 1 - low off / high off */
2276 /* 2 - low off / high on */
2277 /* 3 - low on / high on */
2278 /* There is no low on / high off */
2280 uchar termination_lvd; /* 11 0 - automatic */
2281 /* 1 - low off / high off */
2282 /* 2 - low off / high on */
2283 /* 3 - low on / high on */
2284 /* There is no low on / high off */
2286 ushort bios_ctrl; /* 12 BIOS control bits */
2287 /* bit 0 BIOS don't act as initiator. */
2288 /* bit 1 BIOS > 1 GB support */
2289 /* bit 2 BIOS > 2 Disk Support */
2290 /* bit 3 BIOS don't support removables */
2291 /* bit 4 BIOS support bootable CD */
2292 /* bit 5 BIOS scan enabled */
2293 /* bit 6 BIOS support multiple LUNs */
2294 /* bit 7 BIOS display of message */
2295 /* bit 8 SCAM disabled */
2296 /* bit 9 Reset SCSI bus during init. */
2297 /* bit 10 Basic Integrity Checking disabled */
2298 /* bit 11 No verbose initialization. */
2299 /* bit 12 SCSI parity enabled */
2300 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
2301 /* bit 14 */
2302 /* bit 15 */
2303 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2304 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2305 uchar max_host_qng; /* 15 maximum host queueing */
2306 uchar max_dvc_qng; /* maximum per device queuing */
2307 ushort dvc_cntl; /* 16 control bit for driver */
2308 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2309 ushort serial_number_word1; /* 18 Board serial number word 1 */
2310 ushort serial_number_word2; /* 19 Board serial number word 2 */
2311 ushort serial_number_word3; /* 20 Board serial number word 3 */
2312 ushort check_sum; /* 21 EEP check sum */
2313 uchar oem_name[16]; /* 22 OEM name */
2314 ushort dvc_err_code; /* 30 last device driver error code */
2315 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2316 ushort adv_err_addr; /* 32 last uc error address */
2317 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2318 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2319 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2320 ushort reserved36; /* 36 reserved */
2321 ushort reserved37; /* 37 reserved */
2322 ushort reserved38; /* 38 reserved */
2323 ushort reserved39; /* 39 reserved */
2324 ushort reserved40; /* 40 reserved */
2325 ushort reserved41; /* 41 reserved */
2326 ushort reserved42; /* 42 reserved */
2327 ushort reserved43; /* 43 reserved */
2328 ushort reserved44; /* 44 reserved */
2329 ushort reserved45; /* 45 reserved */
2330 ushort reserved46; /* 46 reserved */
2331 ushort reserved47; /* 47 reserved */
2332 ushort reserved48; /* 48 reserved */
2333 ushort reserved49; /* 49 reserved */
2334 ushort reserved50; /* 50 reserved */
2335 ushort reserved51; /* 51 reserved */
2336 ushort reserved52; /* 52 reserved */
2337 ushort reserved53; /* 53 reserved */
2338 ushort reserved54; /* 54 reserved */
2339 ushort reserved55; /* 55 reserved */
2340 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2341 ushort cisprt_msw; /* 57 CIS PTR MSW */
2342 ushort subsysvid; /* 58 SubSystem Vendor ID */
2343 ushort subsysid; /* 59 SubSystem ID */
2344 ushort reserved60; /* 60 reserved */
2345 ushort reserved61; /* 61 reserved */
2346 ushort reserved62; /* 62 reserved */
2347 ushort reserved63; /* 63 reserved */
2348 } ADVEEP_38C1600_CONFIG;
2351 * EEPROM Commands
2353 #define ASC_EEP_CMD_DONE 0x0200
2354 #define ASC_EEP_CMD_DONE_ERR 0x0001
2356 /* cfg_word */
2357 #define EEP_CFG_WORD_BIG_ENDIAN 0x8000
2359 /* bios_ctrl */
2360 #define BIOS_CTRL_BIOS 0x0001
2361 #define BIOS_CTRL_EXTENDED_XLAT 0x0002
2362 #define BIOS_CTRL_GT_2_DISK 0x0004
2363 #define BIOS_CTRL_BIOS_REMOVABLE 0x0008
2364 #define BIOS_CTRL_BOOTABLE_CD 0x0010
2365 #define BIOS_CTRL_MULTIPLE_LUN 0x0040
2366 #define BIOS_CTRL_DISPLAY_MSG 0x0080
2367 #define BIOS_CTRL_NO_SCAM 0x0100
2368 #define BIOS_CTRL_RESET_SCSI_BUS 0x0200
2369 #define BIOS_CTRL_INIT_VERBOSE 0x0800
2370 #define BIOS_CTRL_SCSI_PARITY 0x1000
2371 #define BIOS_CTRL_AIPP_DIS 0x2000
2373 #define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
2374 #define ADV_3550_IOLEN 0x40 /* I/O Port Range in bytes */
2376 #define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2377 #define ADV_38C0800_IOLEN 0x100 /* I/O Port Range in bytes */
2380 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
2381 * a special 16K Adv Library and Microcode version. After the issue is
2382 * resolved, should restore 32K support.
2384 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
2386 #define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2387 #define ADV_38C1600_IOLEN 0x100 /* I/O Port Range 256 bytes */
2388 #define ADV_38C1600_MEMLEN 0x1000 /* Memory Range 4KB bytes */
2391 * Byte I/O register address from base of 'iop_base'.
2393 #define IOPB_INTR_STATUS_REG 0x00
2394 #define IOPB_CHIP_ID_1 0x01
2395 #define IOPB_INTR_ENABLES 0x02
2396 #define IOPB_CHIP_TYPE_REV 0x03
2397 #define IOPB_RES_ADDR_4 0x04
2398 #define IOPB_RES_ADDR_5 0x05
2399 #define IOPB_RAM_DATA 0x06
2400 #define IOPB_RES_ADDR_7 0x07
2401 #define IOPB_FLAG_REG 0x08
2402 #define IOPB_RES_ADDR_9 0x09
2403 #define IOPB_RISC_CSR 0x0A
2404 #define IOPB_RES_ADDR_B 0x0B
2405 #define IOPB_RES_ADDR_C 0x0C
2406 #define IOPB_RES_ADDR_D 0x0D
2407 #define IOPB_SOFT_OVER_WR 0x0E
2408 #define IOPB_RES_ADDR_F 0x0F
2409 #define IOPB_MEM_CFG 0x10
2410 #define IOPB_RES_ADDR_11 0x11
2411 #define IOPB_GPIO_DATA 0x12
2412 #define IOPB_RES_ADDR_13 0x13
2413 #define IOPB_FLASH_PAGE 0x14
2414 #define IOPB_RES_ADDR_15 0x15
2415 #define IOPB_GPIO_CNTL 0x16
2416 #define IOPB_RES_ADDR_17 0x17
2417 #define IOPB_FLASH_DATA 0x18
2418 #define IOPB_RES_ADDR_19 0x19
2419 #define IOPB_RES_ADDR_1A 0x1A
2420 #define IOPB_RES_ADDR_1B 0x1B
2421 #define IOPB_RES_ADDR_1C 0x1C
2422 #define IOPB_RES_ADDR_1D 0x1D
2423 #define IOPB_RES_ADDR_1E 0x1E
2424 #define IOPB_RES_ADDR_1F 0x1F
2425 #define IOPB_DMA_CFG0 0x20
2426 #define IOPB_DMA_CFG1 0x21
2427 #define IOPB_TICKLE 0x22
2428 #define IOPB_DMA_REG_WR 0x23
2429 #define IOPB_SDMA_STATUS 0x24
2430 #define IOPB_SCSI_BYTE_CNT 0x25
2431 #define IOPB_HOST_BYTE_CNT 0x26
2432 #define IOPB_BYTE_LEFT_TO_XFER 0x27
2433 #define IOPB_BYTE_TO_XFER_0 0x28
2434 #define IOPB_BYTE_TO_XFER_1 0x29
2435 #define IOPB_BYTE_TO_XFER_2 0x2A
2436 #define IOPB_BYTE_TO_XFER_3 0x2B
2437 #define IOPB_ACC_GRP 0x2C
2438 #define IOPB_RES_ADDR_2D 0x2D
2439 #define IOPB_DEV_ID 0x2E
2440 #define IOPB_RES_ADDR_2F 0x2F
2441 #define IOPB_SCSI_DATA 0x30
2442 #define IOPB_RES_ADDR_31 0x31
2443 #define IOPB_RES_ADDR_32 0x32
2444 #define IOPB_SCSI_DATA_HSHK 0x33
2445 #define IOPB_SCSI_CTRL 0x34
2446 #define IOPB_RES_ADDR_35 0x35
2447 #define IOPB_RES_ADDR_36 0x36
2448 #define IOPB_RES_ADDR_37 0x37
2449 #define IOPB_RAM_BIST 0x38
2450 #define IOPB_PLL_TEST 0x39
2451 #define IOPB_PCI_INT_CFG 0x3A
2452 #define IOPB_RES_ADDR_3B 0x3B
2453 #define IOPB_RFIFO_CNT 0x3C
2454 #define IOPB_RES_ADDR_3D 0x3D
2455 #define IOPB_RES_ADDR_3E 0x3E
2456 #define IOPB_RES_ADDR_3F 0x3F
2459 * Word I/O register address from base of 'iop_base'.
2461 #define IOPW_CHIP_ID_0 0x00 /* CID0 */
2462 #define IOPW_CTRL_REG 0x02 /* CC */
2463 #define IOPW_RAM_ADDR 0x04 /* LA */
2464 #define IOPW_RAM_DATA 0x06 /* LD */
2465 #define IOPW_RES_ADDR_08 0x08
2466 #define IOPW_RISC_CSR 0x0A /* CSR */
2467 #define IOPW_SCSI_CFG0 0x0C /* CFG0 */
2468 #define IOPW_SCSI_CFG1 0x0E /* CFG1 */
2469 #define IOPW_RES_ADDR_10 0x10
2470 #define IOPW_SEL_MASK 0x12 /* SM */
2471 #define IOPW_RES_ADDR_14 0x14
2472 #define IOPW_FLASH_ADDR 0x16 /* FA */
2473 #define IOPW_RES_ADDR_18 0x18
2474 #define IOPW_EE_CMD 0x1A /* EC */
2475 #define IOPW_EE_DATA 0x1C /* ED */
2476 #define IOPW_SFIFO_CNT 0x1E /* SFC */
2477 #define IOPW_RES_ADDR_20 0x20
2478 #define IOPW_Q_BASE 0x22 /* QB */
2479 #define IOPW_QP 0x24 /* QP */
2480 #define IOPW_IX 0x26 /* IX */
2481 #define IOPW_SP 0x28 /* SP */
2482 #define IOPW_PC 0x2A /* PC */
2483 #define IOPW_RES_ADDR_2C 0x2C
2484 #define IOPW_RES_ADDR_2E 0x2E
2485 #define IOPW_SCSI_DATA 0x30 /* SD */
2486 #define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
2487 #define IOPW_SCSI_CTRL 0x34 /* SC */
2488 #define IOPW_HSHK_CFG 0x36 /* HCFG */
2489 #define IOPW_SXFR_STATUS 0x36 /* SXS */
2490 #define IOPW_SXFR_CNTL 0x38 /* SXL */
2491 #define IOPW_SXFR_CNTH 0x3A /* SXH */
2492 #define IOPW_RES_ADDR_3C 0x3C
2493 #define IOPW_RFIFO_DATA 0x3E /* RFD */
2496 * Doubleword I/O register address from base of 'iop_base'.
2498 #define IOPDW_RES_ADDR_0 0x00
2499 #define IOPDW_RAM_DATA 0x04
2500 #define IOPDW_RES_ADDR_8 0x08
2501 #define IOPDW_RES_ADDR_C 0x0C
2502 #define IOPDW_RES_ADDR_10 0x10
2503 #define IOPDW_COMMA 0x14
2504 #define IOPDW_COMMB 0x18
2505 #define IOPDW_RES_ADDR_1C 0x1C
2506 #define IOPDW_SDMA_ADDR0 0x20
2507 #define IOPDW_SDMA_ADDR1 0x24
2508 #define IOPDW_SDMA_COUNT 0x28
2509 #define IOPDW_SDMA_ERROR 0x2C
2510 #define IOPDW_RDMA_ADDR0 0x30
2511 #define IOPDW_RDMA_ADDR1 0x34
2512 #define IOPDW_RDMA_COUNT 0x38
2513 #define IOPDW_RDMA_ERROR 0x3C
2515 #define ADV_CHIP_ID_BYTE 0x25
2516 #define ADV_CHIP_ID_WORD 0x04C1
2518 #define ADV_SC_SCSI_BUS_RESET 0x2000
2520 #define ADV_INTR_ENABLE_HOST_INTR 0x01
2521 #define ADV_INTR_ENABLE_SEL_INTR 0x02
2522 #define ADV_INTR_ENABLE_DPR_INTR 0x04
2523 #define ADV_INTR_ENABLE_RTA_INTR 0x08
2524 #define ADV_INTR_ENABLE_RMA_INTR 0x10
2525 #define ADV_INTR_ENABLE_RST_INTR 0x20
2526 #define ADV_INTR_ENABLE_DPE_INTR 0x40
2527 #define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
2529 #define ADV_INTR_STATUS_INTRA 0x01
2530 #define ADV_INTR_STATUS_INTRB 0x02
2531 #define ADV_INTR_STATUS_INTRC 0x04
2533 #define ADV_RISC_CSR_STOP (0x0000)
2534 #define ADV_RISC_TEST_COND (0x2000)
2535 #define ADV_RISC_CSR_RUN (0x4000)
2536 #define ADV_RISC_CSR_SINGLE_STEP (0x8000)
2538 #define ADV_CTRL_REG_HOST_INTR 0x0100
2539 #define ADV_CTRL_REG_SEL_INTR 0x0200
2540 #define ADV_CTRL_REG_DPR_INTR 0x0400
2541 #define ADV_CTRL_REG_RTA_INTR 0x0800
2542 #define ADV_CTRL_REG_RMA_INTR 0x1000
2543 #define ADV_CTRL_REG_RES_BIT14 0x2000
2544 #define ADV_CTRL_REG_DPE_INTR 0x4000
2545 #define ADV_CTRL_REG_POWER_DONE 0x8000
2546 #define ADV_CTRL_REG_ANY_INTR 0xFF00
2548 #define ADV_CTRL_REG_CMD_RESET 0x00C6
2549 #define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
2550 #define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
2551 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
2552 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
2554 #define ADV_TICKLE_NOP 0x00
2555 #define ADV_TICKLE_A 0x01
2556 #define ADV_TICKLE_B 0x02
2557 #define ADV_TICKLE_C 0x03
2559 #define ADV_SCSI_CTRL_RSTOUT 0x2000
2561 #define AdvIsIntPending(port) \
2562 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2565 * SCSI_CFG0 Register bit definitions
2567 #define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
2568 #define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
2569 #define EVEN_PARITY 0x1000 /* Select Even Parity */
2570 #define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2571 #define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
2572 #define PRIM_MODE 0x0100 /* Primitive SCSI mode */
2573 #define SCAM_EN 0x0080 /* Enable SCAM selection */
2574 #define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2575 #define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2576 #define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
2577 #define OUR_ID 0x000F /* SCSI ID */
2580 * SCSI_CFG1 Register bit definitions
2582 #define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
2583 #define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2584 #define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
2585 #define FILTER_SEL 0x0C00 /* Filter Period Selection */
2586 #define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
2587 #define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
2588 #define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
2589 #define ACTIVE_DBL 0x0200 /* Disable Active Negation */
2590 #define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
2591 #define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
2592 #define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
2593 #define TERM_CTL 0x0030 /* External SCSI Termination Bits */
2594 #define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
2595 #define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
2596 #define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
2599 * Addendum for ASC-38C0800 Chip
2601 * The ASC-38C1600 Chip uses the same definitions except that the
2602 * bus mode override bits [12:10] have been moved to byte register
2603 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
2604 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
2605 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
2606 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
2607 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
2609 #define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
2610 #define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
2611 #define HVD 0x1000 /* HVD Device Detect */
2612 #define LVD 0x0800 /* LVD Device Detect */
2613 #define SE 0x0400 /* SE Device Detect */
2614 #define TERM_LVD 0x00C0 /* LVD Termination Bits */
2615 #define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
2616 #define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
2617 #define TERM_SE 0x0030 /* SE Termination Bits */
2618 #define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
2619 #define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
2620 #define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
2621 #define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
2622 #define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
2623 #define C_DET_SE 0x0003 /* SE Cable Detect Bits */
2624 #define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
2625 #define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
2627 #define CABLE_ILLEGAL_A 0x7
2628 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
2630 #define CABLE_ILLEGAL_B 0xB
2631 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
2634 * MEM_CFG Register bit definitions
2636 #define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
2637 #define FAST_EE_CLK 0x20 /* Diagnostic Bit */
2638 #define RAM_SZ 0x1C /* Specify size of RAM to RISC */
2639 #define RAM_SZ_2KB 0x00 /* 2 KB */
2640 #define RAM_SZ_4KB 0x04 /* 4 KB */
2641 #define RAM_SZ_8KB 0x08 /* 8 KB */
2642 #define RAM_SZ_16KB 0x0C /* 16 KB */
2643 #define RAM_SZ_32KB 0x10 /* 32 KB */
2644 #define RAM_SZ_64KB 0x14 /* 64 KB */
2647 * DMA_CFG0 Register bit definitions
2649 * This register is only accessible to the host.
2651 #define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
2652 #define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
2653 #define FIFO_THRESH_16B 0x00 /* 16 bytes */
2654 #define FIFO_THRESH_32B 0x20 /* 32 bytes */
2655 #define FIFO_THRESH_48B 0x30 /* 48 bytes */
2656 #define FIFO_THRESH_64B 0x40 /* 64 bytes */
2657 #define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
2658 #define FIFO_THRESH_96B 0x60 /* 96 bytes */
2659 #define FIFO_THRESH_112B 0x70 /* 112 bytes */
2660 #define START_CTL 0x0C /* DMA start conditions */
2661 #define START_CTL_TH 0x00 /* Wait threshold level (default) */
2662 #define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
2663 #define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
2664 #define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
2665 #define READ_CMD 0x03 /* Memory Read Method */
2666 #define READ_CMD_MR 0x00 /* Memory Read */
2667 #define READ_CMD_MRL 0x02 /* Memory Read Long */
2668 #define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
2671 * ASC-38C0800 RAM BIST Register bit definitions
2673 #define RAM_TEST_MODE 0x80
2674 #define PRE_TEST_MODE 0x40
2675 #define NORMAL_MODE 0x00
2676 #define RAM_TEST_DONE 0x10
2677 #define RAM_TEST_STATUS 0x0F
2678 #define RAM_TEST_HOST_ERROR 0x08
2679 #define RAM_TEST_INTRAM_ERROR 0x04
2680 #define RAM_TEST_RISC_ERROR 0x02
2681 #define RAM_TEST_SCSI_ERROR 0x01
2682 #define RAM_TEST_SUCCESS 0x00
2683 #define PRE_TEST_VALUE 0x05
2684 #define NORMAL_VALUE 0x00
2687 * ASC38C1600 Definitions
2689 * IOPB_PCI_INT_CFG Bit Field Definitions
2692 #define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
2695 * Bit 1 can be set to change the interrupt for the Function to operate in
2696 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
2697 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
2698 * mode, otherwise the operating mode is undefined.
2700 #define TOTEMPOLE 0x02
2703 * Bit 0 can be used to change the Int Pin for the Function. The value is
2704 * 0 by default for both Functions with Function 0 using INT A and Function
2705 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
2706 * INT A is used.
2708 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
2709 * value specified in the PCI Configuration Space.
2711 #define INTAB 0x01
2713 /* a_advlib.h */
2716 * Adv Library Status Definitions
2718 #define ADV_TRUE 1
2719 #define ADV_FALSE 0
2720 #define ADV_NOERROR 1
2721 #define ADV_SUCCESS 1
2722 #define ADV_BUSY 0
2723 #define ADV_ERROR (-1)
2726 * ADV_DVC_VAR 'warn_code' values
2728 #define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
2729 #define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
2730 #define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
2731 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */
2732 #define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
2734 #define ADV_MAX_TID 15 /* max. target identifier */
2735 #define ADV_MAX_LUN 7 /* max. logical unit number */
2738 * Error code values are set in ADV_DVC_VAR 'err_code'.
2740 #define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */
2741 #define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
2742 #define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */
2743 #define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
2744 #define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */
2745 #define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
2746 #define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */
2747 #define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
2748 #define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
2749 #define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */
2750 #define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */
2751 #define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */
2752 #define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */
2753 #define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */
2756 * Fixed locations of microcode operating variables.
2758 #define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
2759 #define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
2760 #define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
2761 #define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
2762 #define ASC_MC_VERSION_NUM 0x003A /* microcode number */
2763 #define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
2764 #define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
2765 #define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
2766 #define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
2767 #define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
2768 #define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
2769 #define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
2770 #define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
2771 #define ASC_MC_CHIP_TYPE 0x009A
2772 #define ASC_MC_INTRB_CODE 0x009B
2773 #define ASC_MC_WDTR_ABLE 0x009C
2774 #define ASC_MC_SDTR_ABLE 0x009E
2775 #define ASC_MC_TAGQNG_ABLE 0x00A0
2776 #define ASC_MC_DISC_ENABLE 0x00A2
2777 #define ASC_MC_IDLE_CMD_STATUS 0x00A4
2778 #define ASC_MC_IDLE_CMD 0x00A6
2779 #define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
2780 #define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
2781 #define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
2782 #define ASC_MC_DEFAULT_MEM_CFG 0x00B0
2783 #define ASC_MC_DEFAULT_SEL_MASK 0x00B2
2784 #define ASC_MC_SDTR_DONE 0x00B6
2785 #define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
2786 #define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
2787 #define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
2788 #define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
2789 #define ASC_MC_WDTR_DONE 0x0124
2790 #define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
2791 #define ASC_MC_ICQ 0x0160
2792 #define ASC_MC_IRQ 0x0164
2793 #define ASC_MC_PPR_ABLE 0x017A
2796 * BIOS LRAM variable absolute offsets.
2798 #define BIOS_CODESEG 0x54
2799 #define BIOS_CODELEN 0x56
2800 #define BIOS_SIGNATURE 0x58
2801 #define BIOS_VERSION 0x5A
2804 * Microcode Control Flags
2806 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2807 * and handled by the microcode.
2809 #define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
2810 #define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
2813 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2815 #define HSHK_CFG_WIDE_XFR 0x8000
2816 #define HSHK_CFG_RATE 0x0F00
2817 #define HSHK_CFG_OFFSET 0x001F
2819 #define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
2820 #define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
2821 #define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
2822 #define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
2824 #define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2825 #define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
2826 #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2827 #define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
2828 #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2830 #define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
2831 #define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
2832 #define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
2833 #define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
2834 #define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
2836 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
2837 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
2839 #define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
2840 #define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
2843 * All fields here are accessed by the board microcode and need to be
2844 * little-endian.
2846 typedef struct adv_carr_t {
2847 ADV_VADDR carr_va; /* Carrier Virtual Address */
2848 ADV_PADDR carr_pa; /* Carrier Physical Address */
2849 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
2851 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
2853 * next_vpa [3:1] Reserved Bits
2854 * next_vpa [0] Done Flag set in Response Queue.
2856 ADV_VADDR next_vpa;
2857 } ADV_CARR_T;
2860 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2862 #define ASC_NEXT_VPA_MASK 0xFFFFFFF0
2864 #define ASC_RQ_DONE 0x00000001
2865 #define ASC_RQ_GOOD 0x00000002
2866 #define ASC_CQ_STOPPER 0x00000000
2868 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2870 #define ADV_CARRIER_NUM_PAGE_CROSSING \
2871 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2872 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2874 #define ADV_CARRIER_BUFSIZE \
2875 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2878 * ASC_SCSI_REQ_Q 'a_flag' definitions
2880 * The Adv Library should limit use to the lower nibble (4 bits) of
2881 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2883 #define ADV_POLL_REQUEST 0x01 /* poll for request completion */
2884 #define ADV_SCSIQ_DONE 0x02 /* request done */
2885 #define ADV_DONT_RETRY 0x08 /* don't do retry */
2887 #define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
2888 #define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
2889 #define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
2892 * Adapter temporary configuration structure
2894 * This structure can be discarded after initialization. Don't add
2895 * fields here needed after initialization.
2897 * Field naming convention:
2899 * *_enable indicates the field enables or disables a feature. The
2900 * value of the field is never reset.
2902 typedef struct adv_dvc_cfg {
2903 ushort disc_enable; /* enable disconnection */
2904 uchar chip_version; /* chip version */
2905 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2906 ushort lib_version; /* Adv Library version number */
2907 ushort control_flag; /* Microcode Control Flag */
2908 ushort mcode_date; /* Microcode date */
2909 ushort mcode_version; /* Microcode version */
2910 ushort pci_slot_info; /* high byte device/function number */
2911 /* bits 7-3 device num., bits 2-0 function num. */
2912 /* low byte bus num. */
2913 ushort serial1; /* EEPROM serial number word 1 */
2914 ushort serial2; /* EEPROM serial number word 2 */
2915 ushort serial3; /* EEPROM serial number word 3 */
2916 struct device *dev; /* pointer to the pci dev structure for this board */
2917 } ADV_DVC_CFG;
2919 struct adv_dvc_var;
2920 struct adv_scsi_req_q;
2922 typedef void (*ADV_ISR_CALLBACK)
2923 (struct adv_dvc_var *, struct adv_scsi_req_q *);
2925 typedef void (*ADV_ASYNC_CALLBACK)
2926 (struct adv_dvc_var *, uchar);
2929 * Adapter operation variable structure.
2931 * One structure is required per host adapter.
2933 * Field naming convention:
2935 * *_able indicates both whether a feature should be enabled or disabled
2936 * and whether a device isi capable of the feature. At initialization
2937 * this field may be set, but later if a device is found to be incapable
2938 * of the feature, the field is cleared.
2940 typedef struct adv_dvc_var {
2941 AdvPortAddr iop_base; /* I/O port address */
2942 ushort err_code; /* fatal error code */
2943 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
2944 ADV_ISR_CALLBACK isr_callback;
2945 ADV_ASYNC_CALLBACK async_callback;
2946 ushort wdtr_able; /* try WDTR for a device */
2947 ushort sdtr_able; /* try SDTR for a device */
2948 ushort ultra_able; /* try SDTR Ultra speed for a device */
2949 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
2950 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
2951 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
2952 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
2953 ushort tagqng_able; /* try tagged queuing with a device */
2954 ushort ppr_able; /* PPR message capable per TID bitmask. */
2955 uchar max_dvc_qng; /* maximum number of tagged commands per device */
2956 ushort start_motor; /* start motor command allowed */
2957 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
2958 uchar chip_no; /* should be assigned by caller */
2959 uchar max_host_qng; /* maximum number of Q'ed command allowed */
2960 uchar irq_no; /* IRQ number */
2961 ushort no_scam; /* scam_tolerant of EEPROM */
2962 struct asc_board *drv_ptr; /* driver pointer to private structure */
2963 uchar chip_scsi_id; /* chip SCSI target ID */
2964 uchar chip_type;
2965 uchar bist_err_code;
2966 ADV_CARR_T *carrier_buf;
2967 ADV_CARR_T *carr_freelist; /* Carrier free list. */
2968 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
2969 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
2970 ushort carr_pending_cnt; /* Count of pending carriers. */
2972 * Note: The following fields will not be used after initialization. The
2973 * driver may discard the buffer after initialization is done.
2975 ADV_DVC_CFG *cfg; /* temporary configuration structure */
2976 } ADV_DVC_VAR;
2978 #define NO_OF_SG_PER_BLOCK 15
2980 typedef struct asc_sg_block {
2981 uchar reserved1;
2982 uchar reserved2;
2983 uchar reserved3;
2984 uchar sg_cnt; /* Valid entries in block. */
2985 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
2986 struct {
2987 ADV_PADDR sg_addr; /* SG element address. */
2988 ADV_DCNT sg_count; /* SG element count. */
2989 } sg_list[NO_OF_SG_PER_BLOCK];
2990 } ADV_SG_BLOCK;
2993 * ADV_SCSI_REQ_Q - microcode request structure
2995 * All fields in this structure up to byte 60 are used by the microcode.
2996 * The microcode makes assumptions about the size and ordering of fields
2997 * in this structure. Do not change the structure definition here without
2998 * coordinating the change with the microcode.
3000 * All fields accessed by microcode must be maintained in little_endian
3001 * order.
3003 typedef struct adv_scsi_req_q {
3004 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
3005 uchar target_cmd;
3006 uchar target_id; /* Device target identifier. */
3007 uchar target_lun; /* Device target logical unit number. */
3008 ADV_PADDR data_addr; /* Data buffer physical address. */
3009 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
3010 ADV_PADDR sense_addr;
3011 ADV_PADDR carr_pa;
3012 uchar mflag;
3013 uchar sense_len;
3014 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
3015 uchar scsi_cntl;
3016 uchar done_status; /* Completion status. */
3017 uchar scsi_status; /* SCSI status byte. */
3018 uchar host_status; /* Ucode host status. */
3019 uchar sg_working_ix;
3020 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
3021 ADV_PADDR sg_real_addr; /* SG list physical address. */
3022 ADV_PADDR scsiq_rptr;
3023 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
3024 ADV_VADDR scsiq_ptr;
3025 ADV_VADDR carr_va;
3027 * End of microcode structure - 60 bytes. The rest of the structure
3028 * is used by the Adv Library and ignored by the microcode.
3030 ADV_VADDR srb_ptr;
3031 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
3032 char *vdata_addr; /* Data buffer virtual address. */
3033 uchar a_flag;
3034 uchar pad[2]; /* Pad out to a word boundary. */
3035 } ADV_SCSI_REQ_Q;
3038 * Microcode idle loop commands
3040 #define IDLE_CMD_COMPLETED 0
3041 #define IDLE_CMD_STOP_CHIP 0x0001
3042 #define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
3043 #define IDLE_CMD_SEND_INT 0x0004
3044 #define IDLE_CMD_ABORT 0x0008
3045 #define IDLE_CMD_DEVICE_RESET 0x0010
3046 #define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
3047 #define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
3048 #define IDLE_CMD_SCSIREQ 0x0080
3050 #define IDLE_CMD_STATUS_SUCCESS 0x0001
3051 #define IDLE_CMD_STATUS_FAILURE 0x0002
3054 * AdvSendIdleCmd() flag definitions.
3056 #define ADV_NOWAIT 0x01
3059 * Wait loop time out values.
3061 #define SCSI_WAIT_10_SEC 10UL /* 10 seconds */
3062 #define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
3063 #define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
3064 #define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */
3065 #define SCSI_MAX_RETRY 10 /* retry count */
3067 #define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
3068 #define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
3069 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
3070 #define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
3072 #define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
3075 * Device drivers must define the following functions.
3077 static inline ulong DvcEnterCritical(void);
3078 static inline void DvcLeaveCritical(ulong);
3079 static void DvcSleepMilliSecond(ADV_DCNT);
3080 static uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
3081 static void DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
3082 static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
3083 uchar *, ASC_SDCNT *, int);
3084 static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
3087 * Adv Library functions available to drivers.
3089 static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3090 static int AdvISR(ADV_DVC_VAR *);
3091 static int AdvInitGetConfig(ADV_DVC_VAR *);
3092 static int AdvInitAsc3550Driver(ADV_DVC_VAR *);
3093 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
3094 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
3095 static int AdvResetChipAndSB(ADV_DVC_VAR *);
3096 static int AdvResetSB(ADV_DVC_VAR *asc_dvc);
3099 * Internal Adv Library functions.
3101 static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
3102 static void AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3103 static int AdvInitFrom3550EEP(ADV_DVC_VAR *);
3104 static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
3105 static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
3106 static ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3107 static void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3108 static ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3109 static void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3110 static ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3111 static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3112 static void AdvWaitEEPCmd(AdvPortAddr);
3113 static ushort AdvReadEEPWord(AdvPortAddr, int);
3116 * PCI Bus Definitions
3118 #define AscPCICmdRegBits_BusMastering 0x0007
3119 #define AscPCICmdRegBits_ParErrRespCtrl 0x0040
3121 /* Read byte from a register. */
3122 #define AdvReadByteRegister(iop_base, reg_off) \
3123 (ADV_MEM_READB((iop_base) + (reg_off)))
3125 /* Write byte to a register. */
3126 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
3127 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3129 /* Read word (2 bytes) from a register. */
3130 #define AdvReadWordRegister(iop_base, reg_off) \
3131 (ADV_MEM_READW((iop_base) + (reg_off)))
3133 /* Write word (2 bytes) to a register. */
3134 #define AdvWriteWordRegister(iop_base, reg_off, word) \
3135 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
3137 /* Write dword (4 bytes) to a register. */
3138 #define AdvWriteDWordRegister(iop_base, reg_off, dword) \
3139 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
3141 /* Read byte from LRAM. */
3142 #define AdvReadByteLram(iop_base, addr, byte) \
3143 do { \
3144 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3145 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3146 } while (0)
3148 /* Write byte to LRAM. */
3149 #define AdvWriteByteLram(iop_base, addr, byte) \
3150 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3151 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3153 /* Read word (2 bytes) from LRAM. */
3154 #define AdvReadWordLram(iop_base, addr, word) \
3155 do { \
3156 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3157 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3158 } while (0)
3160 /* Write word (2 bytes) to LRAM. */
3161 #define AdvWriteWordLram(iop_base, addr, word) \
3162 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3163 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3165 /* Write little-endian double word (4 bytes) to LRAM */
3166 /* Because of unspecified C language ordering don't use auto-increment. */
3167 #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
3168 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3169 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3170 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3171 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3172 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3173 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3175 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
3176 #define AdvReadWordAutoIncLram(iop_base) \
3177 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3179 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
3180 #define AdvWriteWordAutoIncLram(iop_base, word) \
3181 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3184 * Define macro to check for Condor signature.
3186 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3187 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3189 #define AdvFindSignature(iop_base) \
3190 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3191 ADV_CHIP_ID_BYTE) && \
3192 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3193 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
3196 * Define macro to Return the version number of the chip at 'iop_base'.
3198 * The second parameter 'bus_type' is currently unused.
3200 #define AdvGetChipVersion(iop_base, bus_type) \
3201 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3204 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3205 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3207 * If the request has not yet been sent to the device it will simply be
3208 * aborted from RISC memory. If the request is disconnected it will be
3209 * aborted on reselection by sending an Abort Message to the target ID.
3211 * Return value:
3212 * ADV_TRUE(1) - Queue was successfully aborted.
3213 * ADV_FALSE(0) - Queue was not found on the active queue list.
3215 #define AdvAbortQueue(asc_dvc, scsiq) \
3216 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3217 (ADV_DCNT) (scsiq))
3220 * Send a Bus Device Reset Message to the specified target ID.
3222 * All outstanding commands will be purged if sending the
3223 * Bus Device Reset Message is successful.
3225 * Return Value:
3226 * ADV_TRUE(1) - All requests on the target are purged.
3227 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3228 * are not purged.
3230 #define AdvResetDevice(asc_dvc, target_id) \
3231 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3232 (ADV_DCNT) (target_id))
3235 * SCSI Wide Type definition.
3237 #define ADV_SCSI_BIT_ID_TYPE ushort
3240 * AdvInitScsiTarget() 'cntl_flag' options.
3242 #define ADV_SCAN_LUN 0x01
3243 #define ADV_CAPINFO_NOLUN 0x02
3246 * Convert target id to target id bit mask.
3248 #define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
3251 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3254 #define QD_NO_STATUS 0x00 /* Request not completed yet. */
3255 #define QD_NO_ERROR 0x01
3256 #define QD_ABORTED_BY_HOST 0x02
3257 #define QD_WITH_ERROR 0x04
3259 #define QHSTA_NO_ERROR 0x00
3260 #define QHSTA_M_SEL_TIMEOUT 0x11
3261 #define QHSTA_M_DATA_OVER_RUN 0x12
3262 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3263 #define QHSTA_M_QUEUE_ABORTED 0x15
3264 #define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
3265 #define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
3266 #define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
3267 #define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
3268 #define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
3269 #define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
3270 #define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
3271 /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
3272 #define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
3273 #define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
3274 #define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
3275 #define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
3276 #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
3277 #define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
3278 #define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
3279 #define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
3280 #define QHSTA_M_WTM_TIMEOUT 0x41
3281 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
3282 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
3283 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
3284 #define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
3285 #define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
3286 #define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
3289 * Default EEPROM Configuration structure defined in a_init.c.
3291 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
3292 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
3293 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
3296 * DvcGetPhyAddr() flag arguments
3298 #define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
3299 #define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
3300 #define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
3301 #define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
3302 #define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
3303 #define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
3305 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
3306 #define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
3307 #define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
3308 #define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
3311 * Total contiguous memory needed for driver SG blocks.
3313 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3314 * number of scatter-gather elements the driver supports in a
3315 * single request.
3318 #define ADV_SG_LIST_MAX_BYTE_SIZE \
3319 (sizeof(ADV_SG_BLOCK) * \
3320 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3323 * Inquiry data structure and bitfield macros
3325 * Using bitfields to access the subchar data isn't portable across
3326 * endianness, so instead mask and shift. Only quantities of more
3327 * than 1 bit are shifted, since the others are just tested for true
3328 * or false.
3331 #define ADV_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f)
3332 #define ADV_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5)
3333 #define ADV_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f)
3334 #define ADV_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80)
3335 #define ADV_INQ_ANSI_VER(inq) ((inq)->ver & 0x07)
3336 #define ADV_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3)
3337 #define ADV_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6)
3338 #define ADV_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f)
3339 #define ADV_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40)
3340 #define ADV_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80)
3341 #define ADV_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01)
3342 #define ADV_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02)
3343 #define ADV_INQ_LINK_CMD(inq) ((inq)->flags & 0x08)
3344 #define ADV_INQ_SYNC(inq) ((inq)->flags & 0x10)
3345 #define ADV_INQ_WIDE16(inq) ((inq)->flags & 0x20)
3346 #define ADV_INQ_WIDE32(inq) ((inq)->flags & 0x40)
3347 #define ADV_INQ_REL_ADDR(inq) ((inq)->flags & 0x80)
3348 #define ADV_INQ_INFO_UNIT(inq) ((inq)->info & 0x01)
3349 #define ADV_INQ_QUICK_ARB(inq) ((inq)->info & 0x02)
3350 #define ADV_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2)
3352 typedef struct {
3353 uchar periph; /* peripheral device type [0:4] */
3354 /* peripheral qualifier [5:7] */
3355 uchar devtype; /* device type modifier (for SCSI I) [0:6] */
3356 /* RMB - removable medium bit [7] */
3357 uchar ver; /* ANSI approved version [0:2] */
3358 /* ECMA version [3:5] */
3359 /* ISO version [6:7] */
3360 uchar byte3; /* response data format [0:3] */
3361 /* 0 SCSI 1 */
3362 /* 1 CCS */
3363 /* 2 SCSI-2 */
3364 /* 3-F reserved */
3365 /* reserved [4:5] */
3366 /* terminate I/O process bit (see 5.6.22) [6] */
3367 /* asynch. event notification (processor) [7] */
3368 uchar add_len; /* additional length */
3369 uchar res1; /* reserved */
3370 uchar res2; /* reserved */
3371 uchar flags; /* soft reset implemented [0] */
3372 /* command queuing [1] */
3373 /* reserved [2] */
3374 /* linked command for this logical unit [3] */
3375 /* synchronous data transfer [4] */
3376 /* wide bus 16 bit data transfer [5] */
3377 /* wide bus 32 bit data transfer [6] */
3378 /* relative addressing mode [7] */
3379 uchar vendor_id[8]; /* vendor identification */
3380 uchar product_id[16]; /* product identification */
3381 uchar product_rev_level[4]; /* product revision level */
3382 uchar vendor_specific[20]; /* vendor specific */
3383 uchar info; /* information unit supported [0] */
3384 /* quick arbitrate supported [1] */
3385 /* clocking field [2:3] */
3386 /* reserved [4:7] */
3387 uchar res3; /* reserved */
3388 } ADV_SCSI_INQUIRY; /* 58 bytes */
3391 * --- Driver Constants and Macros
3394 /* Reference Scsi_Host hostdata */
3395 #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3397 /* asc_board_t flags */
3398 #define ASC_HOST_IN_RESET 0x01
3399 #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
3400 #define ASC_SELECT_QUEUE_DEPTHS 0x08
3402 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3403 #define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD)
3405 #define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
3407 #define ASC_INFO_SIZE 128 /* advansys_info() line size */
3409 #ifdef CONFIG_PROC_FS
3410 /* /proc/scsi/advansys/[0...] related definitions */
3411 #define ASC_PRTBUF_SIZE 2048
3412 #define ASC_PRTLINE_SIZE 160
3414 #define ASC_PRT_NEXT() \
3415 if (cp) { \
3416 totlen += len; \
3417 leftlen -= len; \
3418 if (leftlen == 0) { \
3419 return totlen; \
3421 cp += len; \
3423 #endif /* CONFIG_PROC_FS */
3425 /* Asc Library return codes */
3426 #define ASC_TRUE 1
3427 #define ASC_FALSE 0
3428 #define ASC_NOERROR 1
3429 #define ASC_BUSY 0
3430 #define ASC_ERROR (-1)
3432 /* struct scsi_cmnd function return codes */
3433 #define STATUS_BYTE(byte) (byte)
3434 #define MSG_BYTE(byte) ((byte) << 8)
3435 #define HOST_BYTE(byte) ((byte) << 16)
3436 #define DRIVER_BYTE(byte) ((byte) << 24)
3439 * The following definitions and macros are OS independent interfaces to
3440 * the queue functions:
3441 * REQ - SCSI request structure
3442 * REQP - pointer to SCSI request structure
3443 * REQPTID(reqp) - reqp's target id
3444 * REQPNEXT(reqp) - reqp's next pointer
3445 * REQPNEXTP(reqp) - pointer to reqp's next pointer
3446 * REQPTIME(reqp) - reqp's time stamp value
3447 * REQTIMESTAMP() - system time stamp value
3449 typedef struct scsi_cmnd REQ, *REQP;
3450 #define REQPNEXT(reqp) ((REQP) ((reqp)->host_scribble))
3451 #define REQPNEXTP(reqp) ((REQP *) &((reqp)->host_scribble))
3452 #define REQPTID(reqp) ((reqp)->device->id)
3453 #define REQPTIME(reqp) ((reqp)->SCp.this_residual)
3454 #define REQTIMESTAMP() (jiffies)
3456 #define REQTIMESTAT(function, ascq, reqp, tid) \
3459 * If the request time stamp is less than the system time stamp, then \
3460 * maybe the system time stamp wrapped. Set the request time to zero.\
3461 */ \
3462 if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3463 REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3464 } else { \
3465 /* Indicate an error occurred with the assertion. */ \
3466 ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3467 REQPTIME(reqp) = 0; \
3469 /* Handle first minimum time case without external initialization. */ \
3470 if (((ascq)->q_tot_cnt[tid] == 1) || \
3471 (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3472 (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3473 ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3474 (function), (tid), (ascq)->q_min_tim[tid]); \
3476 if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3477 (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3478 ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3479 (function), tid, (ascq)->q_max_tim[tid]); \
3481 (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3482 /* Reset the time stamp field. */ \
3483 REQPTIME(reqp) = 0; \
3486 /* asc_enqueue() flags */
3487 #define ASC_FRONT 1
3488 #define ASC_BACK 2
3490 /* asc_dequeue_list() argument */
3491 #define ASC_TID_ALL (-1)
3493 /* Return non-zero, if the queue is empty. */
3494 #define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0)
3496 #ifndef ADVANSYS_STATS
3497 #define ASC_STATS(shost, counter)
3498 #define ASC_STATS_ADD(shost, counter, count)
3499 #else /* ADVANSYS_STATS */
3500 #define ASC_STATS(shost, counter) \
3501 (ASC_BOARDP(shost)->asc_stats.counter++)
3503 #define ASC_STATS_ADD(shost, counter, count) \
3504 (ASC_BOARDP(shost)->asc_stats.counter += (count))
3505 #endif /* ADVANSYS_STATS */
3507 #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3509 /* If the result wraps when calculating tenths, return 0. */
3510 #define ASC_TENTHS(num, den) \
3511 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3512 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3515 * Display a message to the console.
3517 #define ASC_PRINT(s) \
3519 printk("advansys: "); \
3520 printk(s); \
3523 #define ASC_PRINT1(s, a1) \
3525 printk("advansys: "); \
3526 printk((s), (a1)); \
3529 #define ASC_PRINT2(s, a1, a2) \
3531 printk("advansys: "); \
3532 printk((s), (a1), (a2)); \
3535 #define ASC_PRINT3(s, a1, a2, a3) \
3537 printk("advansys: "); \
3538 printk((s), (a1), (a2), (a3)); \
3541 #define ASC_PRINT4(s, a1, a2, a3, a4) \
3543 printk("advansys: "); \
3544 printk((s), (a1), (a2), (a3), (a4)); \
3547 #ifndef ADVANSYS_DEBUG
3549 #define ASC_DBG(lvl, s)
3550 #define ASC_DBG1(lvl, s, a1)
3551 #define ASC_DBG2(lvl, s, a1, a2)
3552 #define ASC_DBG3(lvl, s, a1, a2, a3)
3553 #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3554 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3555 #define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3556 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3557 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3558 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3559 #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3560 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
3561 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
3562 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
3563 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3565 #else /* ADVANSYS_DEBUG */
3568 * Debugging Message Levels:
3569 * 0: Errors Only
3570 * 1: High-Level Tracing
3571 * 2-N: Verbose Tracing
3574 #define ASC_DBG(lvl, s) \
3576 if (asc_dbglvl >= (lvl)) { \
3577 printk(s); \
3581 #define ASC_DBG1(lvl, s, a1) \
3583 if (asc_dbglvl >= (lvl)) { \
3584 printk((s), (a1)); \
3588 #define ASC_DBG2(lvl, s, a1, a2) \
3590 if (asc_dbglvl >= (lvl)) { \
3591 printk((s), (a1), (a2)); \
3595 #define ASC_DBG3(lvl, s, a1, a2, a3) \
3597 if (asc_dbglvl >= (lvl)) { \
3598 printk((s), (a1), (a2), (a3)); \
3602 #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3604 if (asc_dbglvl >= (lvl)) { \
3605 printk((s), (a1), (a2), (a3), (a4)); \
3609 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3611 if (asc_dbglvl >= (lvl)) { \
3612 asc_prt_scsi_host(s); \
3616 #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3618 if (asc_dbglvl >= (lvl)) { \
3619 asc_prt_scsi_cmnd(s); \
3623 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3625 if (asc_dbglvl >= (lvl)) { \
3626 asc_prt_asc_scsi_q(scsiqp); \
3630 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3632 if (asc_dbglvl >= (lvl)) { \
3633 asc_prt_asc_qdone_info(qdone); \
3637 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3639 if (asc_dbglvl >= (lvl)) { \
3640 asc_prt_adv_scsi_req_q(scsiqp); \
3644 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3646 if (asc_dbglvl >= (lvl)) { \
3647 asc_prt_hex((name), (start), (length)); \
3651 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3652 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3654 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3655 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3657 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3658 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3659 #endif /* ADVANSYS_DEBUG */
3661 #ifndef ADVANSYS_ASSERT
3662 #define ASC_ASSERT(a)
3663 #else /* ADVANSYS_ASSERT */
3665 #define ASC_ASSERT(a) \
3667 if (!(a)) { \
3668 printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3669 __FILE__, __LINE__); \
3673 #endif /* ADVANSYS_ASSERT */
3676 * --- Driver Structures
3679 #ifdef ADVANSYS_STATS
3681 /* Per board statistics structure */
3682 struct asc_stats {
3683 /* Driver Entrypoint Statistics */
3684 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
3685 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
3686 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
3687 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
3688 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
3689 ADV_DCNT done; /* # calls to request's scsi_done function */
3690 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
3691 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
3692 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
3693 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3694 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
3695 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
3696 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
3697 ADV_DCNT exe_unknown; /* # unknown returns. */
3698 /* Data Transfer Statistics */
3699 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
3700 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
3701 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
3702 ADV_DCNT sg_elem; /* # scatter-gather elements */
3703 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
3705 #endif /* ADVANSYS_STATS */
3708 * Request queuing structure
3710 typedef struct asc_queue {
3711 ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */
3712 REQP q_first[ADV_MAX_TID + 1]; /* first queued request */
3713 REQP q_last[ADV_MAX_TID + 1]; /* last queued request */
3714 #ifdef ADVANSYS_STATS
3715 short q_cur_cnt[ADV_MAX_TID + 1]; /* current queue count */
3716 short q_max_cnt[ADV_MAX_TID + 1]; /* maximum queue count */
3717 ADV_DCNT q_tot_cnt[ADV_MAX_TID + 1]; /* total enqueue count */
3718 ADV_DCNT q_tot_tim[ADV_MAX_TID + 1]; /* total time queued */
3719 ushort q_max_tim[ADV_MAX_TID + 1]; /* maximum time queued */
3720 ushort q_min_tim[ADV_MAX_TID + 1]; /* minimum time queued */
3721 #endif /* ADVANSYS_STATS */
3722 } asc_queue_t;
3725 * Adv Library Request Structures
3727 * The following two structures are used to process Wide Board requests.
3729 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
3730 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
3731 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
3732 * Mid-Level SCSI request structure.
3734 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
3735 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
3736 * up to 255 scatter-gather elements may be used per request or
3737 * ADV_SCSI_REQ_Q.
3739 * Both structures must be 32 byte aligned.
3741 typedef struct adv_sgblk {
3742 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
3743 uchar align[32]; /* Sgblock structure padding. */
3744 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
3745 } adv_sgblk_t;
3747 typedef struct adv_req {
3748 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
3749 uchar align[32]; /* Request structure padding. */
3750 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
3751 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
3752 struct adv_req *next_reqp; /* Next Request Structure. */
3753 } adv_req_t;
3756 * Structure allocated for each board.
3758 * This structure is allocated by scsi_host_alloc() at the end
3759 * of the 'Scsi_Host' structure starting at the 'hostdata'
3760 * field. It is guaranteed to be allocated from DMA-able memory.
3762 typedef struct asc_board {
3763 int id; /* Board Id */
3764 uint flags; /* Board flags */
3765 union {
3766 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
3767 ADV_DVC_VAR adv_dvc_var; /* Wide board */
3768 } dvc_var;
3769 union {
3770 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
3771 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
3772 } dvc_cfg;
3773 ushort asc_n_io_port; /* Number I/O ports. */
3774 asc_queue_t active; /* Active command queue */
3775 asc_queue_t waiting; /* Waiting command queue */
3776 asc_queue_t done; /* Done command queue */
3777 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
3778 struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */
3779 ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
3780 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
3781 ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */
3782 union {
3783 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
3784 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
3785 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
3786 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
3787 } eep_config;
3788 ulong last_reset; /* Saved last reset time */
3789 spinlock_t lock; /* Board spinlock */
3790 /* /proc/scsi/advansys/[0...] */
3791 char *prtbuf; /* /proc print buffer */
3792 #ifdef ADVANSYS_STATS
3793 struct asc_stats asc_stats; /* Board statistics */
3794 #endif /* ADVANSYS_STATS */
3796 * The following fields are used only for Narrow Boards.
3798 /* The following three structures must be in DMA-able memory. */
3799 ASC_SCSI_REQ_Q scsireqq;
3800 ASC_CAP_INFO cap_info;
3801 ASC_SCSI_INQUIRY inquiry;
3802 uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */
3804 * The following fields are used only for Wide Boards.
3806 void __iomem *ioremap_addr; /* I/O Memory remap address. */
3807 ushort ioport; /* I/O Port address. */
3808 ADV_CARR_T *carrp; /* ADV_CARR_T memory block. */
3809 adv_req_t *orig_reqp; /* adv_req_t memory block. */
3810 adv_req_t *adv_reqp; /* Request structures. */
3811 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
3812 ushort bios_signature; /* BIOS Signature. */
3813 ushort bios_version; /* BIOS Version. */
3814 ushort bios_codeseg; /* BIOS Code Segment. */
3815 ushort bios_codelen; /* BIOS Code Segment Length. */
3816 } asc_board_t;
3818 /* Number of boards detected in system. */
3819 static int asc_board_count;
3821 /* Overrun buffer used by all narrow boards. */
3822 static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
3825 * Global structures required to issue a command.
3827 static ASC_SCSI_Q asc_scsi_q = { {0} };
3828 static ASC_SG_HEAD asc_sg_head = { 0 };
3830 #ifdef ADVANSYS_DEBUG
3831 static int asc_dbglvl = 3;
3832 #endif /* ADVANSYS_DEBUG */
3835 * --- Driver Function Prototypes
3837 * advansys.h contains function prototypes for functions global to Linux.
3840 static int advansys_slave_configure(struct scsi_device *);
3841 static void asc_scsi_done_list(struct scsi_cmnd *);
3842 static int asc_execute_scsi_cmnd(struct scsi_cmnd *);
3843 static int asc_build_req(asc_board_t *, struct scsi_cmnd *);
3844 static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
3845 static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
3846 static void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
3847 static void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3848 static void adv_async_callback(ADV_DVC_VAR *, uchar);
3849 static void asc_enqueue(asc_queue_t *, REQP, int);
3850 static REQP asc_dequeue(asc_queue_t *, int);
3851 static REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
3852 static int asc_rmqueue(asc_queue_t *, REQP);
3853 static void asc_execute_queue(asc_queue_t *);
3854 #ifdef CONFIG_PROC_FS
3855 static int asc_proc_copy(off_t, off_t, char *, int, char *, int);
3856 static int asc_prt_board_devices(struct Scsi_Host *, char *, int);
3857 static int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
3858 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
3859 static int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
3860 static int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
3861 static int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
3862 static int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
3863 static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
3864 static int asc_prt_line(char *, int, char *fmt, ...);
3865 #endif /* CONFIG_PROC_FS */
3867 /* Declaration for Asc Library internal functions referenced by driver. */
3868 static int AscFindSignature(PortAddr);
3869 static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
3871 /* Statistics function prototypes. */
3872 #ifdef ADVANSYS_STATS
3873 #ifdef CONFIG_PROC_FS
3874 static int asc_prt_board_stats(struct Scsi_Host *, char *, int);
3875 static int asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
3876 #endif /* CONFIG_PROC_FS */
3877 #endif /* ADVANSYS_STATS */
3879 /* Debug function prototypes. */
3880 #ifdef ADVANSYS_DEBUG
3881 static void asc_prt_scsi_host(struct Scsi_Host *);
3882 static void asc_prt_scsi_cmnd(struct scsi_cmnd *);
3883 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
3884 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
3885 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
3886 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
3887 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
3888 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
3889 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
3890 static void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
3891 static void asc_prt_hex(char *f, uchar *, int);
3892 #endif /* ADVANSYS_DEBUG */
3894 #ifdef CONFIG_PROC_FS
3896 * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...}
3898 * *buffer: I/O buffer
3899 * **start: if inout == FALSE pointer into buffer where user read should start
3900 * offset: current offset into a /proc/scsi/advansys/[0...] file
3901 * length: length of buffer
3902 * hostno: Scsi_Host host_no
3903 * inout: TRUE - user is writing; FALSE - user is reading
3905 * Return the number of bytes read from or written to a
3906 * /proc/scsi/advansys/[0...] file.
3908 * Note: This function uses the per board buffer 'prtbuf' which is
3909 * allocated when the board is initialized in advansys_detect(). The
3910 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
3911 * used to write to the buffer. The way asc_proc_copy() is written
3912 * if 'prtbuf' is too small it will not be overwritten. Instead the
3913 * user just won't get all the available statistics.
3915 static int
3916 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
3917 off_t offset, int length, int inout)
3919 asc_board_t *boardp;
3920 char *cp;
3921 int cplen;
3922 int cnt;
3923 int totcnt;
3924 int leftlen;
3925 char *curbuf;
3926 off_t advoffset;
3927 #ifdef ADVANSYS_STATS
3928 int tgt_id;
3929 #endif /* ADVANSYS_STATS */
3931 ASC_DBG(1, "advansys_proc_info: begin\n");
3934 * User write not supported.
3936 if (inout == TRUE) {
3937 return (-ENOSYS);
3941 * User read of /proc/scsi/advansys/[0...] file.
3944 boardp = ASC_BOARDP(shost);
3946 /* Copy read data starting at the beginning of the buffer. */
3947 *start = buffer;
3948 curbuf = buffer;
3949 advoffset = 0;
3950 totcnt = 0;
3951 leftlen = length;
3954 * Get board configuration information.
3956 * advansys_info() returns the board string from its own static buffer.
3958 cp = (char *)advansys_info(shost);
3959 strcat(cp, "\n");
3960 cplen = strlen(cp);
3961 /* Copy board information. */
3962 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3963 totcnt += cnt;
3964 leftlen -= cnt;
3965 if (leftlen == 0) {
3966 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3967 return totcnt;
3969 advoffset += cplen;
3970 curbuf += cnt;
3973 * Display Wide Board BIOS Information.
3975 if (ASC_WIDE_BOARD(boardp)) {
3976 cp = boardp->prtbuf;
3977 cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE);
3978 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3979 cnt =
3980 asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
3981 cplen);
3982 totcnt += cnt;
3983 leftlen -= cnt;
3984 if (leftlen == 0) {
3985 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
3986 return totcnt;
3988 advoffset += cplen;
3989 curbuf += cnt;
3993 * Display driver information for each device attached to the board.
3995 cp = boardp->prtbuf;
3996 cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE);
3997 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
3998 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
3999 totcnt += cnt;
4000 leftlen -= cnt;
4001 if (leftlen == 0) {
4002 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4003 return totcnt;
4005 advoffset += cplen;
4006 curbuf += cnt;
4009 * Display EEPROM configuration for the board.
4011 cp = boardp->prtbuf;
4012 if (ASC_NARROW_BOARD(boardp)) {
4013 cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
4014 } else {
4015 cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE);
4017 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4018 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4019 totcnt += cnt;
4020 leftlen -= cnt;
4021 if (leftlen == 0) {
4022 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4023 return totcnt;
4025 advoffset += cplen;
4026 curbuf += cnt;
4029 * Display driver configuration and information for the board.
4031 cp = boardp->prtbuf;
4032 cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE);
4033 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4034 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4035 totcnt += cnt;
4036 leftlen -= cnt;
4037 if (leftlen == 0) {
4038 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4039 return totcnt;
4041 advoffset += cplen;
4042 curbuf += cnt;
4044 #ifdef ADVANSYS_STATS
4046 * Display driver statistics for the board.
4048 cp = boardp->prtbuf;
4049 cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE);
4050 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4051 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4052 totcnt += cnt;
4053 leftlen -= cnt;
4054 if (leftlen == 0) {
4055 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4056 return totcnt;
4058 advoffset += cplen;
4059 curbuf += cnt;
4062 * Display driver statistics for each target.
4064 for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
4065 cp = boardp->prtbuf;
4066 cplen = asc_prt_target_stats(shost, tgt_id, cp,
4067 ASC_PRTBUF_SIZE);
4068 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4069 cnt =
4070 asc_proc_copy(advoffset, offset, curbuf, leftlen, cp,
4071 cplen);
4072 totcnt += cnt;
4073 leftlen -= cnt;
4074 if (leftlen == 0) {
4075 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4076 return totcnt;
4078 advoffset += cplen;
4079 curbuf += cnt;
4081 #endif /* ADVANSYS_STATS */
4084 * Display Asc Library dynamic configuration information
4085 * for the board.
4087 cp = boardp->prtbuf;
4088 if (ASC_NARROW_BOARD(boardp)) {
4089 cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE);
4090 } else {
4091 cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE);
4093 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4094 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4095 totcnt += cnt;
4096 leftlen -= cnt;
4097 if (leftlen == 0) {
4098 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4099 return totcnt;
4101 advoffset += cplen;
4102 curbuf += cnt;
4104 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4106 return totcnt;
4108 #endif /* CONFIG_PROC_FS */
4111 * advansys_info()
4113 * Return suitable for printing on the console with the argument
4114 * adapter's configuration information.
4116 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
4117 * otherwise the static 'info' array will be overrun.
4119 static const char *advansys_info(struct Scsi_Host *shost)
4121 static char info[ASC_INFO_SIZE];
4122 asc_board_t *boardp;
4123 ASC_DVC_VAR *asc_dvc_varp;
4124 ADV_DVC_VAR *adv_dvc_varp;
4125 char *busname;
4126 int iolen;
4127 char *widename = NULL;
4129 boardp = ASC_BOARDP(shost);
4130 if (ASC_NARROW_BOARD(boardp)) {
4131 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4132 ASC_DBG(1, "advansys_info: begin\n");
4133 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
4134 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) ==
4135 ASC_IS_ISAPNP) {
4136 busname = "ISA PnP";
4137 } else {
4138 busname = "ISA";
4140 /* Don't reference 'shost->n_io_port'; It may be truncated. */
4141 sprintf(info,
4142 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
4143 ASC_VERSION, busname,
4144 (ulong)shost->io_port,
4145 (ulong)shost->io_port + boardp->asc_n_io_port -
4146 1, shost->irq, shost->dma_channel);
4147 } else {
4148 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
4149 busname = "VL";
4150 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
4151 busname = "EISA";
4152 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
4153 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
4154 == ASC_IS_PCI_ULTRA) {
4155 busname = "PCI Ultra";
4156 } else {
4157 busname = "PCI";
4159 } else {
4160 busname = "?";
4161 ASC_PRINT2
4162 ("advansys_info: board %d: unknown bus type %d\n",
4163 boardp->id, asc_dvc_varp->bus_type);
4165 /* Don't reference 'shost->n_io_port'; It may be truncated. */
4166 sprintf(info,
4167 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
4168 ASC_VERSION, busname,
4169 (ulong)shost->io_port,
4170 (ulong)shost->io_port + boardp->asc_n_io_port -
4171 1, shost->irq);
4173 } else {
4175 * Wide Adapter Information
4177 * Memory-mapped I/O is used instead of I/O space to access
4178 * the adapter, but display the I/O Port range. The Memory
4179 * I/O address is displayed through the driver /proc file.
4181 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4182 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
4183 iolen = ADV_3550_IOLEN;
4184 widename = "Ultra-Wide";
4185 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
4186 iolen = ADV_38C0800_IOLEN;
4187 widename = "Ultra2-Wide";
4188 } else {
4189 iolen = ADV_38C1600_IOLEN;
4190 widename = "Ultra3-Wide";
4192 sprintf(info,
4193 "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
4194 ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base,
4195 (ulong)adv_dvc_varp->iop_base + iolen - 1, shost->irq);
4197 ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
4198 ASC_DBG(1, "advansys_info: end\n");
4199 return info;
4203 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
4205 * This function always returns 0. Command return status is saved
4206 * in the 'scp' result field.
4208 static int
4209 advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *))
4211 struct Scsi_Host *shost;
4212 asc_board_t *boardp;
4213 ulong flags;
4214 struct scsi_cmnd *done_scp;
4216 shost = scp->device->host;
4217 boardp = ASC_BOARDP(shost);
4218 ASC_STATS(shost, queuecommand);
4220 /* host_lock taken by mid-level prior to call but need to protect */
4221 /* against own ISR */
4222 spin_lock_irqsave(&boardp->lock, flags);
4225 * Block new commands while handling a reset or abort request.
4227 if (boardp->flags & ASC_HOST_IN_RESET) {
4228 ASC_DBG1(1,
4229 "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
4230 (ulong)scp);
4231 scp->result = HOST_BYTE(DID_RESET);
4234 * Add blocked requests to the board's 'done' queue. The queued
4235 * requests will be completed at the end of the abort or reset
4236 * handling.
4238 asc_enqueue(&boardp->done, scp, ASC_BACK);
4239 spin_unlock_irqrestore(&boardp->lock, flags);
4240 return 0;
4244 * Attempt to execute any waiting commands for the board.
4246 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4247 ASC_DBG(1,
4248 "advansys_queuecommand: before asc_execute_queue() waiting\n");
4249 asc_execute_queue(&boardp->waiting);
4253 * Save the function pointer to Linux mid-level 'done' function
4254 * and attempt to execute the command.
4256 * If ASC_NOERROR is returned the request has been added to the
4257 * board's 'active' queue and will be completed by the interrupt
4258 * handler.
4260 * If ASC_BUSY is returned add the request to the board's per
4261 * target waiting list. This is the first time the request has
4262 * been tried. Add it to the back of the waiting list. It will be
4263 * retried later.
4265 * If an error occurred, the request will have been placed on the
4266 * board's 'done' queue and must be completed before returning.
4268 scp->scsi_done = done;
4269 switch (asc_execute_scsi_cmnd(scp)) {
4270 case ASC_NOERROR:
4271 break;
4272 case ASC_BUSY:
4273 asc_enqueue(&boardp->waiting, scp, ASC_BACK);
4274 break;
4275 case ASC_ERROR:
4276 default:
4277 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
4278 /* Interrupts could be enabled here. */
4279 asc_scsi_done_list(done_scp);
4280 break;
4282 spin_unlock_irqrestore(&boardp->lock, flags);
4284 return 0;
4288 * advansys_reset()
4290 * Reset the bus associated with the command 'scp'.
4292 * This function runs its own thread. Interrupts must be blocked but
4293 * sleeping is allowed and no locking other than for host structures is
4294 * required. Returns SUCCESS or FAILED.
4296 static int advansys_reset(struct scsi_cmnd *scp)
4298 struct Scsi_Host *shost;
4299 asc_board_t *boardp;
4300 ASC_DVC_VAR *asc_dvc_varp;
4301 ADV_DVC_VAR *adv_dvc_varp;
4302 ulong flags;
4303 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4304 struct scsi_cmnd *tscp, *new_last_scp;
4305 int status;
4306 int ret = SUCCESS;
4308 ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp);
4310 #ifdef ADVANSYS_STATS
4311 if (scp->device->host != NULL) {
4312 ASC_STATS(scp->device->host, reset);
4314 #endif /* ADVANSYS_STATS */
4316 if ((shost = scp->device->host) == NULL) {
4317 scp->result = HOST_BYTE(DID_ERROR);
4318 return FAILED;
4321 boardp = ASC_BOARDP(shost);
4323 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
4324 boardp->id);
4326 * Check for re-entrancy.
4328 spin_lock_irqsave(&boardp->lock, flags);
4329 if (boardp->flags & ASC_HOST_IN_RESET) {
4330 spin_unlock_irqrestore(&boardp->lock, flags);
4331 return FAILED;
4333 boardp->flags |= ASC_HOST_IN_RESET;
4334 spin_unlock_irqrestore(&boardp->lock, flags);
4336 if (ASC_NARROW_BOARD(boardp)) {
4338 * Narrow Board
4340 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4343 * Reset the chip and SCSI bus.
4345 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
4346 status = AscInitAsc1000Driver(asc_dvc_varp);
4348 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
4349 if (asc_dvc_varp->err_code) {
4350 ASC_PRINT2
4351 ("advansys_reset: board %d: SCSI bus reset error: 0x%x\n",
4352 boardp->id, asc_dvc_varp->err_code);
4353 ret = FAILED;
4354 } else if (status) {
4355 ASC_PRINT2
4356 ("advansys_reset: board %d: SCSI bus reset warning: 0x%x\n",
4357 boardp->id, status);
4358 } else {
4359 ASC_PRINT1
4360 ("advansys_reset: board %d: SCSI bus reset successful.\n",
4361 boardp->id);
4364 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
4365 spin_lock_irqsave(&boardp->lock, flags);
4367 } else {
4369 * Wide Board
4371 * If the suggest reset bus flags are set, then reset the bus.
4372 * Otherwise only reset the device.
4374 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4377 * Reset the target's SCSI bus.
4379 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
4380 switch (AdvResetChipAndSB(adv_dvc_varp)) {
4381 case ASC_TRUE:
4382 ASC_PRINT1
4383 ("advansys_reset: board %d: SCSI bus reset successful.\n",
4384 boardp->id);
4385 break;
4386 case ASC_FALSE:
4387 default:
4388 ASC_PRINT1
4389 ("advansys_reset: board %d: SCSI bus reset error.\n",
4390 boardp->id);
4391 ret = FAILED;
4392 break;
4394 spin_lock_irqsave(&boardp->lock, flags);
4395 (void)AdvISR(adv_dvc_varp);
4397 /* Board lock is held. */
4400 * Dequeue all board 'done' requests. A pointer to the last request
4401 * is returned in 'last_scp'.
4403 done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
4406 * Dequeue all board 'active' requests for all devices and set
4407 * the request status to DID_RESET. A pointer to the last request
4408 * is returned in 'last_scp'.
4410 if (done_scp == NULL) {
4411 done_scp =
4412 asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL);
4413 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4414 tscp->result = HOST_BYTE(DID_RESET);
4416 } else {
4417 /* Append to 'done_scp' at the end with 'last_scp'. */
4418 ASC_ASSERT(last_scp != NULL);
4419 last_scp->host_scribble =
4420 (unsigned char *)asc_dequeue_list(&boardp->active,
4421 &new_last_scp,
4422 ASC_TID_ALL);
4423 if (new_last_scp != NULL) {
4424 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4425 for (tscp = REQPNEXT(last_scp); tscp;
4426 tscp = REQPNEXT(tscp)) {
4427 tscp->result = HOST_BYTE(DID_RESET);
4429 last_scp = new_last_scp;
4434 * Dequeue all 'waiting' requests and set the request status
4435 * to DID_RESET.
4437 if (done_scp == NULL) {
4438 done_scp =
4439 asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL);
4440 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
4441 tscp->result = HOST_BYTE(DID_RESET);
4443 } else {
4444 /* Append to 'done_scp' at the end with 'last_scp'. */
4445 ASC_ASSERT(last_scp != NULL);
4446 last_scp->host_scribble =
4447 (unsigned char *)asc_dequeue_list(&boardp->waiting,
4448 &new_last_scp,
4449 ASC_TID_ALL);
4450 if (new_last_scp != NULL) {
4451 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4452 for (tscp = REQPNEXT(last_scp); tscp;
4453 tscp = REQPNEXT(tscp)) {
4454 tscp->result = HOST_BYTE(DID_RESET);
4456 last_scp = new_last_scp;
4460 /* Save the time of the most recently completed reset. */
4461 boardp->last_reset = jiffies;
4463 /* Clear reset flag. */
4464 boardp->flags &= ~ASC_HOST_IN_RESET;
4465 spin_unlock_irqrestore(&boardp->lock, flags);
4468 * Complete all the 'done_scp' requests.
4470 if (done_scp != NULL) {
4471 asc_scsi_done_list(done_scp);
4474 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
4476 return ret;
4480 * advansys_biosparam()
4482 * Translate disk drive geometry if the "BIOS greater than 1 GB"
4483 * support is enabled for a drive.
4485 * ip (information pointer) is an int array with the following definition:
4486 * ip[0]: heads
4487 * ip[1]: sectors
4488 * ip[2]: cylinders
4490 static int
4491 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
4492 sector_t capacity, int ip[])
4494 asc_board_t *boardp;
4496 ASC_DBG(1, "advansys_biosparam: begin\n");
4497 ASC_STATS(sdev->host, biosparam);
4498 boardp = ASC_BOARDP(sdev->host);
4499 if (ASC_NARROW_BOARD(boardp)) {
4500 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
4501 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
4502 ip[0] = 255;
4503 ip[1] = 63;
4504 } else {
4505 ip[0] = 64;
4506 ip[1] = 32;
4508 } else {
4509 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
4510 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
4511 ip[0] = 255;
4512 ip[1] = 63;
4513 } else {
4514 ip[0] = 64;
4515 ip[1] = 32;
4518 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
4519 ASC_DBG(1, "advansys_biosparam: end\n");
4520 return 0;
4523 static struct scsi_host_template advansys_template = {
4524 .proc_name = "advansys",
4525 #ifdef CONFIG_PROC_FS
4526 .proc_info = advansys_proc_info,
4527 #endif
4528 .name = "advansys",
4529 .info = advansys_info,
4530 .queuecommand = advansys_queuecommand,
4531 .eh_bus_reset_handler = advansys_reset,
4532 .bios_param = advansys_biosparam,
4533 .slave_configure = advansys_slave_configure,
4535 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
4536 * must be set. The flag will be cleared in advansys_board_found
4537 * for non-ISA adapters.
4539 .unchecked_isa_dma = 1,
4541 * All adapters controlled by this driver are capable of large
4542 * scatter-gather lists. According to the mid-level SCSI documentation
4543 * this obviates any performance gain provided by setting
4544 * 'use_clustering'. But empirically while CPU utilization is increased
4545 * by enabling clustering, I/O throughput increases as well.
4547 .use_clustering = ENABLE_CLUSTERING,
4551 * --- Miscellaneous Driver Functions
4555 * First-level interrupt handler.
4557 * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
4558 * all boards are currently checked for interrupts on each interrupt, 'dev_id'
4559 * is not referenced. 'dev_id' could be used to identify an interrupt passed
4560 * to the AdvanSys driver which is for a device sharing an interrupt with
4561 * an AdvanSys adapter.
4563 static irqreturn_t advansys_interrupt(int irq, void *dev_id)
4565 unsigned long flags;
4566 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
4567 struct scsi_cmnd *new_last_scp;
4568 struct Scsi_Host *shost = dev_id;
4569 asc_board_t *boardp = ASC_BOARDP(shost);
4570 irqreturn_t result = IRQ_NONE;
4572 ASC_DBG1(2, "advansys_interrupt: boardp 0x%p\n", boardp);
4573 spin_lock_irqsave(&boardp->lock, flags);
4574 if (ASC_NARROW_BOARD(boardp)) {
4576 * Narrow Board
4578 if (AscIsIntPending(shost->io_port)) {
4579 result = IRQ_HANDLED;
4580 ASC_STATS(shost, interrupt);
4581 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
4582 AscISR(&boardp->dvc_var.asc_dvc_var);
4584 } else {
4586 * Wide Board
4588 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
4589 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
4590 result = IRQ_HANDLED;
4591 ASC_STATS(shost, interrupt);
4596 * Start waiting requests and create a list of completed requests.
4598 * If a reset request is being performed for the board, the reset
4599 * handler will complete pending requests after it has completed.
4601 if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
4602 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%p, "
4603 "last_scp 0x%p\n", done_scp, last_scp);
4605 /* Start any waiting commands for the board. */
4606 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
4607 ASC_DBG(1, "advansys_interrupt: before "
4608 "asc_execute_queue()\n");
4609 asc_execute_queue(&boardp->waiting);
4613 * Add to the list of requests that must be completed.
4615 * 'done_scp' will always be NULL on the first iteration of
4616 * this loop. 'last_scp' is set at the same time as 'done_scp'.
4618 if (done_scp == NULL) {
4619 done_scp = asc_dequeue_list(&boardp->done,
4620 &last_scp, ASC_TID_ALL);
4621 } else {
4622 ASC_ASSERT(last_scp != NULL);
4623 last_scp->host_scribble =
4624 (unsigned char *)asc_dequeue_list(&boardp->
4625 done,
4626 &new_last_scp,
4627 ASC_TID_ALL);
4628 if (new_last_scp != NULL) {
4629 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
4630 last_scp = new_last_scp;
4634 spin_unlock_irqrestore(&boardp->lock, flags);
4637 * If interrupts were enabled on entry, then they
4638 * are now enabled here.
4640 * Complete all requests on the done list.
4643 asc_scsi_done_list(done_scp);
4645 ASC_DBG(1, "advansys_interrupt: end\n");
4646 return result;
4650 * Set the number of commands to queue per device for the
4651 * specified host adapter.
4653 static int advansys_slave_configure(struct scsi_device *device)
4655 asc_board_t *boardp;
4657 boardp = ASC_BOARDP(device->host);
4658 boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
4660 * Save a pointer to the device and set its initial/maximum
4661 * queue depth. Only save the pointer for a lun0 dev though.
4663 if (device->lun == 0)
4664 boardp->device[device->id] = device;
4665 if (device->tagged_supported) {
4666 if (ASC_NARROW_BOARD(boardp)) {
4667 scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
4668 boardp->dvc_var.asc_dvc_var.
4669 max_dvc_qng[device->id]);
4670 } else {
4671 scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
4672 boardp->dvc_var.adv_dvc_var.
4673 max_dvc_qng);
4675 } else {
4676 scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun);
4678 ASC_DBG4(1,
4679 "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n",
4680 (ulong)device, (ulong)boardp, device->id, device->queue_depth);
4681 return 0;
4685 * Complete all requests on the singly linked list pointed
4686 * to by 'scp'.
4688 * Interrupts can be enabled on entry.
4690 static void asc_scsi_done_list(struct scsi_cmnd *scp)
4692 struct scsi_cmnd *tscp;
4694 ASC_DBG(2, "asc_scsi_done_list: begin\n");
4695 while (scp != NULL) {
4696 asc_board_t *boardp;
4697 struct device *dev;
4699 ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp);
4700 tscp = REQPNEXT(scp);
4701 scp->host_scribble = NULL;
4703 boardp = ASC_BOARDP(scp->device->host);
4705 if (ASC_NARROW_BOARD(boardp))
4706 dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
4707 else
4708 dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
4710 if (scp->use_sg)
4711 dma_unmap_sg(dev,
4712 (struct scatterlist *)scp->request_buffer,
4713 scp->use_sg, scp->sc_data_direction);
4714 else if (scp->request_bufflen)
4715 dma_unmap_single(dev, scp->SCp.dma_handle,
4716 scp->request_bufflen,
4717 scp->sc_data_direction);
4719 ASC_STATS(scp->device->host, done);
4720 ASC_ASSERT(scp->scsi_done != NULL);
4722 scp->scsi_done(scp);
4724 scp = tscp;
4726 ASC_DBG(2, "asc_scsi_done_list: done\n");
4727 return;
4731 * Execute a single 'Scsi_Cmnd'.
4733 * The function 'done' is called when the request has been completed.
4735 * Scsi_Cmnd:
4737 * host - board controlling device
4738 * device - device to send command
4739 * target - target of device
4740 * lun - lun of device
4741 * cmd_len - length of SCSI CDB
4742 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
4743 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
4745 * if (use_sg == 0) {
4746 * request_buffer - buffer address for request
4747 * request_bufflen - length of request buffer
4748 * } else {
4749 * request_buffer - pointer to scatterlist structure
4752 * sense_buffer - sense command buffer
4754 * result (4 bytes of an int):
4755 * Byte Meaning
4756 * 0 SCSI Status Byte Code
4757 * 1 SCSI One Byte Message Code
4758 * 2 Host Error Code
4759 * 3 Mid-Level Error Code
4761 * host driver fields:
4762 * SCp - Scsi_Pointer used for command processing status
4763 * scsi_done - used to save caller's done function
4764 * host_scribble - used for pointer to another struct scsi_cmnd
4766 * If this function returns ASC_NOERROR the request has been enqueued
4767 * on the board's 'active' queue and will be completed from the
4768 * interrupt handler.
4770 * If this function returns ASC_NOERROR the request has been enqueued
4771 * on the board's 'done' queue and must be completed by the caller.
4773 * If ASC_BUSY is returned the request will be enqueued by the
4774 * caller on the target's waiting queue and re-tried later.
4776 static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
4778 asc_board_t *boardp;
4779 ASC_DVC_VAR *asc_dvc_varp;
4780 ADV_DVC_VAR *adv_dvc_varp;
4781 ADV_SCSI_REQ_Q *adv_scsiqp;
4782 struct scsi_device *device;
4783 int ret;
4785 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
4786 (ulong)scp, (ulong)scp->scsi_done);
4788 boardp = ASC_BOARDP(scp->device->host);
4789 device = boardp->device[scp->device->id];
4791 if (ASC_NARROW_BOARD(boardp)) {
4793 * Build and execute Narrow Board request.
4796 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4799 * Build Asc Library request structure using the
4800 * global structures 'asc_scsi_req' and 'asc_sg_head'.
4802 * If an error is returned, then the request has been
4803 * queued on the board done queue. It will be completed
4804 * by the caller.
4806 * asc_build_req() can not return ASC_BUSY.
4808 if (asc_build_req(boardp, scp) == ASC_ERROR) {
4809 ASC_STATS(scp->device->host, build_error);
4810 return ASC_ERROR;
4814 * Execute the command. If there is no error, add the command
4815 * to the active queue.
4817 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
4818 case ASC_NOERROR:
4819 ASC_STATS(scp->device->host, exe_noerror);
4821 * Increment monotonically increasing per device successful
4822 * request counter. Wrapping doesn't matter.
4824 boardp->reqcnt[scp->device->id]++;
4825 asc_enqueue(&boardp->active, scp, ASC_BACK);
4826 ASC_DBG(1,
4827 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
4828 break;
4829 case ASC_BUSY:
4831 * Caller will enqueue request on the target's waiting queue
4832 * and retry later.
4834 ASC_STATS(scp->device->host, exe_busy);
4835 break;
4836 case ASC_ERROR:
4837 ASC_PRINT2
4838 ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4839 boardp->id, asc_dvc_varp->err_code);
4840 ASC_STATS(scp->device->host, exe_error);
4841 scp->result = HOST_BYTE(DID_ERROR);
4842 asc_enqueue(&boardp->done, scp, ASC_BACK);
4843 break;
4844 default:
4845 ASC_PRINT2
4846 ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
4847 boardp->id, asc_dvc_varp->err_code);
4848 ASC_STATS(scp->device->host, exe_unknown);
4849 scp->result = HOST_BYTE(DID_ERROR);
4850 asc_enqueue(&boardp->done, scp, ASC_BACK);
4851 break;
4853 } else {
4855 * Build and execute Wide Board request.
4857 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4860 * Build and get a pointer to an Adv Library request structure.
4862 * If the request is successfully built then send it below,
4863 * otherwise return with an error.
4865 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
4866 case ASC_NOERROR:
4867 ASC_DBG(3,
4868 "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
4869 break;
4870 case ASC_BUSY:
4871 ASC_DBG(1,
4872 "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
4874 * If busy is returned the request has not been enqueued.
4875 * It will be enqueued by the caller on the target's waiting
4876 * queue and retried later.
4878 * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg'
4879 * count wide board busy conditions. They are updated in
4880 * adv_build_req and adv_get_sglist, respectively.
4882 return ASC_BUSY;
4883 case ASC_ERROR:
4885 * If an error is returned, then the request has been
4886 * queued on the board done queue. It will be completed
4887 * by the caller.
4889 default:
4890 ASC_DBG(1,
4891 "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
4892 ASC_STATS(scp->device->host, build_error);
4893 return ASC_ERROR;
4897 * Execute the command. If there is no error, add the command
4898 * to the active queue.
4900 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
4901 case ASC_NOERROR:
4902 ASC_STATS(scp->device->host, exe_noerror);
4904 * Increment monotonically increasing per device successful
4905 * request counter. Wrapping doesn't matter.
4907 boardp->reqcnt[scp->device->id]++;
4908 asc_enqueue(&boardp->active, scp, ASC_BACK);
4909 ASC_DBG(1,
4910 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
4911 break;
4912 case ASC_BUSY:
4914 * Caller will enqueue request on the target's waiting queue
4915 * and retry later.
4917 ASC_STATS(scp->device->host, exe_busy);
4918 break;
4919 case ASC_ERROR:
4920 ASC_PRINT2
4921 ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
4922 boardp->id, adv_dvc_varp->err_code);
4923 ASC_STATS(scp->device->host, exe_error);
4924 scp->result = HOST_BYTE(DID_ERROR);
4925 asc_enqueue(&boardp->done, scp, ASC_BACK);
4926 break;
4927 default:
4928 ASC_PRINT2
4929 ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
4930 boardp->id, adv_dvc_varp->err_code);
4931 ASC_STATS(scp->device->host, exe_unknown);
4932 scp->result = HOST_BYTE(DID_ERROR);
4933 asc_enqueue(&boardp->done, scp, ASC_BACK);
4934 break;
4938 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
4939 return ret;
4943 * Build a request structure for the Asc Library (Narrow Board).
4945 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
4946 * used to build the request.
4948 * If an error occurs, then queue the request on the board done
4949 * queue and return ASC_ERROR.
4951 static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
4953 struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
4956 * Mutually exclusive access is required to 'asc_scsi_q' and
4957 * 'asc_sg_head' until after the request is started.
4959 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
4962 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
4964 asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
4967 * Build the ASC_SCSI_Q request.
4969 * For narrow boards a CDB length maximum of 12 bytes
4970 * is supported.
4972 if (scp->cmd_len > ASC_MAX_CDB_LEN) {
4973 ASC_PRINT3
4974 ("asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN %d\n",
4975 boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN);
4976 scp->result = HOST_BYTE(DID_ERROR);
4977 asc_enqueue(&boardp->done, scp, ASC_BACK);
4978 return ASC_ERROR;
4980 asc_scsi_q.cdbptr = &scp->cmnd[0];
4981 asc_scsi_q.q2.cdb_len = scp->cmd_len;
4982 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
4983 asc_scsi_q.q1.target_lun = scp->device->lun;
4984 asc_scsi_q.q2.target_ix =
4985 ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
4986 asc_scsi_q.q1.sense_addr =
4987 cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
4988 asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
4991 * If there are any outstanding requests for the current target,
4992 * then every 255th request send an ORDERED request. This heuristic
4993 * tries to retain the benefit of request sorting while preventing
4994 * request starvation. 255 is the max number of tags or pending commands
4995 * a device may have outstanding.
4997 * The request count is incremented below for every successfully
4998 * started request.
5001 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
5002 (boardp->reqcnt[scp->device->id] % 255) == 0) {
5003 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
5004 } else {
5005 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
5009 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
5010 * buffer command.
5012 if (scp->use_sg == 0) {
5014 * CDB request of single contiguous buffer.
5016 ASC_STATS(scp->device->host, cont_cnt);
5017 scp->SCp.dma_handle = scp->request_bufflen ?
5018 dma_map_single(dev, scp->request_buffer,
5019 scp->request_bufflen,
5020 scp->sc_data_direction) : 0;
5021 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
5022 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
5023 ASC_STATS_ADD(scp->device->host, cont_xfer,
5024 ASC_CEILING(scp->request_bufflen, 512));
5025 asc_scsi_q.q1.sg_queue_cnt = 0;
5026 asc_scsi_q.sg_head = NULL;
5027 } else {
5029 * CDB scatter-gather request list.
5031 int sgcnt;
5032 int use_sg;
5033 struct scatterlist *slp;
5035 slp = (struct scatterlist *)scp->request_buffer;
5036 use_sg =
5037 dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
5039 if (use_sg > scp->device->host->sg_tablesize) {
5040 ASC_PRINT3
5041 ("asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
5042 boardp->id, use_sg,
5043 scp->device->host->sg_tablesize);
5044 dma_unmap_sg(dev, slp, scp->use_sg,
5045 scp->sc_data_direction);
5046 scp->result = HOST_BYTE(DID_ERROR);
5047 asc_enqueue(&boardp->done, scp, ASC_BACK);
5048 return ASC_ERROR;
5051 ASC_STATS(scp->device->host, sg_cnt);
5054 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
5055 * structure to point to it.
5057 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
5059 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
5060 asc_scsi_q.sg_head = &asc_sg_head;
5061 asc_scsi_q.q1.data_cnt = 0;
5062 asc_scsi_q.q1.data_addr = 0;
5063 /* This is a byte value, otherwise it would need to be swapped. */
5064 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
5065 ASC_STATS_ADD(scp->device->host, sg_elem,
5066 asc_sg_head.entry_cnt);
5069 * Convert scatter-gather list into ASC_SG_HEAD list.
5071 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
5072 asc_sg_head.sg_list[sgcnt].addr =
5073 cpu_to_le32(sg_dma_address(slp));
5074 asc_sg_head.sg_list[sgcnt].bytes =
5075 cpu_to_le32(sg_dma_len(slp));
5076 ASC_STATS_ADD(scp->device->host, sg_xfer,
5077 ASC_CEILING(sg_dma_len(slp), 512));
5081 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
5082 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
5084 return ASC_NOERROR;
5088 * Build a request structure for the Adv Library (Wide Board).
5090 * If an adv_req_t can not be allocated to issue the request,
5091 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
5093 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
5094 * microcode for DMA addresses or math operations are byte swapped
5095 * to little-endian order.
5097 static int
5098 adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
5099 ADV_SCSI_REQ_Q **adv_scsiqpp)
5101 adv_req_t *reqp;
5102 ADV_SCSI_REQ_Q *scsiqp;
5103 int i;
5104 int ret;
5105 struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
5108 * Allocate an adv_req_t structure from the board to execute
5109 * the command.
5111 if (boardp->adv_reqp == NULL) {
5112 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
5113 ASC_STATS(scp->device->host, adv_build_noreq);
5114 return ASC_BUSY;
5115 } else {
5116 reqp = boardp->adv_reqp;
5117 boardp->adv_reqp = reqp->next_reqp;
5118 reqp->next_reqp = NULL;
5122 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
5124 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5127 * Initialize the structure.
5129 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
5132 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
5134 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
5137 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
5139 reqp->cmndp = scp;
5142 * Build the ADV_SCSI_REQ_Q request.
5146 * Set CDB length and copy it to the request structure.
5147 * For wide boards a CDB length maximum of 16 bytes
5148 * is supported.
5150 if (scp->cmd_len > ADV_MAX_CDB_LEN) {
5151 ASC_PRINT3
5152 ("adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n",
5153 boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
5154 scp->result = HOST_BYTE(DID_ERROR);
5155 asc_enqueue(&boardp->done, scp, ASC_BACK);
5156 return ASC_ERROR;
5158 scsiqp->cdb_len = scp->cmd_len;
5159 /* Copy first 12 CDB bytes to cdb[]. */
5160 for (i = 0; i < scp->cmd_len && i < 12; i++) {
5161 scsiqp->cdb[i] = scp->cmnd[i];
5163 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
5164 for (; i < scp->cmd_len; i++) {
5165 scsiqp->cdb16[i - 12] = scp->cmnd[i];
5168 scsiqp->target_id = scp->device->id;
5169 scsiqp->target_lun = scp->device->lun;
5171 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
5172 scsiqp->sense_len = sizeof(scp->sense_buffer);
5175 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
5176 * buffer command.
5179 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
5180 scsiqp->vdata_addr = scp->request_buffer;
5181 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
5183 if (scp->use_sg == 0) {
5185 * CDB request of single contiguous buffer.
5187 reqp->sgblkp = NULL;
5188 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
5189 if (scp->request_bufflen) {
5190 scsiqp->vdata_addr = scp->request_buffer;
5191 scp->SCp.dma_handle =
5192 dma_map_single(dev, scp->request_buffer,
5193 scp->request_bufflen,
5194 scp->sc_data_direction);
5195 } else {
5196 scsiqp->vdata_addr = NULL;
5197 scp->SCp.dma_handle = 0;
5199 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
5200 scsiqp->sg_list_ptr = NULL;
5201 scsiqp->sg_real_addr = 0;
5202 ASC_STATS(scp->device->host, cont_cnt);
5203 ASC_STATS_ADD(scp->device->host, cont_xfer,
5204 ASC_CEILING(scp->request_bufflen, 512));
5205 } else {
5207 * CDB scatter-gather request list.
5209 struct scatterlist *slp;
5210 int use_sg;
5212 slp = (struct scatterlist *)scp->request_buffer;
5213 use_sg =
5214 dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
5216 if (use_sg > ADV_MAX_SG_LIST) {
5217 ASC_PRINT3
5218 ("adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
5219 boardp->id, use_sg,
5220 scp->device->host->sg_tablesize);
5221 dma_unmap_sg(dev, slp, scp->use_sg,
5222 scp->sc_data_direction);
5223 scp->result = HOST_BYTE(DID_ERROR);
5224 asc_enqueue(&boardp->done, scp, ASC_BACK);
5227 * Free the 'adv_req_t' structure by adding it back to the
5228 * board free list.
5230 reqp->next_reqp = boardp->adv_reqp;
5231 boardp->adv_reqp = reqp;
5233 return ASC_ERROR;
5236 if ((ret =
5237 adv_get_sglist(boardp, reqp, scp,
5238 use_sg)) != ADV_SUCCESS) {
5240 * Free the adv_req_t structure by adding it back to the
5241 * board free list.
5243 reqp->next_reqp = boardp->adv_reqp;
5244 boardp->adv_reqp = reqp;
5246 return ret;
5249 ASC_STATS(scp->device->host, sg_cnt);
5250 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
5253 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5254 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
5256 *adv_scsiqpp = scsiqp;
5258 return ASC_NOERROR;
5262 * Build scatter-gather list for Adv Library (Wide Board).
5264 * Additional ADV_SG_BLOCK structures will need to be allocated
5265 * if the total number of scatter-gather elements exceeds
5266 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
5267 * assumed to be physically contiguous.
5269 * Return:
5270 * ADV_SUCCESS(1) - SG List successfully created
5271 * ADV_ERROR(-1) - SG List creation failed
5273 static int
5274 adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp,
5275 int use_sg)
5277 adv_sgblk_t *sgblkp;
5278 ADV_SCSI_REQ_Q *scsiqp;
5279 struct scatterlist *slp;
5280 int sg_elem_cnt;
5281 ADV_SG_BLOCK *sg_block, *prev_sg_block;
5282 ADV_PADDR sg_block_paddr;
5283 int i;
5285 scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q);
5286 slp = (struct scatterlist *)scp->request_buffer;
5287 sg_elem_cnt = use_sg;
5288 prev_sg_block = NULL;
5289 reqp->sgblkp = NULL;
5291 do {
5293 * Allocate a 'adv_sgblk_t' structure from the board free
5294 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
5295 * (15) scatter-gather elements.
5297 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
5298 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
5299 ASC_STATS(scp->device->host, adv_build_nosg);
5302 * Allocation failed. Free 'adv_sgblk_t' structures already
5303 * allocated for the request.
5305 while ((sgblkp = reqp->sgblkp) != NULL) {
5306 /* Remove 'sgblkp' from the request list. */
5307 reqp->sgblkp = sgblkp->next_sgblkp;
5309 /* Add 'sgblkp' to the board free list. */
5310 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5311 boardp->adv_sgblkp = sgblkp;
5313 return ASC_BUSY;
5314 } else {
5315 /* Complete 'adv_sgblk_t' board allocation. */
5316 boardp->adv_sgblkp = sgblkp->next_sgblkp;
5317 sgblkp->next_sgblkp = NULL;
5320 * Get 8 byte aligned virtual and physical addresses for
5321 * the allocated ADV_SG_BLOCK structure.
5323 sg_block =
5324 (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block);
5325 sg_block_paddr = virt_to_bus(sg_block);
5328 * Check if this is the first 'adv_sgblk_t' for the request.
5330 if (reqp->sgblkp == NULL) {
5331 /* Request's first scatter-gather block. */
5332 reqp->sgblkp = sgblkp;
5335 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
5336 * address pointers.
5338 scsiqp->sg_list_ptr = sg_block;
5339 scsiqp->sg_real_addr =
5340 cpu_to_le32(sg_block_paddr);
5341 } else {
5342 /* Request's second or later scatter-gather block. */
5343 sgblkp->next_sgblkp = reqp->sgblkp;
5344 reqp->sgblkp = sgblkp;
5347 * Point the previous ADV_SG_BLOCK structure to
5348 * the newly allocated ADV_SG_BLOCK structure.
5350 ASC_ASSERT(prev_sg_block != NULL);
5351 prev_sg_block->sg_ptr =
5352 cpu_to_le32(sg_block_paddr);
5356 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) {
5357 sg_block->sg_list[i].sg_addr =
5358 cpu_to_le32(sg_dma_address(slp));
5359 sg_block->sg_list[i].sg_count =
5360 cpu_to_le32(sg_dma_len(slp));
5361 ASC_STATS_ADD(scp->device->host, sg_xfer,
5362 ASC_CEILING(sg_dma_len(slp), 512));
5364 if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */
5365 sg_block->sg_cnt = i + 1;
5366 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
5367 return ADV_SUCCESS;
5369 slp++;
5371 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
5372 prev_sg_block = sg_block;
5374 while (1);
5375 /* NOTREACHED */
5379 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
5381 * Interrupt callback function for the Narrow SCSI Asc Library.
5383 static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
5385 asc_board_t *boardp;
5386 struct scsi_cmnd *scp;
5387 struct Scsi_Host *shost;
5389 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
5390 (ulong)asc_dvc_varp, (ulong)qdonep);
5391 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
5394 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5395 * command that has been completed.
5397 scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
5398 ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp);
5400 if (scp == NULL) {
5401 ASC_PRINT("asc_isr_callback: scp is NULL\n");
5402 return;
5404 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5406 shost = scp->device->host;
5407 ASC_STATS(shost, callback);
5408 ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost);
5411 * If the request isn't found on the active queue, it may
5412 * have been removed to handle a reset request.
5413 * Display a message and return.
5415 boardp = ASC_BOARDP(shost);
5416 ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
5417 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5418 ASC_PRINT2
5419 ("asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
5420 boardp->id, (ulong)scp);
5421 return;
5425 * 'qdonep' contains the command's ending status.
5427 switch (qdonep->d3.done_stat) {
5428 case QD_NO_ERROR:
5429 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
5430 scp->result = 0;
5433 * If an INQUIRY command completed successfully, then call
5434 * the AscInquiryHandling() function to set-up the device.
5436 if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 &&
5437 (scp->request_bufflen - qdonep->remain_bytes) >= 8) {
5438 AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7,
5439 (ASC_SCSI_INQUIRY *)scp->
5440 request_buffer);
5444 * Check for an underrun condition.
5446 * If there was no error and an underrun condition, then
5447 * then return the number of underrun bytes.
5449 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
5450 qdonep->remain_bytes <= scp->request_bufflen) {
5451 ASC_DBG1(1,
5452 "asc_isr_callback: underrun condition %u bytes\n",
5453 (unsigned)qdonep->remain_bytes);
5454 scp->resid = qdonep->remain_bytes;
5456 break;
5458 case QD_WITH_ERROR:
5459 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
5460 switch (qdonep->d3.host_stat) {
5461 case QHSTA_NO_ERROR:
5462 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
5463 ASC_DBG(2,
5464 "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5465 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5466 sizeof(scp->sense_buffer));
5468 * Note: The 'status_byte()' macro used by target drivers
5469 * defined in scsi.h shifts the status byte returned by
5470 * host drivers right by 1 bit. This is why target drivers
5471 * also use right shifted status byte definitions. For
5472 * instance target drivers use CHECK_CONDITION, defined to
5473 * 0x1, instead of the SCSI defined check condition value
5474 * of 0x2. Host drivers are supposed to return the status
5475 * byte as it is defined by SCSI.
5477 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5478 STATUS_BYTE(qdonep->d3.scsi_stat);
5479 } else {
5480 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
5482 break;
5484 default:
5485 /* QHSTA error occurred */
5486 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
5487 qdonep->d3.host_stat);
5488 scp->result = HOST_BYTE(DID_BAD_TARGET);
5489 break;
5491 break;
5493 case QD_ABORTED_BY_HOST:
5494 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
5495 scp->result =
5496 HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.
5497 scsi_msg) |
5498 STATUS_BYTE(qdonep->d3.scsi_stat);
5499 break;
5501 default:
5502 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n",
5503 qdonep->d3.done_stat);
5504 scp->result =
5505 HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.
5506 scsi_msg) |
5507 STATUS_BYTE(qdonep->d3.scsi_stat);
5508 break;
5512 * If the 'init_tidmask' bit isn't already set for the target and the
5513 * current request finished normally, then set the bit for the target
5514 * to indicate that a device is present.
5516 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5517 qdonep->d3.done_stat == QD_NO_ERROR &&
5518 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
5519 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5523 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5524 * function, add the command to the end of the board's done queue.
5525 * The done function for the command will be called from
5526 * advansys_interrupt().
5528 asc_enqueue(&boardp->done, scp, ASC_BACK);
5530 return;
5534 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
5536 * Callback function for the Wide SCSI Adv Library.
5538 static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
5540 asc_board_t *boardp;
5541 adv_req_t *reqp;
5542 adv_sgblk_t *sgblkp;
5543 struct scsi_cmnd *scp;
5544 struct Scsi_Host *shost;
5545 ADV_DCNT resid_cnt;
5547 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
5548 (ulong)adv_dvc_varp, (ulong)scsiqp);
5549 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
5552 * Get the adv_req_t structure for the command that has been
5553 * completed. The adv_req_t structure actually contains the
5554 * completed ADV_SCSI_REQ_Q structure.
5556 reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr);
5557 ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp);
5558 if (reqp == NULL) {
5559 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
5560 return;
5564 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
5565 * command that has been completed.
5567 * Note: The adv_req_t request structure and adv_sgblk_t structure,
5568 * if any, are dropped, because a board structure pointer can not be
5569 * determined.
5571 scp = reqp->cmndp;
5572 ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp);
5573 if (scp == NULL) {
5574 ASC_PRINT
5575 ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
5576 return;
5578 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
5580 shost = scp->device->host;
5581 ASC_STATS(shost, callback);
5582 ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost);
5585 * If the request isn't found on the active queue, it may have been
5586 * removed to handle a reset request. Display a message and return.
5588 * Note: Because the structure may still be in use don't attempt
5589 * to free the adv_req_t and adv_sgblk_t, if any, structures.
5591 boardp = ASC_BOARDP(shost);
5592 ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
5593 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
5594 ASC_PRINT2
5595 ("adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
5596 boardp->id, (ulong)scp);
5597 return;
5601 * 'done_status' contains the command's ending status.
5603 switch (scsiqp->done_status) {
5604 case QD_NO_ERROR:
5605 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
5606 scp->result = 0;
5609 * Check for an underrun condition.
5611 * If there was no error and an underrun condition, then
5612 * then return the number of underrun bytes.
5614 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
5615 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
5616 resid_cnt <= scp->request_bufflen) {
5617 ASC_DBG1(1,
5618 "adv_isr_callback: underrun condition %lu bytes\n",
5619 (ulong)resid_cnt);
5620 scp->resid = resid_cnt;
5622 break;
5624 case QD_WITH_ERROR:
5625 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
5626 switch (scsiqp->host_status) {
5627 case QHSTA_NO_ERROR:
5628 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
5629 ASC_DBG(2,
5630 "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
5631 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
5632 sizeof(scp->sense_buffer));
5634 * Note: The 'status_byte()' macro used by target drivers
5635 * defined in scsi.h shifts the status byte returned by
5636 * host drivers right by 1 bit. This is why target drivers
5637 * also use right shifted status byte definitions. For
5638 * instance target drivers use CHECK_CONDITION, defined to
5639 * 0x1, instead of the SCSI defined check condition value
5640 * of 0x2. Host drivers are supposed to return the status
5641 * byte as it is defined by SCSI.
5643 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
5644 STATUS_BYTE(scsiqp->scsi_status);
5645 } else {
5646 scp->result = STATUS_BYTE(scsiqp->scsi_status);
5648 break;
5650 default:
5651 /* Some other QHSTA error occurred. */
5652 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
5653 scsiqp->host_status);
5654 scp->result = HOST_BYTE(DID_BAD_TARGET);
5655 break;
5657 break;
5659 case QD_ABORTED_BY_HOST:
5660 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
5661 scp->result =
5662 HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
5663 break;
5665 default:
5666 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n",
5667 scsiqp->done_status);
5668 scp->result =
5669 HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
5670 break;
5674 * If the 'init_tidmask' bit isn't already set for the target and the
5675 * current request finished normally, then set the bit for the target
5676 * to indicate that a device is present.
5678 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
5679 scsiqp->done_status == QD_NO_ERROR &&
5680 scsiqp->host_status == QHSTA_NO_ERROR) {
5681 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
5685 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
5686 * function, add the command to the end of the board's done queue.
5687 * The done function for the command will be called from
5688 * advansys_interrupt().
5690 asc_enqueue(&boardp->done, scp, ASC_BACK);
5693 * Free all 'adv_sgblk_t' structures allocated for the request.
5695 while ((sgblkp = reqp->sgblkp) != NULL) {
5696 /* Remove 'sgblkp' from the request list. */
5697 reqp->sgblkp = sgblkp->next_sgblkp;
5699 /* Add 'sgblkp' to the board free list. */
5700 sgblkp->next_sgblkp = boardp->adv_sgblkp;
5701 boardp->adv_sgblkp = sgblkp;
5705 * Free the adv_req_t structure used with the command by adding
5706 * it back to the board free list.
5708 reqp->next_reqp = boardp->adv_reqp;
5709 boardp->adv_reqp = reqp;
5711 ASC_DBG(1, "adv_isr_callback: done\n");
5713 return;
5717 * adv_async_callback() - Adv Library asynchronous event callback function.
5719 static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
5721 switch (code) {
5722 case ADV_ASYNC_SCSI_BUS_RESET_DET:
5724 * The firmware detected a SCSI Bus reset.
5726 ASC_DBG(0,
5727 "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
5728 break;
5730 case ADV_ASYNC_RDMA_FAILURE:
5732 * Handle RDMA failure by resetting the SCSI Bus and
5733 * possibly the chip if it is unresponsive. Log the error
5734 * with a unique code.
5736 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
5737 AdvResetChipAndSB(adv_dvc_varp);
5738 break;
5740 case ADV_HOST_SCSI_BUS_RESET:
5742 * Host generated SCSI bus reset occurred.
5744 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
5745 break;
5747 default:
5748 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
5749 break;
5754 * Add a 'REQP' to the end of specified queue. Set 'tidmask'
5755 * to indicate a command is queued for the device.
5757 * 'flag' may be either ASC_FRONT or ASC_BACK.
5759 * 'REQPNEXT(reqp)' returns reqp's next pointer.
5761 static void asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
5763 int tid;
5765 ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
5766 (ulong)ascq, (ulong)reqp, flag);
5767 ASC_ASSERT(reqp != NULL);
5768 ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
5769 tid = REQPTID(reqp);
5770 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5771 if (flag == ASC_FRONT) {
5772 reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
5773 ascq->q_first[tid] = reqp;
5774 /* If the queue was empty, set the last pointer. */
5775 if (ascq->q_last[tid] == NULL) {
5776 ascq->q_last[tid] = reqp;
5778 } else { /* ASC_BACK */
5779 if (ascq->q_last[tid] != NULL) {
5780 ascq->q_last[tid]->host_scribble =
5781 (unsigned char *)reqp;
5783 ascq->q_last[tid] = reqp;
5784 reqp->host_scribble = NULL;
5785 /* If the queue was empty, set the first pointer. */
5786 if (ascq->q_first[tid] == NULL) {
5787 ascq->q_first[tid] = reqp;
5790 /* The queue has at least one entry, set its bit. */
5791 ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
5792 #ifdef ADVANSYS_STATS
5793 /* Maintain request queue statistics. */
5794 ascq->q_tot_cnt[tid]++;
5795 ascq->q_cur_cnt[tid]++;
5796 if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
5797 ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
5798 ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
5799 tid, ascq->q_max_cnt[tid]);
5801 REQPTIME(reqp) = REQTIMESTAMP();
5802 #endif /* ADVANSYS_STATS */
5803 ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong)reqp);
5804 return;
5808 * Return first queued 'REQP' on the specified queue for
5809 * the specified target device. Clear the 'tidmask' bit for
5810 * the device if no more commands are left queued for it.
5812 * 'REQPNEXT(reqp)' returns reqp's next pointer.
5814 static REQP asc_dequeue(asc_queue_t *ascq, int tid)
5816 REQP reqp;
5818 ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5819 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5820 if ((reqp = ascq->q_first[tid]) != NULL) {
5821 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
5822 ascq->q_first[tid] = REQPNEXT(reqp);
5823 /* If the queue is empty, clear its bit and the last pointer. */
5824 if (ascq->q_first[tid] == NULL) {
5825 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5826 ASC_ASSERT(ascq->q_last[tid] == reqp);
5827 ascq->q_last[tid] = NULL;
5829 #ifdef ADVANSYS_STATS
5830 /* Maintain request queue statistics. */
5831 ascq->q_cur_cnt[tid]--;
5832 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
5833 REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
5834 #endif /* ADVANSYS_STATS */
5836 ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong)reqp);
5837 return reqp;
5841 * Return a pointer to a singly linked list of all the requests queued
5842 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
5844 * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
5845 * the last request returned in the singly linked list.
5847 * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
5848 * then all queued requests are concatenated into one list and
5849 * returned.
5851 * Note: If 'lastpp' is used to append a new list to the end of
5852 * an old list, only change the old list last pointer if '*lastpp'
5853 * (or the function return value) is not NULL, i.e. use a temporary
5854 * variable for 'lastpp' and check its value after the function return
5855 * before assigning it to the list last pointer.
5857 * Unfortunately collecting queuing time statistics adds overhead to
5858 * the function that isn't inherent to the function's algorithm.
5860 static REQP asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
5862 REQP firstp, lastp;
5863 int i;
5865 ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong)ascq, tid);
5866 ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
5869 * If 'tid' is not ASC_TID_ALL, return requests only for
5870 * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
5871 * requests for all tids.
5873 if (tid != ASC_TID_ALL) {
5874 /* Return all requests for the specified 'tid'. */
5875 if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
5876 /* List is empty; Set first and last return pointers to NULL. */
5877 firstp = lastp = NULL;
5878 } else {
5879 firstp = ascq->q_first[tid];
5880 lastp = ascq->q_last[tid];
5881 ascq->q_first[tid] = ascq->q_last[tid] = NULL;
5882 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5883 #ifdef ADVANSYS_STATS
5885 REQP reqp;
5886 ascq->q_cur_cnt[tid] = 0;
5887 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
5888 REQTIMESTAT("asc_dequeue_list", ascq,
5889 reqp, tid);
5892 #endif /* ADVANSYS_STATS */
5894 } else {
5895 /* Return all requests for all tids. */
5896 firstp = lastp = NULL;
5897 for (i = 0; i <= ADV_MAX_TID; i++) {
5898 if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
5899 if (firstp == NULL) {
5900 firstp = ascq->q_first[i];
5901 lastp = ascq->q_last[i];
5902 } else {
5903 ASC_ASSERT(lastp != NULL);
5904 lastp->host_scribble =
5905 (unsigned char *)ascq->q_first[i];
5906 lastp = ascq->q_last[i];
5908 ascq->q_first[i] = ascq->q_last[i] = NULL;
5909 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
5910 #ifdef ADVANSYS_STATS
5911 ascq->q_cur_cnt[i] = 0;
5912 #endif /* ADVANSYS_STATS */
5915 #ifdef ADVANSYS_STATS
5917 REQP reqp;
5918 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
5919 REQTIMESTAT("asc_dequeue_list", ascq, reqp,
5920 reqp->device->id);
5923 #endif /* ADVANSYS_STATS */
5925 if (lastpp) {
5926 *lastpp = lastp;
5928 ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong)firstp);
5929 return firstp;
5933 * Remove the specified 'REQP' from the specified queue for
5934 * the specified target device. Clear the 'tidmask' bit for the
5935 * device if no more commands are left queued for it.
5937 * 'REQPNEXT(reqp)' returns reqp's the next pointer.
5939 * Return ASC_TRUE if the command was found and removed,
5940 * otherwise return ASC_FALSE.
5942 static int asc_rmqueue(asc_queue_t *ascq, REQP reqp)
5944 REQP currp, prevp;
5945 int tid;
5946 int ret = ASC_FALSE;
5948 ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
5949 (ulong)ascq, (ulong)reqp);
5950 ASC_ASSERT(reqp != NULL);
5952 tid = REQPTID(reqp);
5953 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
5956 * Handle the common case of 'reqp' being the first
5957 * entry on the queue.
5959 if (reqp == ascq->q_first[tid]) {
5960 ret = ASC_TRUE;
5961 ascq->q_first[tid] = REQPNEXT(reqp);
5962 /* If the queue is now empty, clear its bit and the last pointer. */
5963 if (ascq->q_first[tid] == NULL) {
5964 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
5965 ASC_ASSERT(ascq->q_last[tid] == reqp);
5966 ascq->q_last[tid] = NULL;
5968 } else if (ascq->q_first[tid] != NULL) {
5969 ASC_ASSERT(ascq->q_last[tid] != NULL);
5971 * Because the case of 'reqp' being the first entry has been
5972 * handled above and it is known the queue is not empty, if
5973 * 'reqp' is found on the queue it is guaranteed the queue will
5974 * not become empty and that 'q_first[tid]' will not be changed.
5976 * Set 'prevp' to the first entry, 'currp' to the second entry,
5977 * and search for 'reqp'.
5979 for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
5980 currp; prevp = currp, currp = REQPNEXT(currp)) {
5981 if (currp == reqp) {
5982 ret = ASC_TRUE;
5983 prevp->host_scribble =
5984 (unsigned char *)REQPNEXT(currp);
5985 reqp->host_scribble = NULL;
5986 if (ascq->q_last[tid] == reqp) {
5987 ascq->q_last[tid] = prevp;
5989 break;
5993 #ifdef ADVANSYS_STATS
5994 /* Maintain request queue statistics. */
5995 if (ret == ASC_TRUE) {
5996 ascq->q_cur_cnt[tid]--;
5997 REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
5999 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
6000 #endif /* ADVANSYS_STATS */
6001 ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong)reqp, ret);
6002 return ret;
6006 * Execute as many queued requests as possible for the specified queue.
6008 * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd.
6010 static void asc_execute_queue(asc_queue_t *ascq)
6012 ADV_SCSI_BIT_ID_TYPE scan_tidmask;
6013 REQP reqp;
6014 int i;
6016 ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong)ascq);
6018 * Execute queued commands for devices attached to
6019 * the current board in round-robin fashion.
6021 scan_tidmask = ascq->q_tidmask;
6022 do {
6023 for (i = 0; i <= ADV_MAX_TID; i++) {
6024 if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
6025 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
6026 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
6027 } else
6028 if (asc_execute_scsi_cmnd
6029 ((struct scsi_cmnd *)reqp)
6030 == ASC_BUSY) {
6031 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
6033 * The request returned ASC_BUSY. Enqueue at the front of
6034 * target's waiting list to maintain correct ordering.
6036 asc_enqueue(ascq, reqp, ASC_FRONT);
6040 } while (scan_tidmask);
6041 return;
6044 #ifdef CONFIG_PROC_FS
6046 * asc_prt_board_devices()
6048 * Print driver information for devices attached to the board.
6050 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6051 * cf. asc_prt_line().
6053 * Return the number of characters copied into 'cp'. No more than
6054 * 'cplen' characters will be copied to 'cp'.
6056 static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen)
6058 asc_board_t *boardp;
6059 int leftlen;
6060 int totlen;
6061 int len;
6062 int chip_scsi_id;
6063 int i;
6065 boardp = ASC_BOARDP(shost);
6066 leftlen = cplen;
6067 totlen = len = 0;
6069 len = asc_prt_line(cp, leftlen,
6070 "\nDevice Information for AdvanSys SCSI Host %d:\n",
6071 shost->host_no);
6072 ASC_PRT_NEXT();
6074 if (ASC_NARROW_BOARD(boardp)) {
6075 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6076 } else {
6077 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6080 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
6081 ASC_PRT_NEXT();
6082 for (i = 0; i <= ADV_MAX_TID; i++) {
6083 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
6084 len = asc_prt_line(cp, leftlen, " %X,", i);
6085 ASC_PRT_NEXT();
6088 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
6089 ASC_PRT_NEXT();
6091 return totlen;
6095 * Display Wide Board BIOS Information.
6097 static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen)
6099 asc_board_t *boardp;
6100 int leftlen;
6101 int totlen;
6102 int len;
6103 ushort major, minor, letter;
6105 boardp = ASC_BOARDP(shost);
6106 leftlen = cplen;
6107 totlen = len = 0;
6109 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
6110 ASC_PRT_NEXT();
6113 * If the BIOS saved a valid signature, then fill in
6114 * the BIOS code segment base address.
6116 if (boardp->bios_signature != 0x55AA) {
6117 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
6118 ASC_PRT_NEXT();
6119 len = asc_prt_line(cp, leftlen,
6120 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
6121 ASC_PRT_NEXT();
6122 len = asc_prt_line(cp, leftlen,
6123 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
6124 ASC_PRT_NEXT();
6125 } else {
6126 major = (boardp->bios_version >> 12) & 0xF;
6127 minor = (boardp->bios_version >> 8) & 0xF;
6128 letter = (boardp->bios_version & 0xFF);
6130 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
6131 major, minor,
6132 letter >= 26 ? '?' : letter + 'A');
6133 ASC_PRT_NEXT();
6136 * Current available ROM BIOS release is 3.1I for UW
6137 * and 3.2I for U2W. This code doesn't differentiate
6138 * UW and U2W boards.
6140 if (major < 3 || (major <= 3 && minor < 1) ||
6141 (major <= 3 && minor <= 1 && letter < ('I' - 'A'))) {
6142 len = asc_prt_line(cp, leftlen,
6143 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
6144 ASC_PRT_NEXT();
6145 len = asc_prt_line(cp, leftlen,
6146 "ftp://ftp.connectcom.net/pub\n");
6147 ASC_PRT_NEXT();
6151 return totlen;
6155 * Add serial number to information bar if signature AAh
6156 * is found in at bit 15-9 (7 bits) of word 1.
6158 * Serial Number consists fo 12 alpha-numeric digits.
6160 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
6161 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
6162 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
6163 * 5 - Product revision (A-J) Word0: " "
6165 * Signature Word1: 15-9 (7 bits)
6166 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
6167 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
6169 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
6171 * Note 1: Only production cards will have a serial number.
6173 * Note 2: Signature is most significant 7 bits (0xFE).
6175 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
6177 static int asc_get_eeprom_string(ushort *serialnum, uchar *cp)
6179 ushort w, num;
6181 if ((serialnum[1] & 0xFE00) != ((ushort)0xAA << 8)) {
6182 return ASC_FALSE;
6183 } else {
6185 * First word - 6 digits.
6187 w = serialnum[0];
6189 /* Product type - 1st digit. */
6190 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
6191 /* Product type is P=Prototype */
6192 *cp += 0x8;
6194 cp++;
6196 /* Manufacturing location - 2nd digit. */
6197 *cp++ = 'A' + ((w & 0x1C00) >> 10);
6199 /* Product ID - 3rd, 4th digits. */
6200 num = w & 0x3FF;
6201 *cp++ = '0' + (num / 100);
6202 num %= 100;
6203 *cp++ = '0' + (num / 10);
6205 /* Product revision - 5th digit. */
6206 *cp++ = 'A' + (num % 10);
6209 * Second word
6211 w = serialnum[1];
6214 * Year - 6th digit.
6216 * If bit 15 of third word is set, then the
6217 * last digit of the year is greater than 7.
6219 if (serialnum[2] & 0x8000) {
6220 *cp++ = '8' + ((w & 0x1C0) >> 6);
6221 } else {
6222 *cp++ = '0' + ((w & 0x1C0) >> 6);
6225 /* Week of year - 7th, 8th digits. */
6226 num = w & 0x003F;
6227 *cp++ = '0' + num / 10;
6228 num %= 10;
6229 *cp++ = '0' + num;
6232 * Third word
6234 w = serialnum[2] & 0x7FFF;
6236 /* Serial number - 9th digit. */
6237 *cp++ = 'A' + (w / 1000);
6239 /* 10th, 11th, 12th digits. */
6240 num = w % 1000;
6241 *cp++ = '0' + num / 100;
6242 num %= 100;
6243 *cp++ = '0' + num / 10;
6244 num %= 10;
6245 *cp++ = '0' + num;
6247 *cp = '\0'; /* Null Terminate the string. */
6248 return ASC_TRUE;
6253 * asc_prt_asc_board_eeprom()
6255 * Print board EEPROM configuration.
6257 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6258 * cf. asc_prt_line().
6260 * Return the number of characters copied into 'cp'. No more than
6261 * 'cplen' characters will be copied to 'cp'.
6263 static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
6265 asc_board_t *boardp;
6266 ASC_DVC_VAR *asc_dvc_varp;
6267 int leftlen;
6268 int totlen;
6269 int len;
6270 ASCEEP_CONFIG *ep;
6271 int i;
6272 #ifdef CONFIG_ISA
6273 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
6274 #endif /* CONFIG_ISA */
6275 uchar serialstr[13];
6277 boardp = ASC_BOARDP(shost);
6278 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6279 ep = &boardp->eep_config.asc_eep;
6281 leftlen = cplen;
6282 totlen = len = 0;
6284 len = asc_prt_line(cp, leftlen,
6285 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6286 shost->host_no);
6287 ASC_PRT_NEXT();
6289 if (asc_get_eeprom_string((ushort *)&ep->adapter_info[0], serialstr)
6290 == ASC_TRUE) {
6291 len =
6292 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6293 serialstr);
6294 ASC_PRT_NEXT();
6295 } else {
6296 if (ep->adapter_info[5] == 0xBB) {
6297 len = asc_prt_line(cp, leftlen,
6298 " Default Settings Used for EEPROM-less Adapter.\n");
6299 ASC_PRT_NEXT();
6300 } else {
6301 len = asc_prt_line(cp, leftlen,
6302 " Serial Number Signature Not Present.\n");
6303 ASC_PRT_NEXT();
6307 len = asc_prt_line(cp, leftlen,
6308 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6309 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng,
6310 ep->max_tag_qng);
6311 ASC_PRT_NEXT();
6313 len = asc_prt_line(cp, leftlen,
6314 " cntl 0x%x, no_scam 0x%x\n", ep->cntl, ep->no_scam);
6315 ASC_PRT_NEXT();
6317 len = asc_prt_line(cp, leftlen, " Target ID: ");
6318 ASC_PRT_NEXT();
6319 for (i = 0; i <= ASC_MAX_TID; i++) {
6320 len = asc_prt_line(cp, leftlen, " %d", i);
6321 ASC_PRT_NEXT();
6323 len = asc_prt_line(cp, leftlen, "\n");
6324 ASC_PRT_NEXT();
6326 len = asc_prt_line(cp, leftlen, " Disconnects: ");
6327 ASC_PRT_NEXT();
6328 for (i = 0; i <= ASC_MAX_TID; i++) {
6329 len = asc_prt_line(cp, leftlen, " %c",
6330 (ep->
6331 disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6332 'N');
6333 ASC_PRT_NEXT();
6335 len = asc_prt_line(cp, leftlen, "\n");
6336 ASC_PRT_NEXT();
6338 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
6339 ASC_PRT_NEXT();
6340 for (i = 0; i <= ASC_MAX_TID; i++) {
6341 len = asc_prt_line(cp, leftlen, " %c",
6342 (ep->
6343 use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6344 'N');
6345 ASC_PRT_NEXT();
6347 len = asc_prt_line(cp, leftlen, "\n");
6348 ASC_PRT_NEXT();
6350 len = asc_prt_line(cp, leftlen, " Start Motor: ");
6351 ASC_PRT_NEXT();
6352 for (i = 0; i <= ASC_MAX_TID; i++) {
6353 len = asc_prt_line(cp, leftlen, " %c",
6354 (ep->
6355 start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6356 'N');
6357 ASC_PRT_NEXT();
6359 len = asc_prt_line(cp, leftlen, "\n");
6360 ASC_PRT_NEXT();
6362 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6363 ASC_PRT_NEXT();
6364 for (i = 0; i <= ASC_MAX_TID; i++) {
6365 len = asc_prt_line(cp, leftlen, " %c",
6366 (ep->
6367 init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6368 'N');
6369 ASC_PRT_NEXT();
6371 len = asc_prt_line(cp, leftlen, "\n");
6372 ASC_PRT_NEXT();
6374 #ifdef CONFIG_ISA
6375 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
6376 len = asc_prt_line(cp, leftlen,
6377 " Host ISA DMA speed: %d MB/S\n",
6378 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
6379 ASC_PRT_NEXT();
6381 #endif /* CONFIG_ISA */
6383 return totlen;
6387 * asc_prt_adv_board_eeprom()
6389 * Print board EEPROM configuration.
6391 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6392 * cf. asc_prt_line().
6394 * Return the number of characters copied into 'cp'. No more than
6395 * 'cplen' characters will be copied to 'cp'.
6397 static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen)
6399 asc_board_t *boardp;
6400 ADV_DVC_VAR *adv_dvc_varp;
6401 int leftlen;
6402 int totlen;
6403 int len;
6404 int i;
6405 char *termstr;
6406 uchar serialstr[13];
6407 ADVEEP_3550_CONFIG *ep_3550 = NULL;
6408 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
6409 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
6410 ushort word;
6411 ushort *wordp;
6412 ushort sdtr_speed = 0;
6414 boardp = ASC_BOARDP(shost);
6415 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6416 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6417 ep_3550 = &boardp->eep_config.adv_3550_eep;
6418 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6419 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
6420 } else {
6421 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
6424 leftlen = cplen;
6425 totlen = len = 0;
6427 len = asc_prt_line(cp, leftlen,
6428 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n",
6429 shost->host_no);
6430 ASC_PRT_NEXT();
6432 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6433 wordp = &ep_3550->serial_number_word1;
6434 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6435 wordp = &ep_38C0800->serial_number_word1;
6436 } else {
6437 wordp = &ep_38C1600->serial_number_word1;
6440 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
6441 len =
6442 asc_prt_line(cp, leftlen, " Serial Number: %s\n",
6443 serialstr);
6444 ASC_PRT_NEXT();
6445 } else {
6446 len = asc_prt_line(cp, leftlen,
6447 " Serial Number Signature Not Present.\n");
6448 ASC_PRT_NEXT();
6451 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6452 len = asc_prt_line(cp, leftlen,
6453 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6454 ep_3550->adapter_scsi_id,
6455 ep_3550->max_host_qng, ep_3550->max_dvc_qng);
6456 ASC_PRT_NEXT();
6457 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6458 len = asc_prt_line(cp, leftlen,
6459 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6460 ep_38C0800->adapter_scsi_id,
6461 ep_38C0800->max_host_qng,
6462 ep_38C0800->max_dvc_qng);
6463 ASC_PRT_NEXT();
6464 } else {
6465 len = asc_prt_line(cp, leftlen,
6466 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
6467 ep_38C1600->adapter_scsi_id,
6468 ep_38C1600->max_host_qng,
6469 ep_38C1600->max_dvc_qng);
6470 ASC_PRT_NEXT();
6472 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6473 word = ep_3550->termination;
6474 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6475 word = ep_38C0800->termination_lvd;
6476 } else {
6477 word = ep_38C1600->termination_lvd;
6479 switch (word) {
6480 case 1:
6481 termstr = "Low Off/High Off";
6482 break;
6483 case 2:
6484 termstr = "Low Off/High On";
6485 break;
6486 case 3:
6487 termstr = "Low On/High On";
6488 break;
6489 default:
6490 case 0:
6491 termstr = "Automatic";
6492 break;
6495 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6496 len = asc_prt_line(cp, leftlen,
6497 " termination: %u (%s), bios_ctrl: 0x%x\n",
6498 ep_3550->termination, termstr,
6499 ep_3550->bios_ctrl);
6500 ASC_PRT_NEXT();
6501 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6502 len = asc_prt_line(cp, leftlen,
6503 " termination: %u (%s), bios_ctrl: 0x%x\n",
6504 ep_38C0800->termination_lvd, termstr,
6505 ep_38C0800->bios_ctrl);
6506 ASC_PRT_NEXT();
6507 } else {
6508 len = asc_prt_line(cp, leftlen,
6509 " termination: %u (%s), bios_ctrl: 0x%x\n",
6510 ep_38C1600->termination_lvd, termstr,
6511 ep_38C1600->bios_ctrl);
6512 ASC_PRT_NEXT();
6515 len = asc_prt_line(cp, leftlen, " Target ID: ");
6516 ASC_PRT_NEXT();
6517 for (i = 0; i <= ADV_MAX_TID; i++) {
6518 len = asc_prt_line(cp, leftlen, " %X", i);
6519 ASC_PRT_NEXT();
6521 len = asc_prt_line(cp, leftlen, "\n");
6522 ASC_PRT_NEXT();
6524 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6525 word = ep_3550->disc_enable;
6526 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6527 word = ep_38C0800->disc_enable;
6528 } else {
6529 word = ep_38C1600->disc_enable;
6531 len = asc_prt_line(cp, leftlen, " Disconnects: ");
6532 ASC_PRT_NEXT();
6533 for (i = 0; i <= ADV_MAX_TID; i++) {
6534 len = asc_prt_line(cp, leftlen, " %c",
6535 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6536 ASC_PRT_NEXT();
6538 len = asc_prt_line(cp, leftlen, "\n");
6539 ASC_PRT_NEXT();
6541 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6542 word = ep_3550->tagqng_able;
6543 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6544 word = ep_38C0800->tagqng_able;
6545 } else {
6546 word = ep_38C1600->tagqng_able;
6548 len = asc_prt_line(cp, leftlen, " Command Queuing: ");
6549 ASC_PRT_NEXT();
6550 for (i = 0; i <= ADV_MAX_TID; i++) {
6551 len = asc_prt_line(cp, leftlen, " %c",
6552 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6553 ASC_PRT_NEXT();
6555 len = asc_prt_line(cp, leftlen, "\n");
6556 ASC_PRT_NEXT();
6558 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6559 word = ep_3550->start_motor;
6560 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6561 word = ep_38C0800->start_motor;
6562 } else {
6563 word = ep_38C1600->start_motor;
6565 len = asc_prt_line(cp, leftlen, " Start Motor: ");
6566 ASC_PRT_NEXT();
6567 for (i = 0; i <= ADV_MAX_TID; i++) {
6568 len = asc_prt_line(cp, leftlen, " %c",
6569 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6570 ASC_PRT_NEXT();
6572 len = asc_prt_line(cp, leftlen, "\n");
6573 ASC_PRT_NEXT();
6575 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6576 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6577 ASC_PRT_NEXT();
6578 for (i = 0; i <= ADV_MAX_TID; i++) {
6579 len = asc_prt_line(cp, leftlen, " %c",
6580 (ep_3550->
6581 sdtr_able & ADV_TID_TO_TIDMASK(i)) ?
6582 'Y' : 'N');
6583 ASC_PRT_NEXT();
6585 len = asc_prt_line(cp, leftlen, "\n");
6586 ASC_PRT_NEXT();
6589 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6590 len = asc_prt_line(cp, leftlen, " Ultra Transfer: ");
6591 ASC_PRT_NEXT();
6592 for (i = 0; i <= ADV_MAX_TID; i++) {
6593 len = asc_prt_line(cp, leftlen, " %c",
6594 (ep_3550->
6595 ultra_able & ADV_TID_TO_TIDMASK(i))
6596 ? 'Y' : 'N');
6597 ASC_PRT_NEXT();
6599 len = asc_prt_line(cp, leftlen, "\n");
6600 ASC_PRT_NEXT();
6603 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
6604 word = ep_3550->wdtr_able;
6605 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
6606 word = ep_38C0800->wdtr_able;
6607 } else {
6608 word = ep_38C1600->wdtr_able;
6610 len = asc_prt_line(cp, leftlen, " Wide Transfer: ");
6611 ASC_PRT_NEXT();
6612 for (i = 0; i <= ADV_MAX_TID; i++) {
6613 len = asc_prt_line(cp, leftlen, " %c",
6614 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
6615 ASC_PRT_NEXT();
6617 len = asc_prt_line(cp, leftlen, "\n");
6618 ASC_PRT_NEXT();
6620 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
6621 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600) {
6622 len = asc_prt_line(cp, leftlen,
6623 " Synchronous Transfer Speed (Mhz):\n ");
6624 ASC_PRT_NEXT();
6625 for (i = 0; i <= ADV_MAX_TID; i++) {
6626 char *speed_str;
6628 if (i == 0) {
6629 sdtr_speed = adv_dvc_varp->sdtr_speed1;
6630 } else if (i == 4) {
6631 sdtr_speed = adv_dvc_varp->sdtr_speed2;
6632 } else if (i == 8) {
6633 sdtr_speed = adv_dvc_varp->sdtr_speed3;
6634 } else if (i == 12) {
6635 sdtr_speed = adv_dvc_varp->sdtr_speed4;
6637 switch (sdtr_speed & ADV_MAX_TID) {
6638 case 0:
6639 speed_str = "Off";
6640 break;
6641 case 1:
6642 speed_str = " 5";
6643 break;
6644 case 2:
6645 speed_str = " 10";
6646 break;
6647 case 3:
6648 speed_str = " 20";
6649 break;
6650 case 4:
6651 speed_str = " 40";
6652 break;
6653 case 5:
6654 speed_str = " 80";
6655 break;
6656 default:
6657 speed_str = "Unk";
6658 break;
6660 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
6661 ASC_PRT_NEXT();
6662 if (i == 7) {
6663 len = asc_prt_line(cp, leftlen, "\n ");
6664 ASC_PRT_NEXT();
6666 sdtr_speed >>= 4;
6668 len = asc_prt_line(cp, leftlen, "\n");
6669 ASC_PRT_NEXT();
6672 return totlen;
6676 * asc_prt_driver_conf()
6678 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6679 * cf. asc_prt_line().
6681 * Return the number of characters copied into 'cp'. No more than
6682 * 'cplen' characters will be copied to 'cp'.
6684 static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen)
6686 asc_board_t *boardp;
6687 int leftlen;
6688 int totlen;
6689 int len;
6690 int chip_scsi_id;
6692 boardp = ASC_BOARDP(shost);
6694 leftlen = cplen;
6695 totlen = len = 0;
6697 len = asc_prt_line(cp, leftlen,
6698 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
6699 shost->host_no);
6700 ASC_PRT_NEXT();
6702 len = asc_prt_line(cp, leftlen,
6703 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
6704 shost->host_busy, shost->last_reset, shost->max_id,
6705 shost->max_lun, shost->max_channel);
6706 ASC_PRT_NEXT();
6708 len = asc_prt_line(cp, leftlen,
6709 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
6710 shost->unique_id, shost->can_queue, shost->this_id,
6711 shost->sg_tablesize, shost->cmd_per_lun);
6712 ASC_PRT_NEXT();
6714 len = asc_prt_line(cp, leftlen,
6715 " unchecked_isa_dma %d, use_clustering %d\n",
6716 shost->unchecked_isa_dma, shost->use_clustering);
6717 ASC_PRT_NEXT();
6719 len = asc_prt_line(cp, leftlen,
6720 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
6721 boardp->flags, boardp->last_reset, jiffies,
6722 boardp->asc_n_io_port);
6723 ASC_PRT_NEXT();
6725 /* 'shost->n_io_port' may be truncated because it is only one byte. */
6726 len = asc_prt_line(cp, leftlen,
6727 " io_port 0x%x, n_io_port 0x%x\n",
6728 shost->io_port, shost->n_io_port);
6729 ASC_PRT_NEXT();
6731 if (ASC_NARROW_BOARD(boardp)) {
6732 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
6733 } else {
6734 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
6737 return totlen;
6741 * asc_prt_asc_board_info()
6743 * Print dynamic board configuration information.
6745 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6746 * cf. asc_prt_line().
6748 * Return the number of characters copied into 'cp'. No more than
6749 * 'cplen' characters will be copied to 'cp'.
6751 static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen)
6753 asc_board_t *boardp;
6754 int chip_scsi_id;
6755 int leftlen;
6756 int totlen;
6757 int len;
6758 ASC_DVC_VAR *v;
6759 ASC_DVC_CFG *c;
6760 int i;
6761 int renegotiate = 0;
6763 boardp = ASC_BOARDP(shost);
6764 v = &boardp->dvc_var.asc_dvc_var;
6765 c = &boardp->dvc_cfg.asc_dvc_cfg;
6766 chip_scsi_id = c->chip_scsi_id;
6768 leftlen = cplen;
6769 totlen = len = 0;
6771 len = asc_prt_line(cp, leftlen,
6772 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6773 shost->host_no);
6774 ASC_PRT_NEXT();
6776 len = asc_prt_line(cp, leftlen,
6777 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
6778 c->chip_version, c->lib_version, c->lib_serial_no,
6779 c->mcode_date);
6780 ASC_PRT_NEXT();
6782 len = asc_prt_line(cp, leftlen,
6783 " mcode_version 0x%x, err_code %u\n",
6784 c->mcode_version, v->err_code);
6785 ASC_PRT_NEXT();
6787 /* Current number of commands waiting for the host. */
6788 len = asc_prt_line(cp, leftlen,
6789 " Total Command Pending: %d\n", v->cur_total_qng);
6790 ASC_PRT_NEXT();
6792 len = asc_prt_line(cp, leftlen, " Command Queuing:");
6793 ASC_PRT_NEXT();
6794 for (i = 0; i <= ASC_MAX_TID; i++) {
6795 if ((chip_scsi_id == i) ||
6796 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6797 continue;
6799 len = asc_prt_line(cp, leftlen, " %X:%c",
6801 (v->
6802 use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ?
6803 'Y' : 'N');
6804 ASC_PRT_NEXT();
6806 len = asc_prt_line(cp, leftlen, "\n");
6807 ASC_PRT_NEXT();
6809 /* Current number of commands waiting for a device. */
6810 len = asc_prt_line(cp, leftlen, " Command Queue Pending:");
6811 ASC_PRT_NEXT();
6812 for (i = 0; i <= ASC_MAX_TID; i++) {
6813 if ((chip_scsi_id == i) ||
6814 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6815 continue;
6817 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
6818 ASC_PRT_NEXT();
6820 len = asc_prt_line(cp, leftlen, "\n");
6821 ASC_PRT_NEXT();
6823 /* Current limit on number of commands that can be sent to a device. */
6824 len = asc_prt_line(cp, leftlen, " Command Queue Limit:");
6825 ASC_PRT_NEXT();
6826 for (i = 0; i <= ASC_MAX_TID; i++) {
6827 if ((chip_scsi_id == i) ||
6828 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6829 continue;
6831 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
6832 ASC_PRT_NEXT();
6834 len = asc_prt_line(cp, leftlen, "\n");
6835 ASC_PRT_NEXT();
6837 /* Indicate whether the device has returned queue full status. */
6838 len = asc_prt_line(cp, leftlen, " Command Queue Full:");
6839 ASC_PRT_NEXT();
6840 for (i = 0; i <= ASC_MAX_TID; i++) {
6841 if ((chip_scsi_id == i) ||
6842 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6843 continue;
6845 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
6846 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
6847 i, boardp->queue_full_cnt[i]);
6848 } else {
6849 len = asc_prt_line(cp, leftlen, " %X:N", i);
6851 ASC_PRT_NEXT();
6853 len = asc_prt_line(cp, leftlen, "\n");
6854 ASC_PRT_NEXT();
6856 len = asc_prt_line(cp, leftlen, " Synchronous Transfer:");
6857 ASC_PRT_NEXT();
6858 for (i = 0; i <= ASC_MAX_TID; i++) {
6859 if ((chip_scsi_id == i) ||
6860 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6861 continue;
6863 len = asc_prt_line(cp, leftlen, " %X:%c",
6865 (v->
6866 sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6867 'N');
6868 ASC_PRT_NEXT();
6870 len = asc_prt_line(cp, leftlen, "\n");
6871 ASC_PRT_NEXT();
6873 for (i = 0; i <= ASC_MAX_TID; i++) {
6874 uchar syn_period_ix;
6876 if ((chip_scsi_id == i) ||
6877 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
6878 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
6879 continue;
6882 len = asc_prt_line(cp, leftlen, " %X:", i);
6883 ASC_PRT_NEXT();
6885 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0) {
6886 len = asc_prt_line(cp, leftlen, " Asynchronous");
6887 ASC_PRT_NEXT();
6888 } else {
6889 syn_period_ix =
6890 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index -
6893 len = asc_prt_line(cp, leftlen,
6894 " Transfer Period Factor: %d (%d.%d Mhz),",
6895 v->sdtr_period_tbl[syn_period_ix],
6896 250 /
6897 v->sdtr_period_tbl[syn_period_ix],
6898 ASC_TENTHS(250,
6900 sdtr_period_tbl
6901 [syn_period_ix]));
6902 ASC_PRT_NEXT();
6904 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
6905 boardp->
6906 sdtr_data[i] & ASC_SYN_MAX_OFFSET);
6907 ASC_PRT_NEXT();
6910 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
6911 len = asc_prt_line(cp, leftlen, "*\n");
6912 renegotiate = 1;
6913 } else {
6914 len = asc_prt_line(cp, leftlen, "\n");
6916 ASC_PRT_NEXT();
6919 if (renegotiate) {
6920 len = asc_prt_line(cp, leftlen,
6921 " * = Re-negotiation pending before next command.\n");
6922 ASC_PRT_NEXT();
6925 return totlen;
6929 * asc_prt_adv_board_info()
6931 * Print dynamic board configuration information.
6933 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
6934 * cf. asc_prt_line().
6936 * Return the number of characters copied into 'cp'. No more than
6937 * 'cplen' characters will be copied to 'cp'.
6939 static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen)
6941 asc_board_t *boardp;
6942 int leftlen;
6943 int totlen;
6944 int len;
6945 int i;
6946 ADV_DVC_VAR *v;
6947 ADV_DVC_CFG *c;
6948 AdvPortAddr iop_base;
6949 ushort chip_scsi_id;
6950 ushort lramword;
6951 uchar lrambyte;
6952 ushort tagqng_able;
6953 ushort sdtr_able, wdtr_able;
6954 ushort wdtr_done, sdtr_done;
6955 ushort period = 0;
6956 int renegotiate = 0;
6958 boardp = ASC_BOARDP(shost);
6959 v = &boardp->dvc_var.adv_dvc_var;
6960 c = &boardp->dvc_cfg.adv_dvc_cfg;
6961 iop_base = v->iop_base;
6962 chip_scsi_id = v->chip_scsi_id;
6964 leftlen = cplen;
6965 totlen = len = 0;
6967 len = asc_prt_line(cp, leftlen,
6968 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
6969 shost->host_no);
6970 ASC_PRT_NEXT();
6972 len = asc_prt_line(cp, leftlen,
6973 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
6974 v->iop_base,
6975 AdvReadWordRegister(iop_base,
6976 IOPW_SCSI_CFG1) & CABLE_DETECT,
6977 v->err_code);
6978 ASC_PRT_NEXT();
6980 len = asc_prt_line(cp, leftlen,
6981 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
6982 c->chip_version, c->lib_version, c->mcode_date,
6983 c->mcode_version);
6984 ASC_PRT_NEXT();
6986 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
6987 len = asc_prt_line(cp, leftlen, " Queuing Enabled:");
6988 ASC_PRT_NEXT();
6989 for (i = 0; i <= ADV_MAX_TID; i++) {
6990 if ((chip_scsi_id == i) ||
6991 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
6992 continue;
6995 len = asc_prt_line(cp, leftlen, " %X:%c",
6997 (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
6998 'N');
6999 ASC_PRT_NEXT();
7001 len = asc_prt_line(cp, leftlen, "\n");
7002 ASC_PRT_NEXT();
7004 len = asc_prt_line(cp, leftlen, " Queue Limit:");
7005 ASC_PRT_NEXT();
7006 for (i = 0; i <= ADV_MAX_TID; i++) {
7007 if ((chip_scsi_id == i) ||
7008 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7009 continue;
7012 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i,
7013 lrambyte);
7015 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
7016 ASC_PRT_NEXT();
7018 len = asc_prt_line(cp, leftlen, "\n");
7019 ASC_PRT_NEXT();
7021 len = asc_prt_line(cp, leftlen, " Command Pending:");
7022 ASC_PRT_NEXT();
7023 for (i = 0; i <= ADV_MAX_TID; i++) {
7024 if ((chip_scsi_id == i) ||
7025 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7026 continue;
7029 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i,
7030 lrambyte);
7032 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
7033 ASC_PRT_NEXT();
7035 len = asc_prt_line(cp, leftlen, "\n");
7036 ASC_PRT_NEXT();
7038 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
7039 len = asc_prt_line(cp, leftlen, " Wide Enabled:");
7040 ASC_PRT_NEXT();
7041 for (i = 0; i <= ADV_MAX_TID; i++) {
7042 if ((chip_scsi_id == i) ||
7043 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7044 continue;
7047 len = asc_prt_line(cp, leftlen, " %X:%c",
7049 (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7050 'N');
7051 ASC_PRT_NEXT();
7053 len = asc_prt_line(cp, leftlen, "\n");
7054 ASC_PRT_NEXT();
7056 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
7057 len = asc_prt_line(cp, leftlen, " Transfer Bit Width:");
7058 ASC_PRT_NEXT();
7059 for (i = 0; i <= ADV_MAX_TID; i++) {
7060 if ((chip_scsi_id == i) ||
7061 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7062 continue;
7065 AdvReadWordLram(iop_base,
7066 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7067 lramword);
7069 len = asc_prt_line(cp, leftlen, " %X:%d",
7070 i, (lramword & 0x8000) ? 16 : 8);
7071 ASC_PRT_NEXT();
7073 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
7074 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7075 len = asc_prt_line(cp, leftlen, "*");
7076 ASC_PRT_NEXT();
7077 renegotiate = 1;
7080 len = asc_prt_line(cp, leftlen, "\n");
7081 ASC_PRT_NEXT();
7083 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
7084 len = asc_prt_line(cp, leftlen, " Synchronous Enabled:");
7085 ASC_PRT_NEXT();
7086 for (i = 0; i <= ADV_MAX_TID; i++) {
7087 if ((chip_scsi_id == i) ||
7088 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
7089 continue;
7092 len = asc_prt_line(cp, leftlen, " %X:%c",
7094 (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' :
7095 'N');
7096 ASC_PRT_NEXT();
7098 len = asc_prt_line(cp, leftlen, "\n");
7099 ASC_PRT_NEXT();
7101 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
7102 for (i = 0; i <= ADV_MAX_TID; i++) {
7104 AdvReadWordLram(iop_base,
7105 ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
7106 lramword);
7107 lramword &= ~0x8000;
7109 if ((chip_scsi_id == i) ||
7110 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
7111 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
7112 continue;
7115 len = asc_prt_line(cp, leftlen, " %X:", i);
7116 ASC_PRT_NEXT();
7118 if ((lramword & 0x1F) == 0) { /* Check for REQ/ACK Offset 0. */
7119 len = asc_prt_line(cp, leftlen, " Asynchronous");
7120 ASC_PRT_NEXT();
7121 } else {
7122 len =
7123 asc_prt_line(cp, leftlen,
7124 " Transfer Period Factor: ");
7125 ASC_PRT_NEXT();
7127 if ((lramword & 0x1F00) == 0x1100) { /* 80 Mhz */
7128 len =
7129 asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
7130 ASC_PRT_NEXT();
7131 } else if ((lramword & 0x1F00) == 0x1000) { /* 40 Mhz */
7132 len =
7133 asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
7134 ASC_PRT_NEXT();
7135 } else { /* 20 Mhz or below. */
7137 period = (((lramword >> 8) * 25) + 50) / 4;
7139 if (period == 0) { /* Should never happen. */
7140 len =
7141 asc_prt_line(cp, leftlen,
7142 "%d (? Mhz), ");
7143 ASC_PRT_NEXT();
7144 } else {
7145 len = asc_prt_line(cp, leftlen,
7146 "%d (%d.%d Mhz),",
7147 period, 250 / period,
7148 ASC_TENTHS(250,
7149 period));
7150 ASC_PRT_NEXT();
7154 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
7155 lramword & 0x1F);
7156 ASC_PRT_NEXT();
7159 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
7160 len = asc_prt_line(cp, leftlen, "*\n");
7161 renegotiate = 1;
7162 } else {
7163 len = asc_prt_line(cp, leftlen, "\n");
7165 ASC_PRT_NEXT();
7168 if (renegotiate) {
7169 len = asc_prt_line(cp, leftlen,
7170 " * = Re-negotiation pending before next command.\n");
7171 ASC_PRT_NEXT();
7174 return totlen;
7178 * asc_proc_copy()
7180 * Copy proc information to a read buffer taking into account the current
7181 * read offset in the file and the remaining space in the read buffer.
7183 static int
7184 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
7185 char *cp, int cplen)
7187 int cnt = 0;
7189 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
7190 (unsigned)offset, (unsigned)advoffset, cplen);
7191 if (offset <= advoffset) {
7192 /* Read offset below current offset, copy everything. */
7193 cnt = min(cplen, leftlen);
7194 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7195 (ulong)curbuf, (ulong)cp, cnt);
7196 memcpy(curbuf, cp, cnt);
7197 } else if (offset < advoffset + cplen) {
7198 /* Read offset within current range, partial copy. */
7199 cnt = (advoffset + cplen) - offset;
7200 cp = (cp + cplen) - cnt;
7201 cnt = min(cnt, leftlen);
7202 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
7203 (ulong)curbuf, (ulong)cp, cnt);
7204 memcpy(curbuf, cp, cnt);
7206 return cnt;
7210 * asc_prt_line()
7212 * If 'cp' is NULL print to the console, otherwise print to a buffer.
7214 * Return 0 if printing to the console, otherwise return the number of
7215 * bytes written to the buffer.
7217 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
7218 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
7220 static int asc_prt_line(char *buf, int buflen, char *fmt, ...)
7222 va_list args;
7223 int ret;
7224 char s[ASC_PRTLINE_SIZE];
7226 va_start(args, fmt);
7227 ret = vsprintf(s, fmt, args);
7228 ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
7229 if (buf == NULL) {
7230 (void)printk(s);
7231 ret = 0;
7232 } else {
7233 ret = min(buflen, ret);
7234 memcpy(buf, s, ret);
7236 va_end(args);
7237 return ret;
7239 #endif /* CONFIG_PROC_FS */
7242 * --- Functions Required by the Asc Library
7246 * Delay for 'n' milliseconds. Don't use the 'jiffies'
7247 * global variable which is incremented once every 5 ms
7248 * from a timer interrupt, because this function may be
7249 * called when interrupts are disabled.
7251 static void DvcSleepMilliSecond(ADV_DCNT n)
7253 ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong)n);
7254 mdelay(n);
7258 * Currently and inline noop but leave as a placeholder.
7259 * Leave DvcEnterCritical() as a noop placeholder.
7261 static inline ulong DvcEnterCritical(void)
7263 return 0;
7267 * Critical sections are all protected by the board spinlock.
7268 * Leave DvcLeaveCritical() as a noop placeholder.
7270 static inline void DvcLeaveCritical(ulong flags)
7272 return;
7276 * void
7277 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7279 * Calling/Exit State:
7280 * none
7282 * Description:
7283 * Output an ASC_SCSI_Q structure to the chip
7285 static void
7286 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
7288 int i;
7290 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
7291 AscSetChipLramAddr(iop_base, s_addr);
7292 for (i = 0; i < 2 * words; i += 2) {
7293 if (i == 4 || i == 20) {
7294 continue;
7296 outpw(iop_base + IOP_RAM_DATA,
7297 ((ushort)outbuf[i + 1] << 8) | outbuf[i]);
7302 * void
7303 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7305 * Calling/Exit State:
7306 * none
7308 * Description:
7309 * Input an ASC_QDONE_INFO structure from the chip
7311 static void
7312 DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
7314 int i;
7315 ushort word;
7317 AscSetChipLramAddr(iop_base, s_addr);
7318 for (i = 0; i < 2 * words; i += 2) {
7319 if (i == 10) {
7320 continue;
7322 word = inpw(iop_base + IOP_RAM_DATA);
7323 inbuf[i] = word & 0xff;
7324 inbuf[i + 1] = (word >> 8) & 0xff;
7326 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
7330 * Read a PCI configuration byte.
7332 static uchar __devinit DvcReadPCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset)
7334 #ifdef CONFIG_PCI
7335 uchar byte_data;
7336 pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
7337 return byte_data;
7338 #else /* !defined(CONFIG_PCI) */
7339 return 0;
7340 #endif /* !defined(CONFIG_PCI) */
7344 * Write a PCI configuration byte.
7346 static void __devinit
7347 DvcWritePCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset, uchar byte_data)
7349 #ifdef CONFIG_PCI
7350 pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
7351 #endif /* CONFIG_PCI */
7355 * Return the BIOS address of the adapter at the specified
7356 * I/O port and with the specified bus type.
7358 static ushort __devinit AscGetChipBiosAddress(PortAddr iop_base, ushort bus_type)
7360 ushort cfg_lsw;
7361 ushort bios_addr;
7364 * The PCI BIOS is re-located by the motherboard BIOS. Because
7365 * of this the driver can not determine where a PCI BIOS is
7366 * loaded and executes.
7368 if (bus_type & ASC_IS_PCI) {
7369 return (0);
7371 #ifdef CONFIG_ISA
7372 if ((bus_type & ASC_IS_EISA) != 0) {
7373 cfg_lsw = AscGetEisaChipCfg(iop_base);
7374 cfg_lsw &= 0x000F;
7375 bios_addr = (ushort)(ASC_BIOS_MIN_ADDR +
7376 (cfg_lsw * ASC_BIOS_BANK_SIZE));
7377 return (bios_addr);
7378 } /* if */
7379 #endif /* CONFIG_ISA */
7381 cfg_lsw = AscGetChipCfgLsw(iop_base);
7384 * ISA PnP uses the top bit as the 32K BIOS flag
7386 if (bus_type == ASC_IS_ISAPNP) {
7387 cfg_lsw &= 0x7FFF;
7389 /* if */
7390 bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
7391 ASC_BIOS_MIN_ADDR);
7392 return (bios_addr);
7396 * --- Functions Required by the Adv Library
7400 * DvcGetPhyAddr()
7402 * Return the physical address of 'vaddr' and set '*lenp' to the
7403 * number of physically contiguous bytes that follow 'vaddr'.
7404 * 'flag' indicates the type of structure whose physical address
7405 * is being translated.
7407 * Note: Because Linux currently doesn't page the kernel and all
7408 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
7410 ADV_PADDR
7411 DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
7412 uchar *vaddr, ADV_SDCNT *lenp, int flag)
7414 ADV_PADDR paddr;
7416 paddr = virt_to_bus(vaddr);
7418 ASC_DBG4(4,
7419 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
7420 (ulong)vaddr, (ulong)lenp, (ulong)*((ulong *)lenp),
7421 (ulong)paddr);
7423 return paddr;
7427 * Read a PCI configuration byte.
7429 static uchar __devinit DvcAdvReadPCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset)
7431 #ifdef CONFIG_PCI
7432 uchar byte_data;
7433 pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
7434 return byte_data;
7435 #else /* CONFIG_PCI */
7436 return 0;
7437 #endif /* CONFIG_PCI */
7441 * Write a PCI configuration byte.
7443 static void __devinit
7444 DvcAdvWritePCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset, uchar byte_data)
7446 #ifdef CONFIG_PCI
7447 pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
7448 #else /* CONFIG_PCI */
7449 return;
7450 #endif /* CONFIG_PCI */
7454 * --- Tracing and Debugging Functions
7457 #ifdef ADVANSYS_STATS
7458 #ifdef CONFIG_PROC_FS
7460 * asc_prt_board_stats()
7462 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7463 * cf. asc_prt_line().
7465 * Return the number of characters copied into 'cp'. No more than
7466 * 'cplen' characters will be copied to 'cp'.
7468 static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen)
7470 int leftlen;
7471 int totlen;
7472 int len;
7473 struct asc_stats *s;
7474 asc_board_t *boardp;
7476 leftlen = cplen;
7477 totlen = len = 0;
7479 boardp = ASC_BOARDP(shost);
7480 s = &boardp->asc_stats;
7482 len = asc_prt_line(cp, leftlen,
7483 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n",
7484 shost->host_no);
7485 ASC_PRT_NEXT();
7487 len = asc_prt_line(cp, leftlen,
7488 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
7489 s->queuecommand, s->reset, s->biosparam,
7490 s->interrupt);
7491 ASC_PRT_NEXT();
7493 len = asc_prt_line(cp, leftlen,
7494 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
7495 s->callback, s->done, s->build_error,
7496 s->adv_build_noreq, s->adv_build_nosg);
7497 ASC_PRT_NEXT();
7499 len = asc_prt_line(cp, leftlen,
7500 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
7501 s->exe_noerror, s->exe_busy, s->exe_error,
7502 s->exe_unknown);
7503 ASC_PRT_NEXT();
7506 * Display data transfer statistics.
7508 if (s->cont_cnt > 0) {
7509 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
7510 ASC_PRT_NEXT();
7512 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
7513 s->cont_xfer / 2,
7514 ASC_TENTHS(s->cont_xfer, 2));
7515 ASC_PRT_NEXT();
7517 /* Contiguous transfer average size */
7518 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
7519 (s->cont_xfer / 2) / s->cont_cnt,
7520 ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt));
7521 ASC_PRT_NEXT();
7524 if (s->sg_cnt > 0) {
7526 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
7527 s->sg_cnt, s->sg_elem);
7528 ASC_PRT_NEXT();
7530 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
7531 s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2));
7532 ASC_PRT_NEXT();
7534 /* Scatter gather transfer statistics */
7535 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
7536 s->sg_elem / s->sg_cnt,
7537 ASC_TENTHS(s->sg_elem, s->sg_cnt));
7538 ASC_PRT_NEXT();
7540 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
7541 (s->sg_xfer / 2) / s->sg_elem,
7542 ASC_TENTHS((s->sg_xfer / 2), s->sg_elem));
7543 ASC_PRT_NEXT();
7545 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
7546 (s->sg_xfer / 2) / s->sg_cnt,
7547 ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt));
7548 ASC_PRT_NEXT();
7552 * Display request queuing statistics.
7554 len = asc_prt_line(cp, leftlen,
7555 " Active and Waiting Request Queues (Time Unit: %d HZ):\n",
7556 HZ);
7557 ASC_PRT_NEXT();
7559 return totlen;
7563 * asc_prt_target_stats()
7565 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7566 * cf. asc_prt_line().
7568 * This is separated from asc_prt_board_stats because a full set
7569 * of targets will overflow ASC_PRTBUF_SIZE.
7571 * Return the number of characters copied into 'cp'. No more than
7572 * 'cplen' characters will be copied to 'cp'.
7574 static int
7575 asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen)
7577 int leftlen;
7578 int totlen;
7579 int len;
7580 struct asc_stats *s;
7581 ushort chip_scsi_id;
7582 asc_board_t *boardp;
7583 asc_queue_t *active;
7584 asc_queue_t *waiting;
7586 leftlen = cplen;
7587 totlen = len = 0;
7589 boardp = ASC_BOARDP(shost);
7590 s = &boardp->asc_stats;
7592 active = &ASC_BOARDP(shost)->active;
7593 waiting = &ASC_BOARDP(shost)->waiting;
7595 if (ASC_NARROW_BOARD(boardp)) {
7596 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7597 } else {
7598 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7601 if ((chip_scsi_id == tgt_id) ||
7602 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
7603 return 0;
7606 do {
7607 if (active->q_tot_cnt[tgt_id] > 0
7608 || waiting->q_tot_cnt[tgt_id] > 0) {
7609 len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
7610 ASC_PRT_NEXT();
7612 len = asc_prt_line(cp, leftlen,
7613 " active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
7614 active->q_cur_cnt[tgt_id],
7615 active->q_max_cnt[tgt_id],
7616 active->q_tot_cnt[tgt_id],
7617 active->q_min_tim[tgt_id],
7618 active->q_max_tim[tgt_id],
7619 (active->q_tot_cnt[tgt_id] ==
7620 0) ? 0 : (active->
7621 q_tot_tim[tgt_id] /
7622 active->
7623 q_tot_cnt[tgt_id]),
7624 (active->q_tot_cnt[tgt_id] ==
7625 0) ? 0 : ASC_TENTHS(active->
7626 q_tot_tim
7627 [tgt_id],
7628 active->
7629 q_tot_cnt
7630 [tgt_id]));
7631 ASC_PRT_NEXT();
7633 len = asc_prt_line(cp, leftlen,
7634 " waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
7635 waiting->q_cur_cnt[tgt_id],
7636 waiting->q_max_cnt[tgt_id],
7637 waiting->q_tot_cnt[tgt_id],
7638 waiting->q_min_tim[tgt_id],
7639 waiting->q_max_tim[tgt_id],
7640 (waiting->q_tot_cnt[tgt_id] ==
7641 0) ? 0 : (waiting->
7642 q_tot_tim[tgt_id] /
7643 waiting->
7644 q_tot_cnt[tgt_id]),
7645 (waiting->q_tot_cnt[tgt_id] ==
7646 0) ? 0 : ASC_TENTHS(waiting->
7647 q_tot_tim
7648 [tgt_id],
7649 waiting->
7650 q_tot_cnt
7651 [tgt_id]));
7652 ASC_PRT_NEXT();
7654 } while (0);
7656 return totlen;
7658 #endif /* CONFIG_PROC_FS */
7659 #endif /* ADVANSYS_STATS */
7661 #ifdef ADVANSYS_DEBUG
7663 * asc_prt_scsi_host()
7665 static void asc_prt_scsi_host(struct Scsi_Host *s)
7667 asc_board_t *boardp;
7669 boardp = ASC_BOARDP(s);
7671 printk("Scsi_Host at addr 0x%lx\n", (ulong)s);
7672 printk(" host_busy %u, host_no %d, last_reset %d,\n",
7673 s->host_busy, s->host_no, (unsigned)s->last_reset);
7675 printk(" base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
7676 (ulong)s->base, (ulong)s->io_port, s->n_io_port, s->irq);
7678 printk(" dma_channel %d, this_id %d, can_queue %d,\n",
7679 s->dma_channel, s->this_id, s->can_queue);
7681 printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
7682 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
7684 if (ASC_NARROW_BOARD(boardp)) {
7685 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
7686 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
7687 } else {
7688 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
7689 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
7694 * asc_prt_scsi_cmnd()
7696 static void asc_prt_scsi_cmnd(struct scsi_cmnd *s)
7698 printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s);
7700 printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
7701 (ulong)s->device->host, (ulong)s->device, s->device->id,
7702 s->device->lun, s->device->channel);
7704 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
7706 printk("sc_data_direction %u, resid %d\n",
7707 s->sc_data_direction, s->resid);
7709 printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len);
7711 printk(" serial_number 0x%x, retries %d, allowed %d\n",
7712 (unsigned)s->serial_number, s->retries, s->allowed);
7714 printk(" timeout_per_command %d\n", s->timeout_per_command);
7716 printk
7717 (" scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
7718 (ulong)s->scsi_done, (ulong)s->done, (ulong)s->host_scribble,
7719 s->result);
7721 printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid);
7725 * asc_prt_asc_dvc_var()
7727 static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
7729 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h);
7731 printk
7732 (" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n",
7733 h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
7735 printk
7736 (" bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n",
7737 h->bus_type, (ulong)h->isr_callback, (ulong)h->exe_callback,
7738 (unsigned)h->init_sdtr);
7740 printk
7741 (" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n",
7742 (unsigned)h->sdtr_done, (unsigned)h->use_tagged_qng,
7743 (unsigned)h->unit_not_ready, (unsigned)h->chip_no);
7745 printk
7746 (" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n",
7747 (unsigned)h->queue_full_or_busy, (unsigned)h->start_motor,
7748 (unsigned)h->scsi_reset_wait);
7750 printk
7751 (" is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n",
7752 (unsigned)h->is_in_int, (unsigned)h->max_total_qng,
7753 (unsigned)h->cur_total_qng, (unsigned)h->in_critical_cnt);
7755 printk
7756 (" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n",
7757 (unsigned)h->last_q_shortage, (unsigned)h->init_state,
7758 (unsigned)h->no_scam, (unsigned)h->pci_fix_asyn_xfer);
7760 printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no);
7764 * asc_prt_asc_dvc_cfg()
7766 static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
7768 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h);
7770 printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
7771 h->can_tagged_qng, h->cmd_qng_enabled);
7772 printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n",
7773 h->disc_enable, h->sdtr_enable);
7775 printk
7776 (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
7777 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
7778 h->chip_version);
7780 printk
7781 (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
7782 to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
7783 h->mcode_date);
7785 printk(" mcode_version %d, overrun_buf 0x%lx\n",
7786 h->mcode_version, (ulong)h->overrun_buf);
7790 * asc_prt_asc_scsi_q()
7792 static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
7794 ASC_SG_HEAD *sgp;
7795 int i;
7797 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q);
7799 printk
7800 (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
7801 q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr,
7802 q->q2.tag_code);
7804 printk
7805 (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7806 (ulong)le32_to_cpu(q->q1.data_addr),
7807 (ulong)le32_to_cpu(q->q1.data_cnt),
7808 (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
7810 printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
7811 (ulong)q->cdbptr, q->q2.cdb_len,
7812 (ulong)q->sg_head, q->q1.sg_queue_cnt);
7814 if (q->sg_head) {
7815 sgp = q->sg_head;
7816 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp);
7817 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt,
7818 sgp->queue_cnt);
7819 for (i = 0; i < sgp->entry_cnt; i++) {
7820 printk(" [%u]: addr 0x%lx, bytes %lu\n",
7821 i, (ulong)le32_to_cpu(sgp->sg_list[i].addr),
7822 (ulong)le32_to_cpu(sgp->sg_list[i].bytes));
7829 * asc_prt_asc_qdone_info()
7831 static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
7833 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q);
7834 printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
7835 (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
7836 q->d2.tag_code);
7837 printk
7838 (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
7839 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
7843 * asc_prt_adv_dvc_var()
7845 * Display an ADV_DVC_VAR structure.
7847 static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
7849 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h);
7851 printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
7852 (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able);
7854 printk(" isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
7855 (ulong)h->isr_callback, (unsigned)h->sdtr_able,
7856 (unsigned)h->wdtr_able);
7858 printk(" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
7859 (unsigned)h->start_motor,
7860 (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no);
7862 printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
7863 (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng,
7864 (ulong)h->carr_freelist);
7866 printk(" icq_sp 0x%lx, irq_sp 0x%lx\n",
7867 (ulong)h->icq_sp, (ulong)h->irq_sp);
7869 printk(" no_scam 0x%x, tagqng_able 0x%x\n",
7870 (unsigned)h->no_scam, (unsigned)h->tagqng_able);
7872 printk(" chip_scsi_id 0x%x, cfg 0x%lx\n",
7873 (unsigned)h->chip_scsi_id, (ulong)h->cfg);
7877 * asc_prt_adv_dvc_cfg()
7879 * Display an ADV_DVC_CFG structure.
7881 static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
7883 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h);
7885 printk(" disc_enable 0x%x, termination 0x%x\n",
7886 h->disc_enable, h->termination);
7888 printk(" chip_version 0x%x, mcode_date 0x%x\n",
7889 h->chip_version, h->mcode_date);
7891 printk(" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
7892 h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
7894 printk(" control_flag 0x%x, pci_slot_info 0x%x\n",
7895 h->control_flag, h->pci_slot_info);
7899 * asc_prt_adv_scsi_req_q()
7901 * Display an ADV_SCSI_REQ_Q structure.
7903 static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
7905 int sg_blk_cnt;
7906 struct asc_sg_block *sg_ptr;
7908 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q);
7910 printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
7911 q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag);
7913 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
7914 q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr);
7916 printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
7917 (ulong)le32_to_cpu(q->data_cnt),
7918 (ulong)le32_to_cpu(q->sense_addr), q->sense_len);
7920 printk
7921 (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
7922 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
7924 printk(" sg_working_ix 0x%x, target_cmd %u\n",
7925 q->sg_working_ix, q->target_cmd);
7927 printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
7928 (ulong)le32_to_cpu(q->scsiq_rptr),
7929 (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr);
7931 /* Display the request's ADV_SG_BLOCK structures. */
7932 if (q->sg_list_ptr != NULL) {
7933 sg_blk_cnt = 0;
7934 while (1) {
7936 * 'sg_ptr' is a physical address. Convert it to a virtual
7937 * address by indexing 'sg_blk_cnt' into the virtual address
7938 * array 'sg_list_ptr'.
7940 * XXX - Assumes all SG physical blocks are virtually contiguous.
7942 sg_ptr =
7943 &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]);
7944 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
7945 if (sg_ptr->sg_ptr == 0) {
7946 break;
7948 sg_blk_cnt++;
7954 * asc_prt_adv_sgblock()
7956 * Display an ADV_SG_BLOCK structure.
7958 static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
7960 int i;
7962 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
7963 (ulong)b, sgblockno);
7964 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
7965 b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr));
7966 ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
7967 if (b->sg_ptr != 0) {
7968 ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
7970 for (i = 0; i < b->sg_cnt; i++) {
7971 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
7972 i, (ulong)b->sg_list[i].sg_addr,
7973 (ulong)b->sg_list[i].sg_count);
7978 * asc_prt_hex()
7980 * Print hexadecimal output in 4 byte groupings 32 bytes
7981 * or 8 double-words per line.
7983 static void asc_prt_hex(char *f, uchar *s, int l)
7985 int i;
7986 int j;
7987 int k;
7988 int m;
7990 printk("%s: (%d bytes)\n", f, l);
7992 for (i = 0; i < l; i += 32) {
7994 /* Display a maximum of 8 double-words per line. */
7995 if ((k = (l - i) / 4) >= 8) {
7996 k = 8;
7997 m = 0;
7998 } else {
7999 m = (l - i) % 4;
8002 for (j = 0; j < k; j++) {
8003 printk(" %2.2X%2.2X%2.2X%2.2X",
8004 (unsigned)s[i + (j * 4)],
8005 (unsigned)s[i + (j * 4) + 1],
8006 (unsigned)s[i + (j * 4) + 2],
8007 (unsigned)s[i + (j * 4) + 3]);
8010 switch (m) {
8011 case 0:
8012 default:
8013 break;
8014 case 1:
8015 printk(" %2.2X", (unsigned)s[i + (j * 4)]);
8016 break;
8017 case 2:
8018 printk(" %2.2X%2.2X",
8019 (unsigned)s[i + (j * 4)],
8020 (unsigned)s[i + (j * 4) + 1]);
8021 break;
8022 case 3:
8023 printk(" %2.2X%2.2X%2.2X",
8024 (unsigned)s[i + (j * 4) + 1],
8025 (unsigned)s[i + (j * 4) + 2],
8026 (unsigned)s[i + (j * 4) + 3]);
8027 break;
8030 printk("\n");
8033 #endif /* ADVANSYS_DEBUG */
8036 * --- Asc Library Functions
8039 static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base)
8041 PortAddr eisa_cfg_iop;
8043 eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8044 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
8045 return (inpw(eisa_cfg_iop));
8048 static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id)
8050 ushort cfg_lsw;
8052 if (AscGetChipScsiID(iop_base) == new_host_id) {
8053 return (new_host_id);
8055 cfg_lsw = AscGetChipCfgLsw(iop_base);
8056 cfg_lsw &= 0xF8FF;
8057 cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8);
8058 AscSetChipCfgLsw(iop_base, cfg_lsw);
8059 return (AscGetChipScsiID(iop_base));
8062 static uchar __devinit AscGetChipScsiCtrl(PortAddr iop_base)
8064 uchar sc;
8066 AscSetBank(iop_base, 1);
8067 sc = inp(iop_base + IOP_REG_SC);
8068 AscSetBank(iop_base, 0);
8069 return (sc);
8072 static uchar __devinit AscGetChipVersion(PortAddr iop_base, ushort bus_type)
8074 if ((bus_type & ASC_IS_EISA) != 0) {
8075 PortAddr eisa_iop;
8076 uchar revision;
8077 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
8078 (PortAddr) ASC_EISA_REV_IOP_MASK;
8079 revision = inp(eisa_iop);
8080 return ((uchar)((ASC_CHIP_MIN_VER_EISA - 1) + revision));
8082 return (AscGetChipVerNo(iop_base));
8085 static ushort __devinit AscGetChipBusType(PortAddr iop_base)
8087 ushort chip_ver;
8089 chip_ver = AscGetChipVerNo(iop_base);
8090 if ((chip_ver >= ASC_CHIP_MIN_VER_VL)
8091 && (chip_ver <= ASC_CHIP_MAX_VER_VL)
8093 if (((iop_base & 0x0C30) == 0x0C30)
8094 || ((iop_base & 0x0C50) == 0x0C50)
8096 return (ASC_IS_EISA);
8098 return (ASC_IS_VL);
8100 if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
8101 (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
8102 if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
8103 return (ASC_IS_ISAPNP);
8105 return (ASC_IS_ISA);
8106 } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
8107 (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
8108 return (ASC_IS_PCI);
8110 return (0);
8113 static ASC_DCNT
8114 AscLoadMicroCode(PortAddr iop_base,
8115 ushort s_addr, uchar *mcode_buf, ushort mcode_size)
8117 ASC_DCNT chksum;
8118 ushort mcode_word_size;
8119 ushort mcode_chksum;
8121 /* Write the microcode buffer starting at LRAM address 0. */
8122 mcode_word_size = (ushort)(mcode_size >> 1);
8123 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
8124 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
8126 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
8127 ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum);
8128 mcode_chksum = (ushort)AscMemSumLramWord(iop_base,
8129 (ushort)ASC_CODE_SEC_BEG,
8130 (ushort)((mcode_size -
8131 s_addr - (ushort)
8132 ASC_CODE_SEC_BEG) /
8133 2));
8134 ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
8135 (ulong)mcode_chksum);
8136 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
8137 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
8138 return (chksum);
8141 static int AscFindSignature(PortAddr iop_base)
8143 ushort sig_word;
8145 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
8146 iop_base, AscGetChipSignatureByte(iop_base));
8147 if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) {
8148 ASC_DBG2(1,
8149 "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
8150 iop_base, AscGetChipSignatureWord(iop_base));
8151 sig_word = AscGetChipSignatureWord(iop_base);
8152 if ((sig_word == (ushort)ASC_1000_ID0W) ||
8153 (sig_word == (ushort)ASC_1000_ID0W_FIX)) {
8154 return (1);
8157 return (0);
8160 static void __devinit AscToggleIRQAct(PortAddr iop_base)
8162 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
8163 AscSetChipStatus(iop_base, 0);
8164 return;
8167 static uchar __devinit AscGetChipIRQ(PortAddr iop_base, ushort bus_type)
8169 ushort cfg_lsw;
8170 uchar chip_irq;
8172 if ((bus_type & ASC_IS_EISA) != 0) {
8173 cfg_lsw = AscGetEisaChipCfg(iop_base);
8174 chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10);
8175 if ((chip_irq == 13) || (chip_irq > 15)) {
8176 return (0);
8178 return (chip_irq);
8180 if ((bus_type & ASC_IS_VL) != 0) {
8181 cfg_lsw = AscGetChipCfgLsw(iop_base);
8182 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07));
8183 if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) {
8184 return (0);
8186 return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1)));
8188 cfg_lsw = AscGetChipCfgLsw(iop_base);
8189 chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03));
8190 if (chip_irq == 3)
8191 chip_irq += (uchar)2;
8192 return ((uchar)(chip_irq + ASC_MIN_IRQ_NO));
8195 static uchar __devinit
8196 AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type)
8198 ushort cfg_lsw;
8200 if ((bus_type & ASC_IS_VL) != 0) {
8201 if (irq_no != 0) {
8202 if ((irq_no < ASC_MIN_IRQ_NO)
8203 || (irq_no > ASC_MAX_IRQ_NO)) {
8204 irq_no = 0;
8205 } else {
8206 irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1));
8209 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3);
8210 cfg_lsw |= (ushort)0x0010;
8211 AscSetChipCfgLsw(iop_base, cfg_lsw);
8212 AscToggleIRQAct(iop_base);
8213 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0);
8214 cfg_lsw |= (ushort)((irq_no & 0x07) << 2);
8215 AscSetChipCfgLsw(iop_base, cfg_lsw);
8216 AscToggleIRQAct(iop_base);
8217 return (AscGetChipIRQ(iop_base, bus_type));
8219 if ((bus_type & (ASC_IS_ISA)) != 0) {
8220 if (irq_no == 15)
8221 irq_no -= (uchar)2;
8222 irq_no -= (uchar)ASC_MIN_IRQ_NO;
8223 cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3);
8224 cfg_lsw |= (ushort)((irq_no & 0x03) << 2);
8225 AscSetChipCfgLsw(iop_base, cfg_lsw);
8226 return (AscGetChipIRQ(iop_base, bus_type));
8228 return (0);
8231 #ifdef CONFIG_ISA
8232 static void __devinit AscEnableIsaDma(uchar dma_channel)
8234 if (dma_channel < 4) {
8235 outp(0x000B, (ushort)(0xC0 | dma_channel));
8236 outp(0x000A, dma_channel);
8237 } else if (dma_channel < 8) {
8238 outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4)));
8239 outp(0x00D4, (ushort)(dma_channel - 4));
8241 return;
8243 #endif /* CONFIG_ISA */
8245 static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc)
8247 EXT_MSG ext_msg;
8248 EXT_MSG out_msg;
8249 ushort halt_q_addr;
8250 int sdtr_accept;
8251 ushort int_halt_code;
8252 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8253 ASC_SCSI_BIT_ID_TYPE target_id;
8254 PortAddr iop_base;
8255 uchar tag_code;
8256 uchar q_status;
8257 uchar halt_qp;
8258 uchar sdtr_data;
8259 uchar target_ix;
8260 uchar q_cntl, tid_no;
8261 uchar cur_dvc_qng;
8262 uchar asyn_sdtr;
8263 uchar scsi_status;
8264 asc_board_t *boardp;
8266 ASC_ASSERT(asc_dvc->drv_ptr != NULL);
8267 boardp = asc_dvc->drv_ptr;
8269 iop_base = asc_dvc->iop_base;
8270 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
8272 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
8273 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
8274 target_ix = AscReadLramByte(iop_base,
8275 (ushort)(halt_q_addr +
8276 (ushort)ASC_SCSIQ_B_TARGET_IX));
8277 q_cntl =
8278 AscReadLramByte(iop_base,
8279 (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8280 tid_no = ASC_TIX_TO_TID(target_ix);
8281 target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no);
8282 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8283 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
8284 } else {
8285 asyn_sdtr = 0;
8287 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
8288 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8289 AscSetChipSDTR(iop_base, 0, tid_no);
8290 boardp->sdtr_data[tid_no] = 0;
8292 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8293 return (0);
8294 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
8295 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
8296 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8297 boardp->sdtr_data[tid_no] = asyn_sdtr;
8299 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8300 return (0);
8301 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
8303 AscMemWordCopyPtrFromLram(iop_base,
8304 ASCV_MSGIN_BEG,
8305 (uchar *)&ext_msg,
8306 sizeof(EXT_MSG) >> 1);
8308 if (ext_msg.msg_type == MS_EXTEND &&
8309 ext_msg.msg_req == MS_SDTR_CODE &&
8310 ext_msg.msg_len == MS_SDTR_LEN) {
8311 sdtr_accept = TRUE;
8312 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
8314 sdtr_accept = FALSE;
8315 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
8317 if ((ext_msg.xfer_period <
8318 asc_dvc->sdtr_period_tbl[asc_dvc->
8319 host_init_sdtr_index])
8320 || (ext_msg.xfer_period >
8321 asc_dvc->sdtr_period_tbl[asc_dvc->
8322 max_sdtr_index])) {
8323 sdtr_accept = FALSE;
8324 ext_msg.xfer_period =
8325 asc_dvc->sdtr_period_tbl[asc_dvc->
8326 host_init_sdtr_index];
8328 if (sdtr_accept) {
8329 sdtr_data =
8330 AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
8331 ext_msg.req_ack_offset);
8332 if ((sdtr_data == 0xFF)) {
8334 q_cntl |= QC_MSG_OUT;
8335 asc_dvc->init_sdtr &= ~target_id;
8336 asc_dvc->sdtr_done &= ~target_id;
8337 AscSetChipSDTR(iop_base, asyn_sdtr,
8338 tid_no);
8339 boardp->sdtr_data[tid_no] = asyn_sdtr;
8342 if (ext_msg.req_ack_offset == 0) {
8344 q_cntl &= ~QC_MSG_OUT;
8345 asc_dvc->init_sdtr &= ~target_id;
8346 asc_dvc->sdtr_done &= ~target_id;
8347 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8348 } else {
8349 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
8351 q_cntl &= ~QC_MSG_OUT;
8352 asc_dvc->sdtr_done |= target_id;
8353 asc_dvc->init_sdtr |= target_id;
8354 asc_dvc->pci_fix_asyn_xfer &=
8355 ~target_id;
8356 sdtr_data =
8357 AscCalSDTRData(asc_dvc,
8358 ext_msg.xfer_period,
8359 ext_msg.
8360 req_ack_offset);
8361 AscSetChipSDTR(iop_base, sdtr_data,
8362 tid_no);
8363 boardp->sdtr_data[tid_no] = sdtr_data;
8364 } else {
8366 q_cntl |= QC_MSG_OUT;
8367 AscMsgOutSDTR(asc_dvc,
8368 ext_msg.xfer_period,
8369 ext_msg.req_ack_offset);
8370 asc_dvc->pci_fix_asyn_xfer &=
8371 ~target_id;
8372 sdtr_data =
8373 AscCalSDTRData(asc_dvc,
8374 ext_msg.xfer_period,
8375 ext_msg.
8376 req_ack_offset);
8377 AscSetChipSDTR(iop_base, sdtr_data,
8378 tid_no);
8379 boardp->sdtr_data[tid_no] = sdtr_data;
8380 asc_dvc->sdtr_done |= target_id;
8381 asc_dvc->init_sdtr |= target_id;
8385 AscWriteLramByte(iop_base,
8386 (ushort)(halt_q_addr +
8387 (ushort)ASC_SCSIQ_B_CNTL),
8388 q_cntl);
8389 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8390 return (0);
8391 } else if (ext_msg.msg_type == MS_EXTEND &&
8392 ext_msg.msg_req == MS_WDTR_CODE &&
8393 ext_msg.msg_len == MS_WDTR_LEN) {
8395 ext_msg.wdtr_width = 0;
8396 AscMemWordCopyPtrToLram(iop_base,
8397 ASCV_MSGOUT_BEG,
8398 (uchar *)&ext_msg,
8399 sizeof(EXT_MSG) >> 1);
8400 q_cntl |= QC_MSG_OUT;
8401 AscWriteLramByte(iop_base,
8402 (ushort)(halt_q_addr +
8403 (ushort)ASC_SCSIQ_B_CNTL),
8404 q_cntl);
8405 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8406 return (0);
8407 } else {
8409 ext_msg.msg_type = MESSAGE_REJECT;
8410 AscMemWordCopyPtrToLram(iop_base,
8411 ASCV_MSGOUT_BEG,
8412 (uchar *)&ext_msg,
8413 sizeof(EXT_MSG) >> 1);
8414 q_cntl |= QC_MSG_OUT;
8415 AscWriteLramByte(iop_base,
8416 (ushort)(halt_q_addr +
8417 (ushort)ASC_SCSIQ_B_CNTL),
8418 q_cntl);
8419 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8420 return (0);
8422 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
8424 q_cntl |= QC_REQ_SENSE;
8426 if ((asc_dvc->init_sdtr & target_id) != 0) {
8428 asc_dvc->sdtr_done &= ~target_id;
8430 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
8431 q_cntl |= QC_MSG_OUT;
8432 AscMsgOutSDTR(asc_dvc,
8433 asc_dvc->
8434 sdtr_period_tbl[(sdtr_data >> 4) &
8435 (uchar)(asc_dvc->
8436 max_sdtr_index -
8437 1)],
8438 (uchar)(sdtr_data & (uchar)
8439 ASC_SYN_MAX_OFFSET));
8442 AscWriteLramByte(iop_base,
8443 (ushort)(halt_q_addr +
8444 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8446 tag_code = AscReadLramByte(iop_base,
8447 (ushort)(halt_q_addr + (ushort)
8448 ASC_SCSIQ_B_TAG_CODE));
8449 tag_code &= 0xDC;
8450 if ((asc_dvc->pci_fix_asyn_xfer & target_id)
8451 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
8454 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
8455 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
8458 AscWriteLramByte(iop_base,
8459 (ushort)(halt_q_addr +
8460 (ushort)ASC_SCSIQ_B_TAG_CODE),
8461 tag_code);
8463 q_status = AscReadLramByte(iop_base,
8464 (ushort)(halt_q_addr + (ushort)
8465 ASC_SCSIQ_B_STATUS));
8466 q_status |= (QS_READY | QS_BUSY);
8467 AscWriteLramByte(iop_base,
8468 (ushort)(halt_q_addr +
8469 (ushort)ASC_SCSIQ_B_STATUS),
8470 q_status);
8472 scsi_busy = AscReadLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B);
8473 scsi_busy &= ~target_id;
8474 AscWriteLramByte(iop_base, (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8476 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8477 return (0);
8478 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
8480 AscMemWordCopyPtrFromLram(iop_base,
8481 ASCV_MSGOUT_BEG,
8482 (uchar *)&out_msg,
8483 sizeof(EXT_MSG) >> 1);
8485 if ((out_msg.msg_type == MS_EXTEND) &&
8486 (out_msg.msg_len == MS_SDTR_LEN) &&
8487 (out_msg.msg_req == MS_SDTR_CODE)) {
8489 asc_dvc->init_sdtr &= ~target_id;
8490 asc_dvc->sdtr_done &= ~target_id;
8491 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
8492 boardp->sdtr_data[tid_no] = asyn_sdtr;
8494 q_cntl &= ~QC_MSG_OUT;
8495 AscWriteLramByte(iop_base,
8496 (ushort)(halt_q_addr +
8497 (ushort)ASC_SCSIQ_B_CNTL), q_cntl);
8498 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8499 return (0);
8500 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
8502 scsi_status = AscReadLramByte(iop_base,
8503 (ushort)((ushort)halt_q_addr +
8504 (ushort)
8505 ASC_SCSIQ_SCSI_STATUS));
8506 cur_dvc_qng =
8507 AscReadLramByte(iop_base,
8508 (ushort)((ushort)ASC_QADR_BEG +
8509 (ushort)target_ix));
8510 if ((cur_dvc_qng > 0) && (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
8512 scsi_busy = AscReadLramByte(iop_base,
8513 (ushort)ASCV_SCSIBUSY_B);
8514 scsi_busy |= target_id;
8515 AscWriteLramByte(iop_base,
8516 (ushort)ASCV_SCSIBUSY_B, scsi_busy);
8517 asc_dvc->queue_full_or_busy |= target_id;
8519 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
8520 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
8521 cur_dvc_qng -= 1;
8522 asc_dvc->max_dvc_qng[tid_no] =
8523 cur_dvc_qng;
8525 AscWriteLramByte(iop_base,
8526 (ushort)((ushort)
8527 ASCV_MAX_DVC_QNG_BEG
8528 + (ushort)
8529 tid_no),
8530 cur_dvc_qng);
8533 * Set the device queue depth to the number of
8534 * active requests when the QUEUE FULL condition
8535 * was encountered.
8537 boardp->queue_full |= target_id;
8538 boardp->queue_full_cnt[tid_no] =
8539 cur_dvc_qng;
8543 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8544 return (0);
8546 #if CC_VERY_LONG_SG_LIST
8547 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC) {
8548 uchar q_no;
8549 ushort q_addr;
8550 uchar sg_wk_q_no;
8551 uchar first_sg_wk_q_no;
8552 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
8553 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
8554 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
8555 ushort sg_list_dwords;
8556 ushort sg_entry_cnt;
8557 uchar next_qp;
8558 int i;
8560 q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP);
8561 if (q_no == ASC_QLINK_END) {
8562 return (0);
8565 q_addr = ASC_QNO_TO_QADDR(q_no);
8568 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
8569 * structure pointer using a macro provided by the driver.
8570 * The ASC_SCSI_REQ pointer provides a pointer to the
8571 * host ASC_SG_HEAD structure.
8573 /* Read request's SRB pointer. */
8574 scsiq = (ASC_SCSI_Q *)
8575 ASC_SRB2SCSIQ(ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
8576 (ushort)
8577 (q_addr +
8578 ASC_SCSIQ_D_SRBPTR))));
8581 * Get request's first and working SG queue.
8583 sg_wk_q_no = AscReadLramByte(iop_base,
8584 (ushort)(q_addr +
8585 ASC_SCSIQ_B_SG_WK_QP));
8587 first_sg_wk_q_no = AscReadLramByte(iop_base,
8588 (ushort)(q_addr +
8589 ASC_SCSIQ_B_FIRST_SG_WK_QP));
8592 * Reset request's working SG queue back to the
8593 * first SG queue.
8595 AscWriteLramByte(iop_base,
8596 (ushort)(q_addr +
8597 (ushort)ASC_SCSIQ_B_SG_WK_QP),
8598 first_sg_wk_q_no);
8600 sg_head = scsiq->sg_head;
8603 * Set sg_entry_cnt to the number of SG elements
8604 * that will be completed on this interrupt.
8606 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
8607 * SG elements. The data_cnt and data_addr fields which
8608 * add 1 to the SG element capacity are not used when
8609 * restarting SG handling after a halt.
8611 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1)) {
8612 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
8615 * Keep track of remaining number of SG elements that will
8616 * need to be handled on the next interrupt.
8618 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
8619 } else {
8620 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
8621 scsiq->remain_sg_entry_cnt = 0;
8625 * Copy SG elements into the list of allocated SG queues.
8627 * Last index completed is saved in scsiq->next_sg_index.
8629 next_qp = first_sg_wk_q_no;
8630 q_addr = ASC_QNO_TO_QADDR(next_qp);
8631 scsi_sg_q.sg_head_qp = q_no;
8632 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
8633 for (i = 0; i < sg_head->queue_cnt; i++) {
8634 scsi_sg_q.seq_no = i + 1;
8635 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
8636 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
8637 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
8639 * After very first SG queue RISC FW uses next
8640 * SG queue first element then checks sg_list_cnt
8641 * against zero and then decrements, so set
8642 * sg_list_cnt 1 less than number of SG elements
8643 * in each SG queue.
8645 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
8646 scsi_sg_q.sg_cur_list_cnt =
8647 ASC_SG_LIST_PER_Q - 1;
8648 } else {
8650 * This is the last SG queue in the list of
8651 * allocated SG queues. If there are more
8652 * SG elements than will fit in the allocated
8653 * queues, then set the QCSG_SG_XFER_MORE flag.
8655 if (scsiq->remain_sg_entry_cnt != 0) {
8656 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
8657 } else {
8658 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
8660 /* equals sg_entry_cnt * 2 */
8661 sg_list_dwords = sg_entry_cnt << 1;
8662 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
8663 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
8664 sg_entry_cnt = 0;
8667 scsi_sg_q.q_no = next_qp;
8668 AscMemWordCopyPtrToLram(iop_base,
8669 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
8670 (uchar *)&scsi_sg_q,
8671 sizeof(ASC_SG_LIST_Q) >> 1);
8673 AscMemDWordCopyPtrToLram(iop_base,
8674 q_addr + ASC_SGQ_LIST_BEG,
8675 (uchar *)&sg_head->
8676 sg_list[scsiq->next_sg_index],
8677 sg_list_dwords);
8679 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
8682 * If the just completed SG queue contained the
8683 * last SG element, then no more SG queues need
8684 * to be written.
8686 if (scsi_sg_q.cntl & QCSG_SG_XFER_END) {
8687 break;
8690 next_qp = AscReadLramByte(iop_base,
8691 (ushort)(q_addr +
8692 ASC_SCSIQ_B_FWD));
8693 q_addr = ASC_QNO_TO_QADDR(next_qp);
8697 * Clear the halt condition so the RISC will be restarted
8698 * after the return.
8700 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
8701 return (0);
8703 #endif /* CC_VERY_LONG_SG_LIST */
8704 return (0);
8707 static uchar
8708 _AscCopyLramScsiDoneQ(PortAddr iop_base,
8709 ushort q_addr,
8710 ASC_QDONE_INFO *scsiq, ASC_DCNT max_dma_count)
8712 ushort _val;
8713 uchar sg_queue_cnt;
8715 DvcGetQinfo(iop_base,
8716 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
8717 (uchar *)scsiq,
8718 (sizeof(ASC_SCSIQ_2) + sizeof(ASC_SCSIQ_3)) / 2);
8720 _val = AscReadLramWord(iop_base,
8721 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS));
8722 scsiq->q_status = (uchar)_val;
8723 scsiq->q_no = (uchar)(_val >> 8);
8724 _val = AscReadLramWord(iop_base,
8725 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_CNTL));
8726 scsiq->cntl = (uchar)_val;
8727 sg_queue_cnt = (uchar)(_val >> 8);
8728 _val = AscReadLramWord(iop_base,
8729 (ushort)(q_addr +
8730 (ushort)ASC_SCSIQ_B_SENSE_LEN));
8731 scsiq->sense_len = (uchar)_val;
8732 scsiq->extra_bytes = (uchar)(_val >> 8);
8735 * Read high word of remain bytes from alternate location.
8737 scsiq->remain_bytes = (((ADV_DCNT)AscReadLramWord(iop_base,
8738 (ushort)(q_addr +
8739 (ushort)
8740 ASC_SCSIQ_W_ALT_DC1)))
8741 << 16);
8743 * Read low word of remain bytes from original location.
8745 scsiq->remain_bytes += AscReadLramWord(iop_base,
8746 (ushort)(q_addr + (ushort)
8747 ASC_SCSIQ_DW_REMAIN_XFER_CNT));
8749 scsiq->remain_bytes &= max_dma_count;
8750 return (sg_queue_cnt);
8753 static int AscIsrQDone(ASC_DVC_VAR *asc_dvc)
8755 uchar next_qp;
8756 uchar n_q_used;
8757 uchar sg_list_qp;
8758 uchar sg_queue_cnt;
8759 uchar q_cnt;
8760 uchar done_q_tail;
8761 uchar tid_no;
8762 ASC_SCSI_BIT_ID_TYPE scsi_busy;
8763 ASC_SCSI_BIT_ID_TYPE target_id;
8764 PortAddr iop_base;
8765 ushort q_addr;
8766 ushort sg_q_addr;
8767 uchar cur_target_qng;
8768 ASC_QDONE_INFO scsiq_buf;
8769 ASC_QDONE_INFO *scsiq;
8770 int false_overrun;
8771 ASC_ISR_CALLBACK asc_isr_callback;
8773 iop_base = asc_dvc->iop_base;
8774 asc_isr_callback = asc_dvc->isr_callback;
8775 n_q_used = 1;
8776 scsiq = (ASC_QDONE_INFO *)&scsiq_buf;
8777 done_q_tail = (uchar)AscGetVarDoneQTail(iop_base);
8778 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
8779 next_qp = AscReadLramByte(iop_base,
8780 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_FWD));
8781 if (next_qp != ASC_QLINK_END) {
8782 AscPutVarDoneQTail(iop_base, next_qp);
8783 q_addr = ASC_QNO_TO_QADDR(next_qp);
8784 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
8785 asc_dvc->max_dma_count);
8786 AscWriteLramByte(iop_base,
8787 (ushort)(q_addr +
8788 (ushort)ASC_SCSIQ_B_STATUS),
8789 (uchar)(scsiq->
8790 q_status & (uchar)~(QS_READY |
8791 QS_ABORTED)));
8792 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
8793 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
8794 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
8795 sg_q_addr = q_addr;
8796 sg_list_qp = next_qp;
8797 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
8798 sg_list_qp = AscReadLramByte(iop_base,
8799 (ushort)(sg_q_addr
8800 + (ushort)
8801 ASC_SCSIQ_B_FWD));
8802 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
8803 if (sg_list_qp == ASC_QLINK_END) {
8804 AscSetLibErrorCode(asc_dvc,
8805 ASCQ_ERR_SG_Q_LINKS);
8806 scsiq->d3.done_stat = QD_WITH_ERROR;
8807 scsiq->d3.host_stat =
8808 QHSTA_D_QDONE_SG_LIST_CORRUPTED;
8809 goto FATAL_ERR_QDONE;
8811 AscWriteLramByte(iop_base,
8812 (ushort)(sg_q_addr + (ushort)
8813 ASC_SCSIQ_B_STATUS),
8814 QS_FREE);
8816 n_q_used = sg_queue_cnt + 1;
8817 AscPutVarDoneQTail(iop_base, sg_list_qp);
8819 if (asc_dvc->queue_full_or_busy & target_id) {
8820 cur_target_qng = AscReadLramByte(iop_base,
8821 (ushort)((ushort)
8822 ASC_QADR_BEG
8823 + (ushort)
8824 scsiq->d2.
8825 target_ix));
8826 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
8827 scsi_busy = AscReadLramByte(iop_base, (ushort)
8828 ASCV_SCSIBUSY_B);
8829 scsi_busy &= ~target_id;
8830 AscWriteLramByte(iop_base,
8831 (ushort)ASCV_SCSIBUSY_B,
8832 scsi_busy);
8833 asc_dvc->queue_full_or_busy &= ~target_id;
8836 if (asc_dvc->cur_total_qng >= n_q_used) {
8837 asc_dvc->cur_total_qng -= n_q_used;
8838 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
8839 asc_dvc->cur_dvc_qng[tid_no]--;
8841 } else {
8842 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
8843 scsiq->d3.done_stat = QD_WITH_ERROR;
8844 goto FATAL_ERR_QDONE;
8846 if ((scsiq->d2.srb_ptr == 0UL) ||
8847 ((scsiq->q_status & QS_ABORTED) != 0)) {
8848 return (0x11);
8849 } else if (scsiq->q_status == QS_DONE) {
8850 false_overrun = FALSE;
8851 if (scsiq->extra_bytes != 0) {
8852 scsiq->remain_bytes +=
8853 (ADV_DCNT)scsiq->extra_bytes;
8855 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
8856 if (scsiq->d3.host_stat ==
8857 QHSTA_M_DATA_OVER_RUN) {
8858 if ((scsiq->
8859 cntl & (QC_DATA_IN | QC_DATA_OUT))
8860 == 0) {
8861 scsiq->d3.done_stat =
8862 QD_NO_ERROR;
8863 scsiq->d3.host_stat =
8864 QHSTA_NO_ERROR;
8865 } else if (false_overrun) {
8866 scsiq->d3.done_stat =
8867 QD_NO_ERROR;
8868 scsiq->d3.host_stat =
8869 QHSTA_NO_ERROR;
8871 } else if (scsiq->d3.host_stat ==
8872 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
8873 AscStopChip(iop_base);
8874 AscSetChipControl(iop_base,
8875 (uchar)(CC_SCSI_RESET
8876 | CC_HALT));
8877 DvcDelayNanoSecond(asc_dvc, 60000);
8878 AscSetChipControl(iop_base, CC_HALT);
8879 AscSetChipStatus(iop_base,
8880 CIW_CLR_SCSI_RESET_INT);
8881 AscSetChipStatus(iop_base, 0);
8882 AscSetChipControl(iop_base, 0);
8885 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
8886 (*asc_isr_callback) (asc_dvc, scsiq);
8887 } else {
8888 if ((AscReadLramByte(iop_base,
8889 (ushort)(q_addr + (ushort)
8890 ASC_SCSIQ_CDB_BEG))
8891 == START_STOP)) {
8892 asc_dvc->unit_not_ready &= ~target_id;
8893 if (scsiq->d3.done_stat != QD_NO_ERROR) {
8894 asc_dvc->start_motor &=
8895 ~target_id;
8899 return (1);
8900 } else {
8901 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
8902 FATAL_ERR_QDONE:
8903 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
8904 (*asc_isr_callback) (asc_dvc, scsiq);
8906 return (0x80);
8909 return (0);
8912 static int AscISR(ASC_DVC_VAR *asc_dvc)
8914 ASC_CS_TYPE chipstat;
8915 PortAddr iop_base;
8916 ushort saved_ram_addr;
8917 uchar ctrl_reg;
8918 uchar saved_ctrl_reg;
8919 int int_pending;
8920 int status;
8921 uchar host_flag;
8923 iop_base = asc_dvc->iop_base;
8924 int_pending = FALSE;
8926 if (AscIsIntPending(iop_base) == 0) {
8927 return int_pending;
8930 if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
8931 || (asc_dvc->isr_callback == 0)
8933 return (ERR);
8935 if (asc_dvc->in_critical_cnt != 0) {
8936 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
8937 return (ERR);
8939 if (asc_dvc->is_in_int) {
8940 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
8941 return (ERR);
8943 asc_dvc->is_in_int = TRUE;
8944 ctrl_reg = AscGetChipControl(iop_base);
8945 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
8946 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
8947 chipstat = AscGetChipStatus(iop_base);
8948 if (chipstat & CSW_SCSI_RESET_LATCH) {
8949 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
8950 int i = 10;
8951 int_pending = TRUE;
8952 asc_dvc->sdtr_done = 0;
8953 saved_ctrl_reg &= (uchar)(~CC_HALT);
8954 while ((AscGetChipStatus(iop_base) &
8955 CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) {
8956 DvcSleepMilliSecond(100);
8958 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
8959 AscSetChipControl(iop_base, CC_HALT);
8960 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
8961 AscSetChipStatus(iop_base, 0);
8962 chipstat = AscGetChipStatus(iop_base);
8965 saved_ram_addr = AscGetChipLramAddr(iop_base);
8966 host_flag = AscReadLramByte(iop_base,
8967 ASCV_HOST_FLAG_B) &
8968 (uchar)(~ASC_HOST_FLAG_IN_ISR);
8969 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
8970 (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR));
8971 if ((chipstat & CSW_INT_PENDING)
8972 || (int_pending)
8974 AscAckInterrupt(iop_base);
8975 int_pending = TRUE;
8976 if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) {
8977 if (AscIsrChipHalted(asc_dvc) == ERR) {
8978 goto ISR_REPORT_QDONE_FATAL_ERROR;
8979 } else {
8980 saved_ctrl_reg &= (uchar)(~CC_HALT);
8982 } else {
8983 ISR_REPORT_QDONE_FATAL_ERROR:
8984 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
8985 while (((status =
8986 AscIsrQDone(asc_dvc)) & 0x01) != 0) {
8988 } else {
8989 do {
8990 if ((status =
8991 AscIsrQDone(asc_dvc)) == 1) {
8992 break;
8994 } while (status == 0x11);
8996 if ((status & 0x80) != 0)
8997 int_pending = ERR;
9000 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
9001 AscSetChipLramAddr(iop_base, saved_ram_addr);
9002 AscSetChipControl(iop_base, saved_ctrl_reg);
9003 asc_dvc->is_in_int = FALSE;
9004 return (int_pending);
9007 /* Microcode buffer is kept after initialization for error recovery. */
9008 static uchar _asc_mcode_buf[] = {
9009 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9010 0x00, 0x00, 0x00, 0x00,
9011 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00,
9012 0x00, 0x00, 0x00, 0x00,
9013 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9014 0x00, 0x00, 0x00, 0x00,
9015 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9016 0x00, 0x00, 0x00, 0x00,
9017 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00,
9018 0x00, 0xFF, 0x00, 0x00,
9019 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00,
9020 0x00, 0x00, 0x00, 0x00,
9021 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
9022 0x00, 0x00, 0x00, 0x00,
9023 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88,
9024 0x00, 0x00, 0x00, 0x00,
9025 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73,
9026 0x03, 0x23, 0x36, 0x40,
9027 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
9028 0xC2, 0x00, 0x92, 0x80,
9029 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60,
9030 0xB6, 0x00, 0x92, 0x80,
9031 0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00,
9032 0x92, 0x80, 0x80, 0x62,
9033 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
9034 0xCD, 0x04, 0x4D, 0x00,
9035 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01,
9036 0xE6, 0x84, 0xD2, 0xC1,
9037 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97,
9038 0xC6, 0x81, 0xC2, 0x88,
9039 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
9040 0x84, 0x97, 0x07, 0xA6,
9041 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE,
9042 0xC2, 0x88, 0xCE, 0x00,
9043 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01,
9044 0x80, 0x63, 0x07, 0xA6,
9045 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
9046 0x34, 0x01, 0x00, 0x33,
9047 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23,
9048 0x68, 0x98, 0x4D, 0x04,
9049 0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23,
9050 0xF8, 0x88, 0xFB, 0x23,
9051 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
9052 0x00, 0x33, 0x0A, 0x00,
9053 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00,
9054 0xC2, 0x88, 0xCD, 0x04,
9055 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81,
9056 0x06, 0xAB, 0x82, 0x01,
9057 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
9058 0x3C, 0x01, 0x00, 0x05,
9059 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01,
9060 0x15, 0x23, 0xA1, 0x01,
9061 0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00,
9062 0x06, 0x61, 0x00, 0xA0,
9063 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
9064 0xC2, 0x88, 0x06, 0x23,
9065 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01,
9066 0x57, 0x60, 0x00, 0xA0,
9067 0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73,
9068 0x4B, 0x00, 0x06, 0x61,
9069 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
9070 0x4F, 0x00, 0x84, 0x97,
9071 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97,
9072 0x48, 0x04, 0x84, 0x80,
9073 0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00,
9074 0x81, 0x73, 0x06, 0x29,
9075 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
9076 0x04, 0x98, 0xF0, 0x80,
9077 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6,
9078 0x34, 0x02, 0x03, 0xA6,
9079 0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96,
9080 0x46, 0x82, 0xFE, 0x95,
9081 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
9082 0x07, 0xA6, 0x5A, 0x02,
9083 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95,
9084 0x48, 0x82, 0x60, 0x96,
9085 0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84,
9086 0x04, 0x01, 0x0C, 0xDC,
9087 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
9088 0x6F, 0x00, 0xA5, 0x01,
9089 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01,
9090 0x02, 0xA6, 0xAA, 0x02,
9091 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04,
9092 0x01, 0xA6, 0xB4, 0x02,
9093 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
9094 0x80, 0x63, 0x00, 0x43,
9095 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23,
9096 0x04, 0x61, 0x84, 0x01,
9097 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F,
9098 0x00, 0x00, 0xEA, 0x82,
9099 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
9100 0x00, 0x33, 0x1F, 0x00,
9101 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98,
9102 0xB6, 0x2D, 0x01, 0xA6,
9103 0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6,
9104 0x10, 0x03, 0x03, 0xA6,
9105 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
9106 0x7C, 0x95, 0xEE, 0x82,
9107 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4,
9108 0x04, 0x01, 0x2D, 0xC8,
9109 0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01,
9110 0x05, 0x05, 0x86, 0x98,
9111 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
9112 0x3C, 0x04, 0x06, 0xA6,
9113 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88,
9114 0x7C, 0x95, 0x32, 0x83,
9115 0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05,
9116 0xEB, 0x04, 0x00, 0x33,
9117 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
9118 0xFF, 0xA2, 0x7A, 0x03,
9119 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01,
9120 0x00, 0xA2, 0x9A, 0x03,
9121 0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00,
9122 0x01, 0xA6, 0x96, 0x03,
9123 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
9124 0xA4, 0x03, 0x00, 0xA6,
9125 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03,
9126 0x07, 0xA6, 0xB2, 0x03,
9127 0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88,
9128 0xA8, 0x98, 0x80, 0x42,
9129 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
9130 0xC0, 0x83, 0x00, 0x33,
9131 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23,
9132 0xA0, 0x01, 0x12, 0x23,
9133 0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B,
9134 0x80, 0x67, 0x05, 0x23,
9135 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
9136 0x06, 0xA6, 0x0A, 0x04,
9137 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96,
9138 0xF4, 0x83, 0x20, 0x84,
9139 0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
9140 0x83, 0x03, 0x80, 0x63,
9141 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
9142 0x38, 0x04, 0x00, 0x33,
9143 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84,
9144 0x1D, 0x01, 0x06, 0xCC,
9145 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62,
9146 0xA2, 0x0D, 0x80, 0x63,
9147 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
9148 0x80, 0x63, 0xA3, 0x01,
9149 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0,
9150 0x76, 0x04, 0xE0, 0x00,
9151 0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00,
9152 0x00, 0x33, 0x1E, 0x00,
9153 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
9154 0x08, 0x23, 0x22, 0xA3,
9155 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3,
9156 0xC4, 0x04, 0x42, 0x23,
9157 0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23,
9158 0xF8, 0x88, 0x04, 0x98,
9159 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
9160 0x81, 0x62, 0xE8, 0x81,
9161 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98,
9162 0x00, 0x33, 0x00, 0x81,
9163 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23,
9164 0xF8, 0x88, 0x04, 0x23,
9165 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
9166 0xF4, 0x04, 0x00, 0x33,
9167 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01,
9168 0x04, 0x23, 0xA0, 0x01,
9169 0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00,
9170 0x00, 0xA3, 0x22, 0x05,
9171 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
9172 0x46, 0x97, 0xCD, 0x04,
9173 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23,
9174 0x82, 0x01, 0x34, 0x85,
9175 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05,
9176 0x1D, 0x01, 0x04, 0xD6,
9177 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
9178 0x49, 0x00, 0x81, 0x01,
9179 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01,
9180 0x49, 0x04, 0x80, 0x01,
9181 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04,
9182 0x01, 0x23, 0xEA, 0x00,
9183 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
9184 0x07, 0xA4, 0xF8, 0x05,
9185 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00,
9186 0xC2, 0x88, 0x04, 0xA0,
9187 0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61,
9188 0x00, 0xA2, 0xA4, 0x05,
9189 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
9190 0x62, 0x97, 0x04, 0x85,
9191 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05,
9192 0xF4, 0x85, 0x03, 0xA0,
9193 0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63,
9194 0xCC, 0x86, 0x07, 0xA0,
9195 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
9196 0x80, 0x67, 0x80, 0x63,
9197 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23,
9198 0xF8, 0x88, 0x07, 0x23,
9199 0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00,
9200 0x00, 0x63, 0x4A, 0x00,
9201 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
9202 0x07, 0x41, 0x83, 0x03,
9203 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88,
9204 0x1D, 0x01, 0x01, 0xD6,
9205 0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00,
9206 0x07, 0xA6, 0x7C, 0x05,
9207 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
9208 0x52, 0x00, 0x06, 0x61,
9209 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41,
9210 0x00, 0x63, 0x1D, 0x01,
9211 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23,
9212 0x07, 0x41, 0x00, 0x63,
9213 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
9214 0xDF, 0x00, 0x06, 0xA6,
9215 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33,
9216 0x00, 0x40, 0xC0, 0x20,
9217 0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63,
9218 0x06, 0xA6, 0x94, 0x06,
9219 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
9220 0x40, 0x0E, 0x80, 0x63,
9221 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E,
9222 0x80, 0x63, 0x00, 0x43,
9223 0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05,
9224 0x80, 0x67, 0x40, 0x0E,
9225 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
9226 0x07, 0xA6, 0xD6, 0x06,
9227 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00,
9228 0x0A, 0x2B, 0x07, 0xA6,
9229 0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2,
9230 0xF4, 0x06, 0xC0, 0x0E,
9231 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
9232 0x81, 0x62, 0x04, 0x01,
9233 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6,
9234 0x8C, 0x06, 0x00, 0x33,
9235 0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03,
9236 0x80, 0x63, 0x06, 0xA6,
9237 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
9238 0x00, 0x00, 0x80, 0x67,
9239 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05,
9240 0xBF, 0x23, 0x04, 0x61,
9241 0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00,
9242 0x00, 0x01, 0xF2, 0x00,
9243 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
9244 0x80, 0x05, 0x81, 0x05,
9245 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00,
9246 0x70, 0x00, 0x81, 0x01,
9247 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04,
9248 0x70, 0x00, 0x80, 0x01,
9249 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
9250 0xF1, 0x00, 0x70, 0x00,
9251 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01,
9252 0x71, 0x04, 0x70, 0x00,
9253 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05,
9254 0xA3, 0x01, 0xA2, 0x01,
9255 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
9256 0xC4, 0x07, 0x00, 0x33,
9257 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8,
9258 0x48, 0x00, 0xB0, 0x01,
9259 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43,
9260 0x00, 0xA2, 0xE4, 0x07,
9261 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
9262 0x05, 0x05, 0x00, 0x63,
9263 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43,
9264 0x76, 0x08, 0x80, 0x02,
9265 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
9266 0x00, 0x02, 0x00, 0xA0,
9267 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
9268 0x00, 0x63, 0xF3, 0x04,
9269 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40,
9270 0x00, 0xA2, 0x44, 0x08,
9271 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1,
9272 0x24, 0x08, 0x04, 0x98,
9273 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
9274 0x5A, 0x88, 0x02, 0x01,
9275 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00,
9276 0x00, 0xA3, 0x64, 0x08,
9277 0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63,
9278 0x06, 0xA6, 0x76, 0x08,
9279 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
9280 0x00, 0x63, 0x38, 0x2B,
9281 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98,
9282 0x05, 0x05, 0xB2, 0x09,
9283 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63,
9284 0x80, 0x32, 0x80, 0x36,
9285 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
9286 0x40, 0x36, 0x40, 0x3A,
9287 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08,
9288 0x5D, 0x00, 0xFE, 0xC3,
9289 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73,
9290 0xFF, 0xFD, 0x80, 0x73,
9291 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
9292 0xA1, 0x23, 0xA1, 0x01,
9293 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2,
9294 0x80, 0x00, 0x03, 0xC2,
9295 0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23,
9296 0xA0, 0x01, 0xE6, 0x84,
9299 static ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
9300 static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
9302 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
9303 static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = {
9304 INQUIRY,
9305 REQUEST_SENSE,
9306 READ_CAPACITY,
9307 READ_TOC,
9308 MODE_SELECT,
9309 MODE_SENSE,
9310 MODE_SELECT_10,
9311 MODE_SENSE_10,
9312 0xFF,
9313 0xFF,
9314 0xFF,
9315 0xFF,
9316 0xFF,
9317 0xFF,
9318 0xFF,
9319 0xFF
9322 static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq)
9324 PortAddr iop_base;
9325 ulong last_int_level;
9326 int sta;
9327 int n_q_required;
9328 int disable_syn_offset_one_fix;
9329 int i;
9330 ASC_PADDR addr;
9331 ASC_EXE_CALLBACK asc_exe_callback;
9332 ushort sg_entry_cnt = 0;
9333 ushort sg_entry_cnt_minus_one = 0;
9334 uchar target_ix;
9335 uchar tid_no;
9336 uchar sdtr_data;
9337 uchar extra_bytes;
9338 uchar scsi_cmd;
9339 uchar disable_cmd;
9340 ASC_SG_HEAD *sg_head;
9341 ASC_DCNT data_cnt;
9343 iop_base = asc_dvc->iop_base;
9344 sg_head = scsiq->sg_head;
9345 asc_exe_callback = asc_dvc->exe_callback;
9346 if (asc_dvc->err_code != 0)
9347 return (ERR);
9348 if (scsiq == (ASC_SCSI_Q *)0L) {
9349 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
9350 return (ERR);
9352 scsiq->q1.q_no = 0;
9353 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
9354 scsiq->q1.extra_bytes = 0;
9356 sta = 0;
9357 target_ix = scsiq->q2.target_ix;
9358 tid_no = ASC_TIX_TO_TID(target_ix);
9359 n_q_required = 1;
9360 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
9361 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
9362 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
9363 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9364 AscMsgOutSDTR(asc_dvc,
9365 asc_dvc->
9366 sdtr_period_tbl[(sdtr_data >> 4) &
9367 (uchar)(asc_dvc->
9368 max_sdtr_index -
9369 1)],
9370 (uchar)(sdtr_data & (uchar)
9371 ASC_SYN_MAX_OFFSET));
9372 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
9375 last_int_level = DvcEnterCritical();
9376 if (asc_dvc->in_critical_cnt != 0) {
9377 DvcLeaveCritical(last_int_level);
9378 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
9379 return (ERR);
9381 asc_dvc->in_critical_cnt++;
9382 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9383 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
9384 asc_dvc->in_critical_cnt--;
9385 DvcLeaveCritical(last_int_level);
9386 return (ERR);
9388 #if !CC_VERY_LONG_SG_LIST
9389 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9390 asc_dvc->in_critical_cnt--;
9391 DvcLeaveCritical(last_int_level);
9392 return (ERR);
9394 #endif /* !CC_VERY_LONG_SG_LIST */
9395 if (sg_entry_cnt == 1) {
9396 scsiq->q1.data_addr =
9397 (ADV_PADDR)sg_head->sg_list[0].addr;
9398 scsiq->q1.data_cnt =
9399 (ADV_DCNT)sg_head->sg_list[0].bytes;
9400 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
9402 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
9404 scsi_cmd = scsiq->cdbptr[0];
9405 disable_syn_offset_one_fix = FALSE;
9406 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
9407 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
9408 if (scsiq->q1.cntl & QC_SG_HEAD) {
9409 data_cnt = 0;
9410 for (i = 0; i < sg_entry_cnt; i++) {
9411 data_cnt +=
9412 (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i].
9413 bytes);
9415 } else {
9416 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
9418 if (data_cnt != 0UL) {
9419 if (data_cnt < 512UL) {
9420 disable_syn_offset_one_fix = TRUE;
9421 } else {
9422 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST;
9423 i++) {
9424 disable_cmd =
9425 _syn_offset_one_disable_cmd[i];
9426 if (disable_cmd == 0xFF) {
9427 break;
9429 if (scsi_cmd == disable_cmd) {
9430 disable_syn_offset_one_fix =
9431 TRUE;
9432 break;
9438 if (disable_syn_offset_one_fix) {
9439 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9440 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
9441 ASC_TAG_FLAG_DISABLE_DISCONNECT);
9442 } else {
9443 scsiq->q2.tag_code &= 0x27;
9445 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
9446 if (asc_dvc->bug_fix_cntl) {
9447 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9448 if ((scsi_cmd == READ_6) ||
9449 (scsi_cmd == READ_10)) {
9450 addr =
9451 (ADV_PADDR)le32_to_cpu(sg_head->
9452 sg_list
9453 [sg_entry_cnt_minus_one].
9454 addr) +
9455 (ADV_DCNT)le32_to_cpu(sg_head->
9456 sg_list
9457 [sg_entry_cnt_minus_one].
9458 bytes);
9459 extra_bytes =
9460 (uchar)((ushort)addr & 0x0003);
9461 if ((extra_bytes != 0)
9463 ((scsiq->q2.
9464 tag_code &
9465 ASC_TAG_FLAG_EXTRA_BYTES)
9466 == 0)) {
9467 scsiq->q2.tag_code |=
9468 ASC_TAG_FLAG_EXTRA_BYTES;
9469 scsiq->q1.extra_bytes =
9470 extra_bytes;
9471 data_cnt =
9472 le32_to_cpu(sg_head->
9473 sg_list
9474 [sg_entry_cnt_minus_one].
9475 bytes);
9476 data_cnt -=
9477 (ASC_DCNT) extra_bytes;
9478 sg_head->
9479 sg_list
9480 [sg_entry_cnt_minus_one].
9481 bytes =
9482 cpu_to_le32(data_cnt);
9487 sg_head->entry_to_copy = sg_head->entry_cnt;
9488 #if CC_VERY_LONG_SG_LIST
9490 * Set the sg_entry_cnt to the maximum possible. The rest of
9491 * the SG elements will be copied when the RISC completes the
9492 * SG elements that fit and halts.
9494 if (sg_entry_cnt > ASC_MAX_SG_LIST) {
9495 sg_entry_cnt = ASC_MAX_SG_LIST;
9497 #endif /* CC_VERY_LONG_SG_LIST */
9498 n_q_required = AscSgListToQueue(sg_entry_cnt);
9499 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
9500 (uint) n_q_required)
9501 || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9502 if ((sta =
9503 AscSendScsiQueue(asc_dvc, scsiq,
9504 n_q_required)) == 1) {
9505 asc_dvc->in_critical_cnt--;
9506 if (asc_exe_callback != 0) {
9507 (*asc_exe_callback) (asc_dvc, scsiq);
9509 DvcLeaveCritical(last_int_level);
9510 return (sta);
9513 } else {
9514 if (asc_dvc->bug_fix_cntl) {
9515 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
9516 if ((scsi_cmd == READ_6) ||
9517 (scsi_cmd == READ_10)) {
9518 addr =
9519 le32_to_cpu(scsiq->q1.data_addr) +
9520 le32_to_cpu(scsiq->q1.data_cnt);
9521 extra_bytes =
9522 (uchar)((ushort)addr & 0x0003);
9523 if ((extra_bytes != 0)
9525 ((scsiq->q2.
9526 tag_code &
9527 ASC_TAG_FLAG_EXTRA_BYTES)
9528 == 0)) {
9529 data_cnt =
9530 le32_to_cpu(scsiq->q1.
9531 data_cnt);
9532 if (((ushort)data_cnt & 0x01FF)
9533 == 0) {
9534 scsiq->q2.tag_code |=
9535 ASC_TAG_FLAG_EXTRA_BYTES;
9536 data_cnt -= (ASC_DCNT)
9537 extra_bytes;
9538 scsiq->q1.data_cnt =
9539 cpu_to_le32
9540 (data_cnt);
9541 scsiq->q1.extra_bytes =
9542 extra_bytes;
9548 n_q_required = 1;
9549 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
9550 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
9551 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
9552 n_q_required)) == 1) {
9553 asc_dvc->in_critical_cnt--;
9554 if (asc_exe_callback != 0) {
9555 (*asc_exe_callback) (asc_dvc, scsiq);
9557 DvcLeaveCritical(last_int_level);
9558 return (sta);
9562 asc_dvc->in_critical_cnt--;
9563 DvcLeaveCritical(last_int_level);
9564 return (sta);
9567 static int
9568 AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required)
9570 PortAddr iop_base;
9571 uchar free_q_head;
9572 uchar next_qp;
9573 uchar tid_no;
9574 uchar target_ix;
9575 int sta;
9577 iop_base = asc_dvc->iop_base;
9578 target_ix = scsiq->q2.target_ix;
9579 tid_no = ASC_TIX_TO_TID(target_ix);
9580 sta = 0;
9581 free_q_head = (uchar)AscGetVarFreeQHead(iop_base);
9582 if (n_q_required > 1) {
9583 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
9584 free_q_head, (uchar)
9585 (n_q_required)))
9586 != (uchar)ASC_QLINK_END) {
9587 asc_dvc->last_q_shortage = 0;
9588 scsiq->sg_head->queue_cnt = n_q_required - 1;
9589 scsiq->q1.q_no = free_q_head;
9590 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
9591 free_q_head)) == 1) {
9592 AscPutVarFreeQHead(iop_base, next_qp);
9593 asc_dvc->cur_total_qng += (uchar)(n_q_required);
9594 asc_dvc->cur_dvc_qng[tid_no]++;
9596 return (sta);
9598 } else if (n_q_required == 1) {
9599 if ((next_qp = AscAllocFreeQueue(iop_base,
9600 free_q_head)) !=
9601 ASC_QLINK_END) {
9602 scsiq->q1.q_no = free_q_head;
9603 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
9604 free_q_head)) == 1) {
9605 AscPutVarFreeQHead(iop_base, next_qp);
9606 asc_dvc->cur_total_qng++;
9607 asc_dvc->cur_dvc_qng[tid_no]++;
9609 return (sta);
9612 return (sta);
9615 static int AscSgListToQueue(int sg_list)
9617 int n_sg_list_qs;
9619 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
9620 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
9621 n_sg_list_qs++;
9622 return (n_sg_list_qs + 1);
9625 static uint
9626 AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs)
9628 uint cur_used_qs;
9629 uint cur_free_qs;
9630 ASC_SCSI_BIT_ID_TYPE target_id;
9631 uchar tid_no;
9633 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
9634 tid_no = ASC_TIX_TO_TID(target_ix);
9635 if ((asc_dvc->unit_not_ready & target_id) ||
9636 (asc_dvc->queue_full_or_busy & target_id)) {
9637 return (0);
9639 if (n_qs == 1) {
9640 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9641 (uint) asc_dvc->last_q_shortage + (uint) ASC_MIN_FREE_Q;
9642 } else {
9643 cur_used_qs = (uint) asc_dvc->cur_total_qng +
9644 (uint) ASC_MIN_FREE_Q;
9646 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
9647 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
9648 if (asc_dvc->cur_dvc_qng[tid_no] >=
9649 asc_dvc->max_dvc_qng[tid_no]) {
9650 return (0);
9652 return (cur_free_qs);
9654 if (n_qs > 1) {
9655 if ((n_qs > asc_dvc->last_q_shortage)
9656 && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
9657 asc_dvc->last_q_shortage = n_qs;
9660 return (0);
9663 static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
9665 ushort q_addr;
9666 uchar tid_no;
9667 uchar sdtr_data;
9668 uchar syn_period_ix;
9669 uchar syn_offset;
9670 PortAddr iop_base;
9672 iop_base = asc_dvc->iop_base;
9673 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
9674 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
9675 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
9676 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
9677 syn_period_ix =
9678 (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
9679 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
9680 AscMsgOutSDTR(asc_dvc,
9681 asc_dvc->sdtr_period_tbl[syn_period_ix],
9682 syn_offset);
9683 scsiq->q1.cntl |= QC_MSG_OUT;
9685 q_addr = ASC_QNO_TO_QADDR(q_no);
9686 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
9687 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
9689 scsiq->q1.status = QS_FREE;
9690 AscMemWordCopyPtrToLram(iop_base,
9691 q_addr + ASC_SCSIQ_CDB_BEG,
9692 (uchar *)scsiq->cdbptr, scsiq->q2.cdb_len >> 1);
9694 DvcPutScsiQ(iop_base,
9695 q_addr + ASC_SCSIQ_CPY_BEG,
9696 (uchar *)&scsiq->q1.cntl,
9697 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
9698 AscWriteLramWord(iop_base,
9699 (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS),
9700 (ushort)(((ushort)scsiq->q1.
9701 q_no << 8) | (ushort)QS_READY));
9702 return (1);
9705 static int
9706 AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no)
9708 int sta;
9709 int i;
9710 ASC_SG_HEAD *sg_head;
9711 ASC_SG_LIST_Q scsi_sg_q;
9712 ASC_DCNT saved_data_addr;
9713 ASC_DCNT saved_data_cnt;
9714 PortAddr iop_base;
9715 ushort sg_list_dwords;
9716 ushort sg_index;
9717 ushort sg_entry_cnt;
9718 ushort q_addr;
9719 uchar next_qp;
9721 iop_base = asc_dvc->iop_base;
9722 sg_head = scsiq->sg_head;
9723 saved_data_addr = scsiq->q1.data_addr;
9724 saved_data_cnt = scsiq->q1.data_cnt;
9725 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
9726 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
9727 #if CC_VERY_LONG_SG_LIST
9729 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
9730 * then not all SG elements will fit in the allocated queues.
9731 * The rest of the SG elements will be copied when the RISC
9732 * completes the SG elements that fit and halts.
9734 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9736 * Set sg_entry_cnt to be the number of SG elements that
9737 * will fit in the allocated SG queues. It is minus 1, because
9738 * the first SG element is handled above. ASC_MAX_SG_LIST is
9739 * already inflated by 1 to account for this. For example it
9740 * may be 50 which is 1 + 7 queues * 7 SG elements.
9742 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
9745 * Keep track of remaining number of SG elements that will
9746 * need to be handled from a_isr.c.
9748 scsiq->remain_sg_entry_cnt =
9749 sg_head->entry_cnt - ASC_MAX_SG_LIST;
9750 } else {
9751 #endif /* CC_VERY_LONG_SG_LIST */
9753 * Set sg_entry_cnt to be the number of SG elements that
9754 * will fit in the allocated SG queues. It is minus 1, because
9755 * the first SG element is handled above.
9757 sg_entry_cnt = sg_head->entry_cnt - 1;
9758 #if CC_VERY_LONG_SG_LIST
9760 #endif /* CC_VERY_LONG_SG_LIST */
9761 if (sg_entry_cnt != 0) {
9762 scsiq->q1.cntl |= QC_SG_HEAD;
9763 q_addr = ASC_QNO_TO_QADDR(q_no);
9764 sg_index = 1;
9765 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
9766 scsi_sg_q.sg_head_qp = q_no;
9767 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
9768 for (i = 0; i < sg_head->queue_cnt; i++) {
9769 scsi_sg_q.seq_no = i + 1;
9770 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
9771 sg_list_dwords = (uchar)(ASC_SG_LIST_PER_Q * 2);
9772 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
9773 if (i == 0) {
9774 scsi_sg_q.sg_list_cnt =
9775 ASC_SG_LIST_PER_Q;
9776 scsi_sg_q.sg_cur_list_cnt =
9777 ASC_SG_LIST_PER_Q;
9778 } else {
9779 scsi_sg_q.sg_list_cnt =
9780 ASC_SG_LIST_PER_Q - 1;
9781 scsi_sg_q.sg_cur_list_cnt =
9782 ASC_SG_LIST_PER_Q - 1;
9784 } else {
9785 #if CC_VERY_LONG_SG_LIST
9787 * This is the last SG queue in the list of
9788 * allocated SG queues. If there are more
9789 * SG elements than will fit in the allocated
9790 * queues, then set the QCSG_SG_XFER_MORE flag.
9792 if (sg_head->entry_cnt > ASC_MAX_SG_LIST) {
9793 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
9794 } else {
9795 #endif /* CC_VERY_LONG_SG_LIST */
9796 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
9797 #if CC_VERY_LONG_SG_LIST
9799 #endif /* CC_VERY_LONG_SG_LIST */
9800 sg_list_dwords = sg_entry_cnt << 1;
9801 if (i == 0) {
9802 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
9803 scsi_sg_q.sg_cur_list_cnt =
9804 sg_entry_cnt;
9805 } else {
9806 scsi_sg_q.sg_list_cnt =
9807 sg_entry_cnt - 1;
9808 scsi_sg_q.sg_cur_list_cnt =
9809 sg_entry_cnt - 1;
9811 sg_entry_cnt = 0;
9813 next_qp = AscReadLramByte(iop_base,
9814 (ushort)(q_addr +
9815 ASC_SCSIQ_B_FWD));
9816 scsi_sg_q.q_no = next_qp;
9817 q_addr = ASC_QNO_TO_QADDR(next_qp);
9818 AscMemWordCopyPtrToLram(iop_base,
9819 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
9820 (uchar *)&scsi_sg_q,
9821 sizeof(ASC_SG_LIST_Q) >> 1);
9822 AscMemDWordCopyPtrToLram(iop_base,
9823 q_addr + ASC_SGQ_LIST_BEG,
9824 (uchar *)&sg_head->
9825 sg_list[sg_index],
9826 sg_list_dwords);
9827 sg_index += ASC_SG_LIST_PER_Q;
9828 scsiq->next_sg_index = sg_index;
9830 } else {
9831 scsiq->q1.cntl &= ~QC_SG_HEAD;
9833 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
9834 scsiq->q1.data_addr = saved_data_addr;
9835 scsiq->q1.data_cnt = saved_data_cnt;
9836 return (sta);
9839 static int
9840 AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data)
9842 int sta = FALSE;
9844 if (AscHostReqRiscHalt(iop_base)) {
9845 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
9846 AscStartChip(iop_base);
9847 return (sta);
9849 return (sta);
9852 static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data)
9854 ASC_SCSI_BIT_ID_TYPE org_id;
9855 int i;
9856 int sta = TRUE;
9858 AscSetBank(iop_base, 1);
9859 org_id = AscReadChipDvcID(iop_base);
9860 for (i = 0; i <= ASC_MAX_TID; i++) {
9861 if (org_id == (0x01 << i))
9862 break;
9864 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
9865 AscWriteChipDvcID(iop_base, id);
9866 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
9867 AscSetBank(iop_base, 0);
9868 AscSetChipSyn(iop_base, sdtr_data);
9869 if (AscGetChipSyn(iop_base) != sdtr_data) {
9870 sta = FALSE;
9872 } else {
9873 sta = FALSE;
9875 AscSetBank(iop_base, 1);
9876 AscWriteChipDvcID(iop_base, org_id);
9877 AscSetBank(iop_base, 0);
9878 return (sta);
9881 static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
9883 uchar i;
9884 ushort s_addr;
9885 PortAddr iop_base;
9886 ushort warn_code;
9888 iop_base = asc_dvc->iop_base;
9889 warn_code = 0;
9890 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
9891 (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) *
9892 64) >> 1)
9894 i = ASC_MIN_ACTIVE_QNO;
9895 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
9896 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9897 (uchar)(i + 1));
9898 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9899 (uchar)(asc_dvc->max_total_qng));
9900 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9901 (uchar)i);
9902 i++;
9903 s_addr += ASC_QBLK_SIZE;
9904 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
9905 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9906 (uchar)(i + 1));
9907 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9908 (uchar)(i - 1));
9909 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9910 (uchar)i);
9912 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD),
9913 (uchar)ASC_QLINK_END);
9914 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD),
9915 (uchar)(asc_dvc->max_total_qng - 1));
9916 AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO),
9917 (uchar)asc_dvc->max_total_qng);
9918 i++;
9919 s_addr += ASC_QBLK_SIZE;
9920 for (; i <= (uchar)(asc_dvc->max_total_qng + 3);
9921 i++, s_addr += ASC_QBLK_SIZE) {
9922 AscWriteLramByte(iop_base,
9923 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i);
9924 AscWriteLramByte(iop_base,
9925 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i);
9926 AscWriteLramByte(iop_base,
9927 (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i);
9929 return (warn_code);
9932 static ushort AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
9934 PortAddr iop_base;
9935 int i;
9936 ushort lram_addr;
9938 iop_base = asc_dvc->iop_base;
9939 AscPutRiscVarFreeQHead(iop_base, 1);
9940 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
9941 AscPutVarFreeQHead(iop_base, 1);
9942 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
9943 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
9944 (uchar)((int)asc_dvc->max_total_qng + 1));
9945 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
9946 (uchar)((int)asc_dvc->max_total_qng + 2));
9947 AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B,
9948 asc_dvc->max_total_qng);
9949 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
9950 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9951 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
9952 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
9953 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
9954 AscPutQDoneInProgress(iop_base, 0);
9955 lram_addr = ASC_QADR_BEG;
9956 for (i = 0; i < 32; i++, lram_addr += 2) {
9957 AscWriteLramWord(iop_base, lram_addr, 0);
9959 return (0);
9962 static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code)
9964 if (asc_dvc->err_code == 0) {
9965 asc_dvc->err_code = err_code;
9966 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
9967 err_code);
9969 return (err_code);
9972 static uchar
9973 AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset)
9975 EXT_MSG sdtr_buf;
9976 uchar sdtr_period_index;
9977 PortAddr iop_base;
9979 iop_base = asc_dvc->iop_base;
9980 sdtr_buf.msg_type = MS_EXTEND;
9981 sdtr_buf.msg_len = MS_SDTR_LEN;
9982 sdtr_buf.msg_req = MS_SDTR_CODE;
9983 sdtr_buf.xfer_period = sdtr_period;
9984 sdtr_offset &= ASC_SYN_MAX_OFFSET;
9985 sdtr_buf.req_ack_offset = sdtr_offset;
9986 if ((sdtr_period_index =
9987 AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
9988 asc_dvc->max_sdtr_index) {
9989 AscMemWordCopyPtrToLram(iop_base,
9990 ASCV_MSGOUT_BEG,
9991 (uchar *)&sdtr_buf,
9992 sizeof(EXT_MSG) >> 1);
9993 return ((sdtr_period_index << 4) | sdtr_offset);
9994 } else {
9996 sdtr_buf.req_ack_offset = 0;
9997 AscMemWordCopyPtrToLram(iop_base,
9998 ASCV_MSGOUT_BEG,
9999 (uchar *)&sdtr_buf,
10000 sizeof(EXT_MSG) >> 1);
10001 return (0);
10005 static uchar
10006 AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset)
10008 uchar byte;
10009 uchar sdtr_period_ix;
10011 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
10012 if ((sdtr_period_ix > asc_dvc->max_sdtr_index)
10014 return (0xFF);
10016 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
10017 return (byte);
10020 static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no)
10022 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
10023 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
10024 return;
10027 static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time)
10029 uchar *period_table;
10030 int max_index;
10031 int min_index;
10032 int i;
10034 period_table = asc_dvc->sdtr_period_tbl;
10035 max_index = (int)asc_dvc->max_sdtr_index;
10036 min_index = (int)asc_dvc->host_init_sdtr_index;
10037 if ((syn_time <= period_table[max_index])) {
10038 for (i = min_index; i < (max_index - 1); i++) {
10039 if (syn_time <= period_table[i]) {
10040 return ((uchar)i);
10043 return ((uchar)max_index);
10044 } else {
10045 return ((uchar)(max_index + 1));
10049 static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head)
10051 ushort q_addr;
10052 uchar next_qp;
10053 uchar q_status;
10055 q_addr = ASC_QNO_TO_QADDR(free_q_head);
10056 q_status = (uchar)AscReadLramByte(iop_base,
10057 (ushort)(q_addr +
10058 ASC_SCSIQ_B_STATUS));
10059 next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD));
10060 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
10061 return (next_qp);
10063 return (ASC_QLINK_END);
10066 static uchar
10067 AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q)
10069 uchar i;
10071 for (i = 0; i < n_free_q; i++) {
10072 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
10073 == ASC_QLINK_END) {
10074 return (ASC_QLINK_END);
10077 return (free_q_head);
10080 static int AscHostReqRiscHalt(PortAddr iop_base)
10082 int count = 0;
10083 int sta = 0;
10084 uchar saved_stop_code;
10086 if (AscIsChipHalted(iop_base))
10087 return (1);
10088 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
10089 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
10090 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP);
10091 do {
10092 if (AscIsChipHalted(iop_base)) {
10093 sta = 1;
10094 break;
10096 DvcSleepMilliSecond(100);
10097 } while (count++ < 20);
10098 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
10099 return (sta);
10102 static int AscStopQueueExe(PortAddr iop_base)
10104 int count = 0;
10106 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
10107 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
10108 ASC_STOP_REQ_RISC_STOP);
10109 do {
10110 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
10111 ASC_STOP_ACK_RISC_STOP) {
10112 return (1);
10114 DvcSleepMilliSecond(100);
10115 } while (count++ < 20);
10117 return (0);
10120 static void DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
10122 udelay(micro_sec);
10125 static void DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
10127 udelay((nano_sec + 999) / 1000);
10130 static int AscStartChip(PortAddr iop_base)
10132 AscSetChipControl(iop_base, 0);
10133 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
10134 return (0);
10136 return (1);
10139 static int AscStopChip(PortAddr iop_base)
10141 uchar cc_val;
10143 cc_val =
10144 AscGetChipControl(iop_base) &
10145 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
10146 AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT));
10147 AscSetChipIH(iop_base, INS_HALT);
10148 AscSetChipIH(iop_base, INS_RFLAG_WTM);
10149 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
10150 return (0);
10152 return (1);
10155 static int AscIsChipHalted(PortAddr iop_base)
10157 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
10158 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
10159 return (1);
10162 return (0);
10165 static void AscSetChipIH(PortAddr iop_base, ushort ins_code)
10167 AscSetBank(iop_base, 1);
10168 AscWriteChipIH(iop_base, ins_code);
10169 AscSetBank(iop_base, 0);
10170 return;
10173 static void AscAckInterrupt(PortAddr iop_base)
10175 uchar host_flag;
10176 uchar risc_flag;
10177 ushort loop;
10179 loop = 0;
10180 do {
10181 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
10182 if (loop++ > 0x7FFF) {
10183 break;
10185 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
10186 host_flag =
10187 AscReadLramByte(iop_base,
10188 ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
10189 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10190 (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT));
10191 AscSetChipStatus(iop_base, CIW_INT_ACK);
10192 loop = 0;
10193 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
10194 AscSetChipStatus(iop_base, CIW_INT_ACK);
10195 if (loop++ > 3) {
10196 break;
10199 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10200 return;
10203 static void AscDisableInterrupt(PortAddr iop_base)
10205 ushort cfg;
10207 cfg = AscGetChipCfgLsw(iop_base);
10208 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
10209 return;
10212 static void AscEnableInterrupt(PortAddr iop_base)
10214 ushort cfg;
10216 cfg = AscGetChipCfgLsw(iop_base);
10217 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
10218 return;
10221 static void AscSetBank(PortAddr iop_base, uchar bank)
10223 uchar val;
10225 val = AscGetChipControl(iop_base) &
10227 (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET |
10228 CC_CHIP_RESET));
10229 if (bank == 1) {
10230 val |= CC_BANK_ONE;
10231 } else if (bank == 2) {
10232 val |= CC_DIAG | CC_BANK_ONE;
10233 } else {
10234 val &= ~CC_BANK_ONE;
10236 AscSetChipControl(iop_base, val);
10237 return;
10240 static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc)
10242 PortAddr iop_base;
10243 int i = 10;
10245 iop_base = asc_dvc->iop_base;
10246 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE)
10247 && (i-- > 0)) {
10248 DvcSleepMilliSecond(100);
10250 AscStopChip(iop_base);
10251 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
10252 DvcDelayNanoSecond(asc_dvc, 60000);
10253 AscSetChipIH(iop_base, INS_RFLAG_WTM);
10254 AscSetChipIH(iop_base, INS_HALT);
10255 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
10256 AscSetChipControl(iop_base, CC_HALT);
10257 DvcSleepMilliSecond(200);
10258 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10259 AscSetChipStatus(iop_base, 0);
10260 return (AscIsChipHalted(iop_base));
10263 static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type)
10265 if (bus_type & ASC_IS_ISA)
10266 return (ASC_MAX_ISA_DMA_COUNT);
10267 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
10268 return (ASC_MAX_VL_DMA_COUNT);
10269 return (ASC_MAX_PCI_DMA_COUNT);
10272 #ifdef CONFIG_ISA
10273 static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base)
10275 ushort channel;
10277 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
10278 if (channel == 0x03)
10279 return (0);
10280 else if (channel == 0x00)
10281 return (7);
10282 return (channel + 4);
10285 static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel)
10287 ushort cfg_lsw;
10288 uchar value;
10290 if ((dma_channel >= 5) && (dma_channel <= 7)) {
10291 if (dma_channel == 7)
10292 value = 0x00;
10293 else
10294 value = dma_channel - 4;
10295 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
10296 cfg_lsw |= value;
10297 AscSetChipCfgLsw(iop_base, cfg_lsw);
10298 return (AscGetIsaDmaChannel(iop_base));
10300 return (0);
10303 static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value)
10305 speed_value &= 0x07;
10306 AscSetBank(iop_base, 1);
10307 AscWriteChipDmaSpeed(iop_base, speed_value);
10308 AscSetBank(iop_base, 0);
10309 return (AscGetIsaDmaSpeed(iop_base));
10312 static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base)
10314 uchar speed_value;
10316 AscSetBank(iop_base, 1);
10317 speed_value = AscReadChipDmaSpeed(iop_base);
10318 speed_value &= 0x07;
10319 AscSetBank(iop_base, 0);
10320 return (speed_value);
10322 #endif /* CONFIG_ISA */
10324 static ushort __devinit
10325 AscReadPCIConfigWord(ASC_DVC_VAR *asc_dvc, ushort pci_config_offset)
10327 uchar lsb, msb;
10329 lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
10330 msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
10331 return ((ushort)((msb << 8) | lsb));
10334 static ushort __devinit AscInitGetConfig(ASC_DVC_VAR *asc_dvc)
10336 ushort warn_code;
10337 PortAddr iop_base;
10338 ushort PCIDeviceID;
10339 ushort PCIVendorID;
10340 uchar PCIRevisionID;
10341 uchar prevCmdRegBits;
10343 warn_code = 0;
10344 iop_base = asc_dvc->iop_base;
10345 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
10346 if (asc_dvc->err_code != 0) {
10347 return (UW_ERR);
10349 if (asc_dvc->bus_type == ASC_IS_PCI) {
10350 PCIVendorID = AscReadPCIConfigWord(asc_dvc,
10351 AscPCIConfigVendorIDRegister);
10353 PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
10354 AscPCIConfigDeviceIDRegister);
10356 PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
10357 AscPCIConfigRevisionIDRegister);
10359 if (PCIVendorID != PCI_VENDOR_ID_ASP) {
10360 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10362 prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
10363 AscPCIConfigCommandRegister);
10365 if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
10366 AscPCICmdRegBits_IOMemBusMaster) {
10367 DvcWritePCIConfigByte(asc_dvc,
10368 AscPCIConfigCommandRegister,
10369 (prevCmdRegBits |
10370 AscPCICmdRegBits_IOMemBusMaster));
10372 if ((DvcReadPCIConfigByte(asc_dvc,
10373 AscPCIConfigCommandRegister)
10374 & AscPCICmdRegBits_IOMemBusMaster)
10375 != AscPCICmdRegBits_IOMemBusMaster) {
10376 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10379 if ((PCIDeviceID == PCI_DEVICE_ID_ASP_1200A) ||
10380 (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940)) {
10381 DvcWritePCIConfigByte(asc_dvc,
10382 AscPCIConfigLatencyTimer, 0x00);
10383 if (DvcReadPCIConfigByte
10384 (asc_dvc, AscPCIConfigLatencyTimer)
10385 != 0x00) {
10386 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
10388 } else if (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940U) {
10389 if (DvcReadPCIConfigByte(asc_dvc,
10390 AscPCIConfigLatencyTimer) <
10391 0x20) {
10392 DvcWritePCIConfigByte(asc_dvc,
10393 AscPCIConfigLatencyTimer,
10394 0x20);
10396 if (DvcReadPCIConfigByte(asc_dvc,
10397 AscPCIConfigLatencyTimer)
10398 < 0x20) {
10399 warn_code |=
10400 ASC_WARN_SET_PCI_CONFIG_SPACE;
10406 if (AscFindSignature(iop_base)) {
10407 warn_code |= AscInitAscDvcVar(asc_dvc);
10408 warn_code |= AscInitFromEEP(asc_dvc);
10409 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
10410 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
10411 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
10413 } else {
10414 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10416 return (warn_code);
10419 static ushort __devinit AscInitSetConfig(ASC_DVC_VAR *asc_dvc)
10421 ushort warn_code = 0;
10423 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
10424 if (asc_dvc->err_code != 0)
10425 return (UW_ERR);
10426 if (AscFindSignature(asc_dvc->iop_base)) {
10427 warn_code |= AscInitFromAscDvcVar(asc_dvc);
10428 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
10429 } else {
10430 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10432 return (warn_code);
10435 static ushort __devinit AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc)
10437 PortAddr iop_base;
10438 ushort cfg_msw;
10439 ushort warn_code;
10440 ushort pci_device_id = 0;
10442 iop_base = asc_dvc->iop_base;
10443 #ifdef CONFIG_PCI
10444 if (asc_dvc->cfg->dev)
10445 pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device;
10446 #endif
10447 warn_code = 0;
10448 cfg_msw = AscGetChipCfgMsw(iop_base);
10449 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10450 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10451 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10452 AscSetChipCfgMsw(iop_base, cfg_msw);
10454 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
10455 asc_dvc->cfg->cmd_qng_enabled) {
10456 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
10457 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10459 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10460 warn_code |= ASC_WARN_AUTO_CONFIG;
10462 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
10463 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
10464 != asc_dvc->irq_no) {
10465 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
10468 if (asc_dvc->bus_type & ASC_IS_PCI) {
10469 cfg_msw &= 0xFFC0;
10470 AscSetChipCfgMsw(iop_base, cfg_msw);
10471 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
10472 } else {
10473 if ((pci_device_id == PCI_DEVICE_ID_ASP_1200A) ||
10474 (pci_device_id == PCI_DEVICE_ID_ASP_ABP940)) {
10475 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
10476 asc_dvc->bug_fix_cntl |=
10477 ASC_BUG_FIX_ASYN_USE_SYN;
10480 } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
10481 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
10482 == ASC_CHIP_VER_ASYN_BUG) {
10483 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
10486 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
10487 asc_dvc->cfg->chip_scsi_id) {
10488 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
10490 #ifdef CONFIG_ISA
10491 if (asc_dvc->bus_type & ASC_IS_ISA) {
10492 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
10493 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
10495 #endif /* CONFIG_ISA */
10496 return (warn_code);
10499 static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
10501 ushort warn_code;
10502 PortAddr iop_base;
10504 iop_base = asc_dvc->iop_base;
10505 warn_code = 0;
10506 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
10507 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
10508 AscResetChipAndScsiBus(asc_dvc);
10509 DvcSleepMilliSecond((ASC_DCNT)
10510 ((ushort)asc_dvc->scsi_reset_wait * 1000));
10512 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
10513 if (asc_dvc->err_code != 0)
10514 return (UW_ERR);
10515 if (!AscFindSignature(asc_dvc->iop_base)) {
10516 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
10517 return (warn_code);
10519 AscDisableInterrupt(iop_base);
10520 warn_code |= AscInitLram(asc_dvc);
10521 if (asc_dvc->err_code != 0)
10522 return (UW_ERR);
10523 ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
10524 (ulong)_asc_mcode_chksum);
10525 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
10526 _asc_mcode_size) != _asc_mcode_chksum) {
10527 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
10528 return (warn_code);
10530 warn_code |= AscInitMicroCodeVar(asc_dvc);
10531 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
10532 AscEnableInterrupt(iop_base);
10533 return (warn_code);
10536 static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc)
10538 int i;
10539 PortAddr iop_base;
10540 ushort warn_code;
10541 uchar chip_version;
10543 iop_base = asc_dvc->iop_base;
10544 warn_code = 0;
10545 asc_dvc->err_code = 0;
10546 if ((asc_dvc->bus_type &
10547 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
10548 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
10550 AscSetChipControl(iop_base, CC_HALT);
10551 AscSetChipStatus(iop_base, 0);
10552 asc_dvc->bug_fix_cntl = 0;
10553 asc_dvc->pci_fix_asyn_xfer = 0;
10554 asc_dvc->pci_fix_asyn_xfer_always = 0;
10555 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
10556 asc_dvc->sdtr_done = 0;
10557 asc_dvc->cur_total_qng = 0;
10558 asc_dvc->is_in_int = 0;
10559 asc_dvc->in_critical_cnt = 0;
10560 asc_dvc->last_q_shortage = 0;
10561 asc_dvc->use_tagged_qng = 0;
10562 asc_dvc->no_scam = 0;
10563 asc_dvc->unit_not_ready = 0;
10564 asc_dvc->queue_full_or_busy = 0;
10565 asc_dvc->redo_scam = 0;
10566 asc_dvc->res2 = 0;
10567 asc_dvc->host_init_sdtr_index = 0;
10568 asc_dvc->cfg->can_tagged_qng = 0;
10569 asc_dvc->cfg->cmd_qng_enabled = 0;
10570 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
10571 asc_dvc->init_sdtr = 0;
10572 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
10573 asc_dvc->scsi_reset_wait = 3;
10574 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
10575 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
10576 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
10577 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
10578 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
10579 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
10580 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
10581 ASC_LIB_VERSION_MINOR;
10582 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
10583 asc_dvc->cfg->chip_version = chip_version;
10584 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
10585 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
10586 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
10587 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
10588 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
10589 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
10590 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
10591 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
10592 asc_dvc->max_sdtr_index = 7;
10593 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
10594 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
10595 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
10596 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
10597 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
10598 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
10599 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
10600 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
10601 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
10602 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
10603 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
10604 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
10605 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
10606 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
10607 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
10608 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
10609 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
10610 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
10611 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
10612 asc_dvc->max_sdtr_index = 15;
10613 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) {
10614 AscSetExtraControl(iop_base,
10615 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10616 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
10617 AscSetExtraControl(iop_base,
10618 (SEC_ACTIVE_NEGATE |
10619 SEC_ENABLE_FILTER));
10622 if (asc_dvc->bus_type == ASC_IS_PCI) {
10623 AscSetExtraControl(iop_base,
10624 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
10627 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
10628 if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
10629 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
10630 asc_dvc->bus_type = ASC_IS_ISAPNP;
10632 #ifdef CONFIG_ISA
10633 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
10634 asc_dvc->cfg->isa_dma_channel =
10635 (uchar)AscGetIsaDmaChannel(iop_base);
10637 #endif /* CONFIG_ISA */
10638 for (i = 0; i <= ASC_MAX_TID; i++) {
10639 asc_dvc->cur_dvc_qng[i] = 0;
10640 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
10641 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *)0L;
10642 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L;
10643 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
10645 return (warn_code);
10648 static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
10650 ASCEEP_CONFIG eep_config_buf;
10651 ASCEEP_CONFIG *eep_config;
10652 PortAddr iop_base;
10653 ushort chksum;
10654 ushort warn_code;
10655 ushort cfg_msw, cfg_lsw;
10656 int i;
10657 int write_eep = 0;
10659 iop_base = asc_dvc->iop_base;
10660 warn_code = 0;
10661 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
10662 AscStopQueueExe(iop_base);
10663 if ((AscStopChip(iop_base) == FALSE) ||
10664 (AscGetChipScsiCtrl(iop_base) != 0)) {
10665 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
10666 AscResetChipAndScsiBus(asc_dvc);
10667 DvcSleepMilliSecond((ASC_DCNT)
10668 ((ushort)asc_dvc->scsi_reset_wait * 1000));
10670 if (AscIsChipHalted(iop_base) == FALSE) {
10671 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10672 return (warn_code);
10674 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10675 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10676 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10677 return (warn_code);
10679 eep_config = (ASCEEP_CONFIG *)&eep_config_buf;
10680 cfg_msw = AscGetChipCfgMsw(iop_base);
10681 cfg_lsw = AscGetChipCfgLsw(iop_base);
10682 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
10683 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
10684 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
10685 AscSetChipCfgMsw(iop_base, cfg_msw);
10687 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
10688 ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
10689 if (chksum == 0) {
10690 chksum = 0xaa55;
10692 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
10693 warn_code |= ASC_WARN_AUTO_CONFIG;
10694 if (asc_dvc->cfg->chip_version == 3) {
10695 if (eep_config->cfg_lsw != cfg_lsw) {
10696 warn_code |= ASC_WARN_EEPROM_RECOVER;
10697 eep_config->cfg_lsw =
10698 AscGetChipCfgLsw(iop_base);
10700 if (eep_config->cfg_msw != cfg_msw) {
10701 warn_code |= ASC_WARN_EEPROM_RECOVER;
10702 eep_config->cfg_msw =
10703 AscGetChipCfgMsw(iop_base);
10707 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
10708 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
10709 ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
10710 eep_config->chksum);
10711 if (chksum != eep_config->chksum) {
10712 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
10713 ASC_CHIP_VER_PCI_ULTRA_3050) {
10714 ASC_DBG(1,
10715 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
10716 eep_config->init_sdtr = 0xFF;
10717 eep_config->disc_enable = 0xFF;
10718 eep_config->start_motor = 0xFF;
10719 eep_config->use_cmd_qng = 0;
10720 eep_config->max_total_qng = 0xF0;
10721 eep_config->max_tag_qng = 0x20;
10722 eep_config->cntl = 0xBFFF;
10723 ASC_EEP_SET_CHIP_ID(eep_config, 7);
10724 eep_config->no_scam = 0;
10725 eep_config->adapter_info[0] = 0;
10726 eep_config->adapter_info[1] = 0;
10727 eep_config->adapter_info[2] = 0;
10728 eep_config->adapter_info[3] = 0;
10729 eep_config->adapter_info[4] = 0;
10730 /* Indicate EEPROM-less board. */
10731 eep_config->adapter_info[5] = 0xBB;
10732 } else {
10733 ASC_PRINT
10734 ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
10735 write_eep = 1;
10736 warn_code |= ASC_WARN_EEPROM_CHKSUM;
10739 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
10740 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
10741 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
10742 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
10743 asc_dvc->start_motor = eep_config->start_motor;
10744 asc_dvc->dvc_cntl = eep_config->cntl;
10745 asc_dvc->no_scam = eep_config->no_scam;
10746 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
10747 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
10748 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
10749 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
10750 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
10751 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
10752 if (!AscTestExternalLram(asc_dvc)) {
10753 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) ==
10754 ASC_IS_PCI_ULTRA)) {
10755 eep_config->max_total_qng =
10756 ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
10757 eep_config->max_tag_qng =
10758 ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
10759 } else {
10760 eep_config->cfg_msw |= 0x0800;
10761 cfg_msw |= 0x0800;
10762 AscSetChipCfgMsw(iop_base, cfg_msw);
10763 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
10764 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
10766 } else {
10768 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
10769 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
10771 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
10772 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
10774 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
10775 eep_config->max_tag_qng = eep_config->max_total_qng;
10777 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
10778 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
10780 asc_dvc->max_total_qng = eep_config->max_total_qng;
10781 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
10782 eep_config->use_cmd_qng) {
10783 eep_config->disc_enable = eep_config->use_cmd_qng;
10784 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
10786 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
10787 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
10789 ASC_EEP_SET_CHIP_ID(eep_config,
10790 ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
10791 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
10792 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
10793 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
10794 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
10797 for (i = 0; i <= ASC_MAX_TID; i++) {
10798 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
10799 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
10800 asc_dvc->cfg->sdtr_period_offset[i] =
10801 (uchar)(ASC_DEF_SDTR_OFFSET |
10802 (asc_dvc->host_init_sdtr_index << 4));
10804 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
10805 if (write_eep) {
10806 if ((i =
10807 AscSetEEPConfig(iop_base, eep_config,
10808 asc_dvc->bus_type)) != 0) {
10809 ASC_PRINT1
10810 ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n",
10812 } else {
10813 ASC_PRINT
10814 ("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
10817 return (warn_code);
10820 static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
10822 int i;
10823 ushort warn_code;
10824 PortAddr iop_base;
10825 ASC_PADDR phy_addr;
10826 ASC_DCNT phy_size;
10828 iop_base = asc_dvc->iop_base;
10829 warn_code = 0;
10830 for (i = 0; i <= ASC_MAX_TID; i++) {
10831 AscPutMCodeInitSDTRAtID(iop_base, i,
10832 asc_dvc->cfg->sdtr_period_offset[i]
10836 AscInitQLinkVar(asc_dvc);
10837 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
10838 asc_dvc->cfg->disc_enable);
10839 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
10840 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
10842 /* Align overrun buffer on an 8 byte boundary. */
10843 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
10844 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
10845 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
10846 (uchar *)&phy_addr, 1);
10847 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
10848 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
10849 (uchar *)&phy_size, 1);
10851 asc_dvc->cfg->mcode_date =
10852 AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W);
10853 asc_dvc->cfg->mcode_version =
10854 AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W);
10856 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
10857 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
10858 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
10859 return (warn_code);
10861 if (AscStartChip(iop_base) != 1) {
10862 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
10863 return (warn_code);
10866 return (warn_code);
10869 static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc)
10871 PortAddr iop_base;
10872 ushort q_addr;
10873 ushort saved_word;
10874 int sta;
10876 iop_base = asc_dvc->iop_base;
10877 sta = 0;
10878 q_addr = ASC_QNO_TO_QADDR(241);
10879 saved_word = AscReadLramWord(iop_base, q_addr);
10880 AscSetChipLramAddr(iop_base, q_addr);
10881 AscSetChipLramData(iop_base, 0x55AA);
10882 DvcSleepMilliSecond(10);
10883 AscSetChipLramAddr(iop_base, q_addr);
10884 if (AscGetChipLramData(iop_base) == 0x55AA) {
10885 sta = 1;
10886 AscWriteLramWord(iop_base, q_addr, saved_word);
10888 return (sta);
10891 static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg)
10893 uchar read_back;
10894 int retry;
10896 retry = 0;
10897 while (TRUE) {
10898 AscSetChipEEPCmd(iop_base, cmd_reg);
10899 DvcSleepMilliSecond(1);
10900 read_back = AscGetChipEEPCmd(iop_base);
10901 if (read_back == cmd_reg) {
10902 return (1);
10904 if (retry++ > ASC_EEP_MAX_RETRY) {
10905 return (0);
10910 static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg)
10912 ushort read_back;
10913 int retry;
10915 retry = 0;
10916 while (TRUE) {
10917 AscSetChipEEPData(iop_base, data_reg);
10918 DvcSleepMilliSecond(1);
10919 read_back = AscGetChipEEPData(iop_base);
10920 if (read_back == data_reg) {
10921 return (1);
10923 if (retry++ > ASC_EEP_MAX_RETRY) {
10924 return (0);
10929 static void __devinit AscWaitEEPRead(void)
10931 DvcSleepMilliSecond(1);
10932 return;
10935 static void __devinit AscWaitEEPWrite(void)
10937 DvcSleepMilliSecond(20);
10938 return;
10941 static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr)
10943 ushort read_wval;
10944 uchar cmd_reg;
10946 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
10947 AscWaitEEPRead();
10948 cmd_reg = addr | ASC_EEP_CMD_READ;
10949 AscWriteEEPCmdReg(iop_base, cmd_reg);
10950 AscWaitEEPRead();
10951 read_wval = AscGetChipEEPData(iop_base);
10952 AscWaitEEPRead();
10953 return (read_wval);
10956 static ushort __devinit
10957 AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val)
10959 ushort read_wval;
10961 read_wval = AscReadEEPWord(iop_base, addr);
10962 if (read_wval != word_val) {
10963 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
10964 AscWaitEEPRead();
10965 AscWriteEEPDataReg(iop_base, word_val);
10966 AscWaitEEPRead();
10967 AscWriteEEPCmdReg(iop_base,
10968 (uchar)((uchar)ASC_EEP_CMD_WRITE | addr));
10969 AscWaitEEPWrite();
10970 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
10971 AscWaitEEPRead();
10972 return (AscReadEEPWord(iop_base, addr));
10974 return (read_wval);
10977 static ushort __devinit
10978 AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
10980 ushort wval;
10981 ushort sum;
10982 ushort *wbuf;
10983 int cfg_beg;
10984 int cfg_end;
10985 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
10986 int s_addr;
10988 wbuf = (ushort *)cfg_buf;
10989 sum = 0;
10990 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
10991 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
10992 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
10993 sum += *wbuf;
10995 if (bus_type & ASC_IS_VL) {
10996 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
10997 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
10998 } else {
10999 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11000 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11002 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11003 wval = AscReadEEPWord(iop_base, (uchar)s_addr);
11004 if (s_addr <= uchar_end_in_config) {
11006 * Swap all char fields - must unswap bytes already swapped
11007 * by AscReadEEPWord().
11009 *wbuf = le16_to_cpu(wval);
11010 } else {
11011 /* Don't swap word field at the end - cntl field. */
11012 *wbuf = wval;
11014 sum += wval; /* Checksum treats all EEPROM data as words. */
11017 * Read the checksum word which will be compared against 'sum'
11018 * by the caller. Word field already swapped.
11020 *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr);
11021 return (sum);
11024 static int __devinit
11025 AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11027 int n_error;
11028 ushort *wbuf;
11029 ushort word;
11030 ushort sum;
11031 int s_addr;
11032 int cfg_beg;
11033 int cfg_end;
11034 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
11036 wbuf = (ushort *)cfg_buf;
11037 n_error = 0;
11038 sum = 0;
11039 /* Write two config words; AscWriteEEPWord() will swap bytes. */
11040 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11041 sum += *wbuf;
11042 if (*wbuf != AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11043 n_error++;
11046 if (bus_type & ASC_IS_VL) {
11047 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11048 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11049 } else {
11050 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11051 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11053 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11054 if (s_addr <= uchar_end_in_config) {
11056 * This is a char field. Swap char fields before they are
11057 * swapped again by AscWriteEEPWord().
11059 word = cpu_to_le16(*wbuf);
11060 if (word !=
11061 AscWriteEEPWord(iop_base, (uchar)s_addr, word)) {
11062 n_error++;
11064 } else {
11065 /* Don't swap word field at the end - cntl field. */
11066 if (*wbuf !=
11067 AscWriteEEPWord(iop_base, (uchar)s_addr, *wbuf)) {
11068 n_error++;
11071 sum += *wbuf; /* Checksum calculated from word values. */
11073 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
11074 *wbuf = sum;
11075 if (sum != AscWriteEEPWord(iop_base, (uchar)s_addr, sum)) {
11076 n_error++;
11079 /* Read EEPROM back again. */
11080 wbuf = (ushort *)cfg_buf;
11082 * Read two config words; Byte-swapping done by AscReadEEPWord().
11084 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
11085 if (*wbuf != AscReadEEPWord(iop_base, (uchar)s_addr)) {
11086 n_error++;
11089 if (bus_type & ASC_IS_VL) {
11090 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
11091 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
11092 } else {
11093 cfg_beg = ASC_EEP_DVC_CFG_BEG;
11094 cfg_end = ASC_EEP_MAX_DVC_ADDR;
11096 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
11097 if (s_addr <= uchar_end_in_config) {
11099 * Swap all char fields. Must unswap bytes already swapped
11100 * by AscReadEEPWord().
11102 word =
11103 le16_to_cpu(AscReadEEPWord
11104 (iop_base, (uchar)s_addr));
11105 } else {
11106 /* Don't swap word field at the end - cntl field. */
11107 word = AscReadEEPWord(iop_base, (uchar)s_addr);
11109 if (*wbuf != word) {
11110 n_error++;
11113 /* Read checksum; Byte swapping not needed. */
11114 if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) {
11115 n_error++;
11117 return (n_error);
11120 static int __devinit
11121 AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type)
11123 int retry;
11124 int n_error;
11126 retry = 0;
11127 while (TRUE) {
11128 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
11129 bus_type)) == 0) {
11130 break;
11132 if (++retry > ASC_EEP_MAX_RETRY) {
11133 break;
11136 return (n_error);
11139 static void
11140 AscAsyncFix(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq)
11142 uchar dvc_type;
11143 ASC_SCSI_BIT_ID_TYPE tid_bits;
11145 dvc_type = ASC_INQ_DVC_TYPE(inq);
11146 tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
11148 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) {
11149 if (!(asc_dvc->init_sdtr & tid_bits)) {
11150 if ((dvc_type == TYPE_ROM) &&
11151 (AscCompareString((uchar *)inq->vendor_id,
11152 (uchar *)"HP ", 3) == 0)) {
11153 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
11155 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
11156 if ((dvc_type == TYPE_PROCESSOR) ||
11157 (dvc_type == TYPE_SCANNER) ||
11158 (dvc_type == TYPE_ROM) || (dvc_type == TYPE_TAPE)) {
11159 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
11162 if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
11163 AscSetRunChipSynRegAtID(asc_dvc->iop_base,
11164 tid_no,
11165 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
11169 return;
11172 static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
11174 if ((inq->add_len >= 32) &&
11175 (AscCompareString((uchar *)inq->vendor_id,
11176 (uchar *)"QUANTUM XP34301", 15) == 0) &&
11177 (AscCompareString((uchar *)inq->product_rev_level,
11178 (uchar *)"1071", 4) == 0)) {
11179 return 0;
11181 return 1;
11184 static void
11185 AscInquiryHandling(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq)
11187 ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
11188 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
11190 orig_init_sdtr = asc_dvc->init_sdtr;
11191 orig_use_tagged_qng = asc_dvc->use_tagged_qng;
11193 asc_dvc->init_sdtr &= ~tid_bit;
11194 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
11195 asc_dvc->use_tagged_qng &= ~tid_bit;
11197 if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) {
11198 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) {
11199 asc_dvc->init_sdtr |= tid_bit;
11201 if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) &&
11202 ASC_INQ_CMD_QUEUE(inq)) {
11203 if (AscTagQueuingSafe(inq)) {
11204 asc_dvc->use_tagged_qng |= tid_bit;
11205 asc_dvc->cfg->can_tagged_qng |= tid_bit;
11209 if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
11210 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
11211 asc_dvc->cfg->disc_enable);
11212 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
11213 asc_dvc->use_tagged_qng);
11214 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
11215 asc_dvc->cfg->can_tagged_qng);
11217 asc_dvc->max_dvc_qng[tid_no] =
11218 asc_dvc->cfg->max_tag_qng[tid_no];
11219 AscWriteLramByte(asc_dvc->iop_base,
11220 (ushort)(ASCV_MAX_DVC_QNG_BEG + tid_no),
11221 asc_dvc->max_dvc_qng[tid_no]);
11223 if (orig_init_sdtr != asc_dvc->init_sdtr) {
11224 AscAsyncFix(asc_dvc, tid_no, inq);
11226 return;
11229 static int AscCompareString(uchar *str1, uchar *str2, int len)
11231 int i;
11232 int diff;
11234 for (i = 0; i < len; i++) {
11235 diff = (int)(str1[i] - str2[i]);
11236 if (diff != 0)
11237 return (diff);
11239 return (0);
11242 static uchar AscReadLramByte(PortAddr iop_base, ushort addr)
11244 uchar byte_data;
11245 ushort word_data;
11247 if (isodd_word(addr)) {
11248 AscSetChipLramAddr(iop_base, addr - 1);
11249 word_data = AscGetChipLramData(iop_base);
11250 byte_data = (uchar)((word_data >> 8) & 0xFF);
11251 } else {
11252 AscSetChipLramAddr(iop_base, addr);
11253 word_data = AscGetChipLramData(iop_base);
11254 byte_data = (uchar)(word_data & 0xFF);
11256 return (byte_data);
11259 static ushort AscReadLramWord(PortAddr iop_base, ushort addr)
11261 ushort word_data;
11263 AscSetChipLramAddr(iop_base, addr);
11264 word_data = AscGetChipLramData(iop_base);
11265 return (word_data);
11268 #if CC_VERY_LONG_SG_LIST
11269 static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr)
11271 ushort val_low, val_high;
11272 ASC_DCNT dword_data;
11274 AscSetChipLramAddr(iop_base, addr);
11275 val_low = AscGetChipLramData(iop_base);
11276 val_high = AscGetChipLramData(iop_base);
11277 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
11278 return (dword_data);
11280 #endif /* CC_VERY_LONG_SG_LIST */
11282 static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val)
11284 AscSetChipLramAddr(iop_base, addr);
11285 AscSetChipLramData(iop_base, word_val);
11286 return;
11289 static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
11291 ushort word_data;
11293 if (isodd_word(addr)) {
11294 addr--;
11295 word_data = AscReadLramWord(iop_base, addr);
11296 word_data &= 0x00FF;
11297 word_data |= (((ushort)byte_val << 8) & 0xFF00);
11298 } else {
11299 word_data = AscReadLramWord(iop_base, addr);
11300 word_data &= 0xFF00;
11301 word_data |= ((ushort)byte_val & 0x00FF);
11303 AscWriteLramWord(iop_base, addr, word_data);
11304 return;
11308 * Copy 2 bytes to LRAM.
11310 * The source data is assumed to be in little-endian order in memory
11311 * and is maintained in little-endian order when written to LRAM.
11313 static void
11314 AscMemWordCopyPtrToLram(PortAddr iop_base,
11315 ushort s_addr, uchar *s_buffer, int words)
11317 int i;
11319 AscSetChipLramAddr(iop_base, s_addr);
11320 for (i = 0; i < 2 * words; i += 2) {
11322 * On a little-endian system the second argument below
11323 * produces a little-endian ushort which is written to
11324 * LRAM in little-endian order. On a big-endian system
11325 * the second argument produces a big-endian ushort which
11326 * is "transparently" byte-swapped by outpw() and written
11327 * in little-endian order to LRAM.
11329 outpw(iop_base + IOP_RAM_DATA,
11330 ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]);
11332 return;
11336 * Copy 4 bytes to LRAM.
11338 * The source data is assumed to be in little-endian order in memory
11339 * and is maintained in little-endian order when writen to LRAM.
11341 static void
11342 AscMemDWordCopyPtrToLram(PortAddr iop_base,
11343 ushort s_addr, uchar *s_buffer, int dwords)
11345 int i;
11347 AscSetChipLramAddr(iop_base, s_addr);
11348 for (i = 0; i < 4 * dwords; i += 4) {
11349 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
11350 outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
11352 return;
11356 * Copy 2 bytes from LRAM.
11358 * The source data is assumed to be in little-endian order in LRAM
11359 * and is maintained in little-endian order when written to memory.
11361 static void
11362 AscMemWordCopyPtrFromLram(PortAddr iop_base,
11363 ushort s_addr, uchar *d_buffer, int words)
11365 int i;
11366 ushort word;
11368 AscSetChipLramAddr(iop_base, s_addr);
11369 for (i = 0; i < 2 * words; i += 2) {
11370 word = inpw(iop_base + IOP_RAM_DATA);
11371 d_buffer[i] = word & 0xff;
11372 d_buffer[i + 1] = (word >> 8) & 0xff;
11374 return;
11377 static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words)
11379 ASC_DCNT sum;
11380 int i;
11382 sum = 0L;
11383 for (i = 0; i < words; i++, s_addr += 2) {
11384 sum += AscReadLramWord(iop_base, s_addr);
11386 return (sum);
11389 static void
11390 AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words)
11392 int i;
11394 AscSetChipLramAddr(iop_base, s_addr);
11395 for (i = 0; i < words; i++) {
11396 AscSetChipLramData(iop_base, set_wval);
11398 return;
11402 * --- Adv Library Functions
11405 /* a_mcode.h */
11407 /* Microcode buffer is kept after initialization for error recovery. */
11408 static unsigned char _adv_asc3550_buf[] = {
11409 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
11410 0x01, 0x00, 0x48, 0xe4,
11411 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff,
11412 0x28, 0x0e, 0x9e, 0xe7,
11413 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7,
11414 0x55, 0xf0, 0x01, 0xf6,
11415 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
11416 0x00, 0xec, 0x85, 0xf0,
11417 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0,
11418 0x86, 0xf0, 0xb4, 0x00,
11419 0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00,
11420 0xaa, 0x18, 0x02, 0x80,
11421 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
11422 0x00, 0x57, 0x01, 0xea,
11423 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80,
11424 0x03, 0xe6, 0xb6, 0x00,
11425 0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12,
11426 0x02, 0x4a, 0xb9, 0x54,
11427 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
11428 0x3e, 0x00, 0x80, 0x00,
11429 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
11430 0x74, 0x01, 0x76, 0x01,
11431 0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13,
11432 0x4c, 0x1c, 0xbb, 0x55,
11433 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
11434 0x03, 0xf7, 0x06, 0xf7,
11435 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08,
11436 0x30, 0x13, 0x64, 0x15,
11437 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c,
11438 0x04, 0xea, 0x5d, 0xf0,
11439 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
11440 0xcc, 0x00, 0x20, 0x01,
11441 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13,
11442 0x40, 0x13, 0x30, 0x1c,
11443 0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
11444 0x59, 0xf0, 0xa7, 0xf0,
11445 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
11446 0xa4, 0x00, 0xb5, 0x00,
11447 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a,
11448 0x14, 0x0e, 0x02, 0x10,
11449 0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13,
11450 0x10, 0x15, 0x14, 0x15,
11451 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
11452 0x91, 0x44, 0x0a, 0x45,
11453 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58,
11454 0x83, 0x59, 0x05, 0xe6,
11455 0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8,
11456 0x02, 0xfa, 0x03, 0xfa,
11457 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
11458 0x9e, 0x00, 0xa8, 0x00,
11459 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01,
11460 0x7a, 0x01, 0xc0, 0x01,
11461 0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08,
11462 0x69, 0x08, 0xba, 0x08,
11463 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
11464 0xf1, 0x10, 0x06, 0x12,
11465 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14,
11466 0x8a, 0x15, 0xc6, 0x17,
11467 0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
11468 0x0e, 0x47, 0x48, 0x47,
11469 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
11470 0x14, 0x56, 0x77, 0x57,
11471 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c,
11472 0xf0, 0x29, 0x02, 0xfe,
11473 0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf,
11474 0xfe, 0x80, 0x01, 0xff,
11475 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
11476 0x00, 0xfe, 0x57, 0x24,
11477 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09,
11478 0x00, 0x00, 0xff, 0x08,
11479 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
11480 0xff, 0xff, 0xff, 0x0f,
11481 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
11482 0xfe, 0x04, 0xf7, 0xcf,
11483 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67,
11484 0x0b, 0x3c, 0x2a, 0xfe,
11485 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0,
11486 0xfe, 0xf0, 0x01, 0xfe,
11487 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
11488 0x02, 0xfe, 0xd4, 0x0c,
11489 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
11490 0x1c, 0x05, 0xfe, 0xa6,
11491 0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48,
11492 0xf0, 0xfe, 0x86, 0x02,
11493 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
11494 0xfe, 0x46, 0xf0, 0xfe,
11495 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
11496 0x44, 0x02, 0xfe, 0x44,
11497 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b,
11498 0xa0, 0x17, 0x06, 0x18,
11499 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
11500 0x1e, 0x1c, 0xfe, 0xe9,
11501 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7,
11502 0x0a, 0x6b, 0x01, 0x9e,
11503 0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b,
11504 0x01, 0x82, 0xfe, 0xbd,
11505 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
11506 0x58, 0x1c, 0x17, 0x06,
11507 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21,
11508 0xfe, 0x94, 0x02, 0xfe,
11509 0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97,
11510 0x01, 0xfe, 0x54, 0x0f,
11511 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
11512 0x69, 0x10, 0x17, 0x06,
11513 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05,
11514 0xf6, 0xc7, 0x01, 0xfe,
11515 0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6,
11516 0x02, 0x29, 0x0a, 0x40,
11517 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
11518 0x58, 0x0a, 0x99, 0x01,
11519 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29,
11520 0x2a, 0x46, 0xfe, 0x02,
11521 0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc,
11522 0x01, 0xfe, 0x07, 0x4b,
11523 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
11524 0xfe, 0x56, 0x03, 0xfe,
11525 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10,
11526 0xfe, 0x9f, 0xf0, 0xfe,
11527 0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48,
11528 0x1c, 0xeb, 0x09, 0x04,
11529 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
11530 0x01, 0x0e, 0xac, 0x75,
11531 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2,
11532 0xfe, 0x82, 0xf0, 0xfe,
11533 0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25,
11534 0x32, 0x1f, 0xfe, 0xb4,
11535 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
11536 0x0a, 0xf0, 0xfe, 0x7a,
11537 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c,
11538 0x01, 0x33, 0x8f, 0xfe,
11539 0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8,
11540 0xf7, 0xfe, 0x48, 0x1c,
11541 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
11542 0x0a, 0xca, 0x01, 0x0e,
11543 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14,
11544 0x2c, 0x01, 0x33, 0x8f,
11545 0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65,
11546 0xfe, 0x3c, 0x04, 0x1f,
11547 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
11548 0x12, 0x2b, 0xff, 0x02,
11549 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f,
11550 0x22, 0x30, 0x2e, 0xd5,
11551 0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c,
11552 0xfe, 0x4c, 0x54, 0x64,
11553 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
11554 0xfe, 0x2a, 0x13, 0x2f,
11555 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
11556 0xd3, 0xfa, 0xef, 0x86,
11557 0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04,
11558 0x1d, 0xfe, 0x1c, 0x12,
11559 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
11560 0x70, 0x0c, 0x02, 0x22,
11561 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92,
11562 0x01, 0x33, 0x02, 0x29,
11563 0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87,
11564 0x80, 0xfe, 0x31, 0xe4,
11565 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
11566 0xfe, 0x70, 0x12, 0x49,
11567 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe,
11568 0x80, 0x05, 0xfe, 0x31,
11569 0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00,
11570 0x28, 0xfe, 0x42, 0x12,
11571 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
11572 0x11, 0xfe, 0xe3, 0x00,
11573 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
11574 0x64, 0x05, 0x83, 0x24,
11575 0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe,
11576 0x09, 0x48, 0x01, 0x08,
11577 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
11578 0x86, 0x24, 0x06, 0x12,
11579 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47,
11580 0x01, 0xa7, 0x14, 0x92,
11581 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c,
11582 0x02, 0x22, 0x05, 0xfe,
11583 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
11584 0x47, 0x01, 0xa7, 0x26,
11585 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f,
11586 0x01, 0xfe, 0xaa, 0x14,
11587 0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00,
11588 0x05, 0x50, 0xb4, 0x0c,
11589 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
11590 0x13, 0x01, 0xfe, 0x14,
11591 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c,
11592 0xff, 0x02, 0x00, 0x57,
11593 0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe,
11594 0x72, 0x06, 0x49, 0x04,
11595 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
11596 0x06, 0x11, 0x9a, 0x01,
11597 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06,
11598 0x01, 0xa7, 0xec, 0x72,
11599 0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32,
11600 0xfe, 0x0a, 0xf0, 0xfe,
11601 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
11602 0x8d, 0x81, 0x02, 0x22,
11603 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00,
11604 0x01, 0x08, 0x15, 0x00,
11605 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15,
11606 0x00, 0x02, 0xfe, 0x32,
11607 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
11608 0xfe, 0x1b, 0x00, 0x01,
11609 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
11610 0x08, 0x15, 0x06, 0x01,
11611 0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe,
11612 0x9a, 0x81, 0x4b, 0x1d,
11613 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
11614 0x45, 0xfe, 0x32, 0x12,
11615 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0,
11616 0xfe, 0x32, 0x07, 0x8d,
11617 0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a,
11618 0x06, 0x15, 0x19, 0x02,
11619 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
11620 0x90, 0x77, 0xfe, 0xca,
11621 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07,
11622 0x10, 0xfe, 0x0e, 0x12,
11623 0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe,
11624 0x83, 0xe7, 0xc4, 0xa1,
11625 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
11626 0x40, 0x12, 0x58, 0x01,
11627 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6,
11628 0x51, 0x83, 0xfb, 0xfe,
11629 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90,
11630 0xfe, 0x40, 0x50, 0xfe,
11631 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
11632 0xfe, 0x2a, 0x12, 0xfe,
11633 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f,
11634 0x85, 0x01, 0xa8, 0xfe,
11635 0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56,
11636 0x18, 0x57, 0xfb, 0xfe,
11637 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
11638 0x0c, 0x39, 0x18, 0x3a,
11639 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e,
11640 0x11, 0x65, 0xfe, 0x48,
11641 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73,
11642 0xdd, 0xb8, 0xfe, 0x80,
11643 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
11644 0xfe, 0x7a, 0x08, 0x8d,
11645 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9,
11646 0x10, 0x61, 0x04, 0x06,
11647 0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68,
11648 0x12, 0xfe, 0x2e, 0x1c,
11649 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
11650 0x52, 0x12, 0xfe, 0x2c,
11651 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe,
11652 0x08, 0xfe, 0x8a, 0x10,
11653 0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe,
11654 0x24, 0x0a, 0xab, 0xfe,
11655 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
11656 0x1c, 0x12, 0xb5, 0xfe,
11657 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb,
11658 0x1c, 0x06, 0x16, 0x9d,
11659 0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b,
11660 0x14, 0x92, 0x01, 0x33,
11661 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
11662 0xfe, 0x74, 0x18, 0x1c,
11663 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b,
11664 0x01, 0xe6, 0x1e, 0x27,
11665 0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a,
11666 0x09, 0x04, 0x6a, 0xfe,
11667 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
11668 0xfe, 0x83, 0x80, 0xfe,
11669 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63,
11670 0x27, 0xfe, 0x40, 0x59,
11671 0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18,
11672 0x7c, 0xbe, 0x54, 0xbf,
11673 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
11674 0x79, 0x56, 0x68, 0x57,
11675 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5,
11676 0xa2, 0x23, 0x0c, 0x7b,
11677 0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19,
11678 0x16, 0xd7, 0x79, 0x39,
11679 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
11680 0xfe, 0x10, 0x58, 0xfe,
11681 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04,
11682 0x19, 0x16, 0xd7, 0x09,
11683 0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f,
11684 0xfe, 0x10, 0x90, 0xfe,
11685 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
11686 0x11, 0x9b, 0x09, 0x04,
11687 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08,
11688 0xfe, 0x0c, 0x58, 0xfe,
11689 0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04,
11690 0x0b, 0xfe, 0x1a, 0x12,
11691 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
11692 0x14, 0x7a, 0x01, 0x33,
11693 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39,
11694 0xfe, 0xed, 0x19, 0xbf,
11695 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff,
11696 0x34, 0xfe, 0x74, 0x10,
11697 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
11698 0x84, 0x05, 0xcb, 0x1c,
11699 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1,
11700 0xf0, 0xfe, 0xc4, 0x0a,
11701 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe,
11702 0xce, 0xf0, 0xfe, 0xca,
11703 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
11704 0x22, 0x00, 0x02, 0x5a,
11705 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a,
11706 0xfe, 0xd0, 0xf0, 0xfe,
11707 0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f,
11708 0x4c, 0xfe, 0x10, 0x10,
11709 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
11710 0x2a, 0x13, 0xfe, 0x4e,
11711 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1,
11712 0x16, 0x32, 0x2a, 0x73,
11713 0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25,
11714 0x32, 0x8c, 0xfe, 0x48,
11715 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
11716 0xdb, 0x10, 0x11, 0xfe,
11717 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0,
11718 0x22, 0x30, 0x2e, 0xd8,
11719 0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1,
11720 0x45, 0x0f, 0xfe, 0x42,
11721 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
11722 0x09, 0x04, 0x0b, 0xfe,
11723 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28,
11724 0x00, 0x21, 0xfe, 0xa6,
11725 0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00,
11726 0xfe, 0xe2, 0x10, 0x01,
11727 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
11728 0x01, 0x6f, 0x02, 0x29,
11729 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10,
11730 0x01, 0x86, 0x3e, 0x0b,
11731 0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3,
11732 0x3e, 0x0b, 0x0f, 0xfe,
11733 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
11734 0xe8, 0x59, 0x11, 0x2d,
11735 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09,
11736 0x04, 0x0b, 0x84, 0x3e,
11737 0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12,
11738 0x09, 0x04, 0x1b, 0xfe,
11739 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
11740 0x1c, 0x1c, 0xfe, 0x9d,
11741 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f,
11742 0xfe, 0x15, 0x00, 0xfe,
11743 0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10,
11744 0x0f, 0xfe, 0x47, 0x00,
11745 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
11746 0xab, 0x70, 0x05, 0x6b,
11747 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe,
11748 0x1c, 0x42, 0x59, 0x01,
11749 0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31,
11750 0x00, 0x37, 0x97, 0x01,
11751 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
11752 0x1d, 0xfe, 0xce, 0x45,
11753 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75,
11754 0x57, 0x05, 0x51, 0xfe,
11755 0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48,
11756 0x46, 0x09, 0x04, 0x1d,
11757 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
11758 0x99, 0x01, 0x0e, 0xfe,
11759 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51,
11760 0xfe, 0xee, 0x14, 0xee,
11761 0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad,
11762 0x13, 0x02, 0x29, 0x1e,
11763 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
11764 0xce, 0x1e, 0x2d, 0x47,
11765 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06,
11766 0x12, 0x4d, 0x01, 0xfe,
11767 0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe,
11768 0xf0, 0x0d, 0xfe, 0x02,
11769 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
11770 0xf6, 0xfe, 0x34, 0x01,
11771 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13,
11772 0xaf, 0xfe, 0x02, 0xea,
11773 0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c,
11774 0x05, 0xfe, 0x38, 0x01,
11775 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
11776 0x0c, 0xfe, 0x62, 0x01,
11777 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06,
11778 0x03, 0x23, 0x03, 0x1e,
11779 0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe,
11780 0x71, 0x13, 0xfe, 0x24,
11781 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
11782 0xdc, 0xfe, 0x73, 0x57,
11783 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe,
11784 0x80, 0x5d, 0x03, 0xfe,
11785 0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6,
11786 0x75, 0x03, 0x09, 0x04,
11787 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
11788 0xfe, 0x1e, 0x80, 0xe1,
11789 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e,
11790 0x90, 0xa3, 0xfe, 0x3c,
11791 0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82,
11792 0x16, 0x2f, 0x07, 0x2d,
11793 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
11794 0xe8, 0x11, 0xfe, 0xe9,
11795 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe,
11796 0x1e, 0x1c, 0xfe, 0x14,
11797 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01,
11798 0x09, 0x04, 0x4f, 0xfe,
11799 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
11800 0x40, 0x12, 0x20, 0x63,
11801 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08,
11802 0x1c, 0x05, 0xfe, 0xac,
11803 0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05,
11804 0xfe, 0xb0, 0x00, 0xfe,
11805 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
11806 0x24, 0x69, 0x12, 0xc9,
11807 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe,
11808 0x90, 0x4d, 0xfe, 0x91,
11809 0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c,
11810 0xfe, 0x90, 0x4d, 0xfe,
11811 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
11812 0x46, 0x1e, 0x20, 0xed,
11813 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea,
11814 0x70, 0xfe, 0x14, 0x1c,
11815 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee,
11816 0xfe, 0x07, 0xe6, 0x1d,
11817 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
11818 0xfa, 0xef, 0xfe, 0x42,
11819 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0,
11820 0xfe, 0x36, 0x12, 0xf0,
11821 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
11822 0x3d, 0x75, 0x07, 0x10,
11823 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
11824 0x10, 0x07, 0x7e, 0x45,
11825 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74,
11826 0xfe, 0x01, 0xec, 0x97,
11827 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76,
11828 0x27, 0x01, 0xda, 0xfe,
11829 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
11830 0xfe, 0x48, 0x12, 0x07,
11831 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16,
11832 0xfe, 0x3e, 0x11, 0x07,
11833 0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8,
11834 0x11, 0x07, 0x19, 0xfe,
11835 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
11836 0x01, 0x08, 0x8c, 0x43,
11837 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11,
11838 0x7e, 0x02, 0x29, 0x2b,
11839 0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe,
11840 0xfc, 0x10, 0x09, 0x04,
11841 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
11842 0xc6, 0x10, 0x1e, 0x58,
11843 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c,
11844 0x54, 0x18, 0x55, 0x23,
11845 0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01,
11846 0xa5, 0xc0, 0x38, 0xc1,
11847 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
11848 0x05, 0xfa, 0x4e, 0xfe,
11849 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56,
11850 0x0c, 0x56, 0x18, 0x57,
11851 0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe,
11852 0x00, 0x56, 0xfe, 0xa1,
11853 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
11854 0x58, 0xfe, 0x1f, 0x40,
11855 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56,
11856 0x31, 0x57, 0xfe, 0x44,
11857 0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe,
11858 0x8a, 0x50, 0x05, 0x39,
11859 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
11860 0x12, 0xcd, 0x02, 0x5b,
11861 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44,
11862 0x2f, 0x07, 0x9b, 0x21,
11863 0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79,
11864 0x39, 0x68, 0x3a, 0xfe,
11865 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
11866 0x51, 0xfe, 0x8e, 0x51,
11867 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b,
11868 0x01, 0x08, 0x25, 0x32,
11869 0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b,
11870 0x3b, 0x02, 0x44, 0x01,
11871 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
11872 0x01, 0x08, 0x1f, 0xa2,
11873 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c,
11874 0x00, 0x28, 0x84, 0x49,
11875 0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06,
11876 0x78, 0x3d, 0xfe, 0xda,
11877 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
11878 0x05, 0xc6, 0x28, 0x84,
11879 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8,
11880 0x14, 0xfe, 0x03, 0x17,
11881 0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01,
11882 0xfe, 0xaa, 0x14, 0x02,
11883 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
11884 0x21, 0x44, 0x01, 0xfe,
11885 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87,
11886 0xfe, 0x4a, 0xf4, 0x0b,
11887 0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a,
11888 0x85, 0x02, 0x5b, 0x05,
11889 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
11890 0xd8, 0x14, 0x02, 0x5c,
11891 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1,
11892 0x01, 0x08, 0x23, 0x72,
11893 0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca,
11894 0x12, 0x5e, 0x2b, 0x01,
11895 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
11896 0x1c, 0xfe, 0xff, 0x7f,
11897 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00,
11898 0x57, 0x48, 0x8b, 0x1c,
11899 0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02,
11900 0x00, 0x57, 0x48, 0x8b,
11901 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
11902 0x03, 0x0a, 0x50, 0x01,
11903 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00,
11904 0x54, 0xfe, 0x00, 0xf4,
11905 0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe,
11906 0x03, 0x7c, 0x63, 0x27,
11907 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
11908 0xfe, 0x82, 0x4a, 0xfe,
11909 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe,
11910 0x42, 0x48, 0x5f, 0x60,
11911 0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08,
11912 0x1f, 0xfe, 0xa2, 0x14,
11913 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
11914 0xcc, 0x12, 0x49, 0x04,
11915 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe,
11916 0xe8, 0x13, 0x3b, 0x13,
11917 0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55,
11918 0xa1, 0xff, 0x02, 0x83,
11919 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
11920 0x13, 0x06, 0xfe, 0x56,
11921 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe,
11922 0x64, 0x00, 0x17, 0x93,
11923 0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe,
11924 0xc8, 0x00, 0x8e, 0xe4,
11925 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
11926 0x01, 0xba, 0xfe, 0x4e,
11927 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0,
11928 0xfe, 0x60, 0x14, 0xfe,
11929 0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01,
11930 0xfe, 0x22, 0x13, 0x1c,
11931 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
11932 0xfe, 0x9c, 0x14, 0xb7,
11933 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba,
11934 0xfe, 0x9c, 0x14, 0xb7,
11935 0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06,
11936 0xfe, 0xb4, 0x56, 0xfe,
11937 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
11938 0xe5, 0x15, 0x0b, 0x01,
11939 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89,
11940 0x49, 0x01, 0x08, 0x03,
11941 0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6,
11942 0x15, 0x06, 0x01, 0x08,
11943 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
11944 0x4a, 0x01, 0x08, 0x03,
11945 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc,
11946 0xfe, 0x49, 0xf4, 0x00,
11947 0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01,
11948 0x08, 0x2f, 0x07, 0xfe,
11949 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
11950 0x01, 0x43, 0x1e, 0xcd,
11951 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e,
11952 0xed, 0x88, 0x07, 0x10,
11953 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a,
11954 0x80, 0x01, 0x0e, 0x88,
11955 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
11956 0x88, 0x03, 0x0a, 0x42,
11957 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e,
11958 0xfe, 0x80, 0x80, 0xf2,
11959 0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51,
11960 0x01, 0x82, 0x03, 0x17,
11961 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
11962 0xfe, 0x24, 0x1c, 0xfe,
11963 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0,
11964 0x91, 0x1d, 0x66, 0xfe,
11965 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe,
11966 0xda, 0x10, 0x17, 0x10,
11967 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
11968 0x05, 0xfe, 0x66, 0x01,
11969 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06,
11970 0xfe, 0x3c, 0x50, 0x66,
11971 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe,
11972 0x40, 0x16, 0xfe, 0xb6,
11973 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
11974 0x10, 0x71, 0xfe, 0x83,
11975 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90,
11976 0xfe, 0x62, 0x16, 0xfe,
11977 0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19,
11978 0xfe, 0x98, 0xe7, 0x00,
11979 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
11980 0xfe, 0x30, 0xbc, 0xfe,
11981 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
11982 0xc5, 0x90, 0xfe, 0x9a,
11983 0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe,
11984 0x42, 0x10, 0xfe, 0x02,
11985 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
11986 0xfe, 0x1d, 0xf7, 0x4f,
11987 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f,
11988 0x47, 0xfe, 0x83, 0x58,
11989 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11,
11990 0xfe, 0xdd, 0x00, 0x63,
11991 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
11992 0x06, 0x37, 0x95, 0xa9,
11993 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e,
11994 0x18, 0x1c, 0x1a, 0x5d,
11995 0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe,
11996 0xe1, 0x10, 0x78, 0x2c,
11997 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
11998 0x13, 0x3c, 0x8a, 0x0a,
11999 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
12000 0xe3, 0xfe, 0x00, 0xcc,
12001 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01,
12002 0x0e, 0xf2, 0x01, 0x6f,
12003 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
12004 0xf6, 0xfe, 0xd6, 0xf0,
12005 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe,
12006 0x15, 0x00, 0x59, 0x76,
12007 0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35,
12008 0x11, 0x2d, 0x01, 0x6f,
12009 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
12010 0xc8, 0xfe, 0x48, 0x55,
12011 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a,
12012 0x99, 0x01, 0x0e, 0xf0,
12013 0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73,
12014 0x75, 0x03, 0x0a, 0x42,
12015 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
12016 0x0e, 0x73, 0x75, 0x03,
12017 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00,
12018 0xfe, 0x3a, 0x45, 0x5b,
12019 0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00,
12020 0xfe, 0x02, 0xe6, 0x1b,
12021 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
12022 0xfe, 0x94, 0x00, 0xfe,
12023 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02,
12024 0xe6, 0x2c, 0xfe, 0x4e,
12025 0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69,
12026 0x03, 0x07, 0x7a, 0xfe,
12027 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
12028 0x07, 0x1b, 0xfe, 0x5a,
12029 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d,
12030 0x24, 0x2c, 0xdc, 0x07,
12031 0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d,
12032 0x9f, 0xad, 0x03, 0x14,
12033 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
12034 0x03, 0x25, 0xfe, 0xca,
12035 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a,
12036 0x00, 0x00,
12039 static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
12040 static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
12042 /* Microcode buffer is kept after initialization for error recovery. */
12043 static unsigned char _adv_asc38C0800_buf[] = {
12044 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
12045 0x01, 0x00, 0x48, 0xe4,
12046 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff,
12047 0x1c, 0x0f, 0x00, 0xf6,
12048 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6,
12049 0x09, 0xe7, 0x55, 0xf0,
12050 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
12051 0x18, 0xf4, 0x08, 0x00,
12052 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6,
12053 0x86, 0xf0, 0xb1, 0xf0,
12054 0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c,
12055 0x3c, 0x00, 0xbb, 0x00,
12056 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
12057 0xba, 0x13, 0x18, 0x40,
12058 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01,
12059 0x6e, 0x01, 0x74, 0x01,
12060 0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00,
12061 0xc0, 0x00, 0x01, 0x01,
12062 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
12063 0x08, 0x12, 0x02, 0x4a,
12064 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4,
12065 0x5d, 0xf0, 0x02, 0xfa,
12066 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01,
12067 0x68, 0x01, 0x6a, 0x01,
12068 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
12069 0x06, 0x13, 0x4c, 0x1c,
12070 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00,
12071 0x0f, 0x00, 0x47, 0x00,
12072 0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c,
12073 0x4e, 0x1c, 0x10, 0x44,
12074 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
12075 0x05, 0x00, 0x34, 0x00,
12076 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b,
12077 0x42, 0x0c, 0x12, 0x0f,
12078 0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48,
12079 0x00, 0x4e, 0x42, 0x54,
12080 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
12081 0x59, 0xf0, 0xb8, 0xf0,
12082 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00,
12083 0x19, 0x00, 0x33, 0x00,
12084 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00,
12085 0xe7, 0x00, 0xe2, 0x03,
12086 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
12087 0x12, 0x13, 0x24, 0x14,
12088 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c,
12089 0x36, 0x1c, 0x08, 0x44,
12090 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54,
12091 0x3a, 0x55, 0x83, 0x55,
12092 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
12093 0x0c, 0xf0, 0x04, 0xf8,
12094 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00,
12095 0xa8, 0x00, 0xaa, 0x00,
12096 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01,
12097 0xc4, 0x01, 0xc6, 0x01,
12098 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
12099 0x68, 0x08, 0x69, 0x08,
12100 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10,
12101 0xed, 0x10, 0xf1, 0x10,
12102 0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13,
12103 0x1e, 0x13, 0x46, 0x14,
12104 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
12105 0xca, 0x18, 0xe6, 0x19,
12106 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c,
12107 0xf0, 0x2b, 0x02, 0xfe,
12108 0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6,
12109 0xfe, 0x84, 0x01, 0xff,
12110 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
12111 0x00, 0xfe, 0x57, 0x24,
12112 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09,
12113 0x00, 0x00, 0xff, 0x08,
12114 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
12115 0xff, 0xff, 0xff, 0x11,
12116 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
12117 0xfe, 0x04, 0xf7, 0xd6,
12118 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99,
12119 0x0a, 0x42, 0x2c, 0xfe,
12120 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0,
12121 0xfe, 0xf4, 0x01, 0xfe,
12122 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
12123 0x02, 0xfe, 0xc8, 0x0d,
12124 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28,
12125 0x1c, 0x03, 0xfe, 0xa6,
12126 0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48,
12127 0xf0, 0xfe, 0x8a, 0x02,
12128 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
12129 0xfe, 0x46, 0xf0, 0xfe,
12130 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe,
12131 0x48, 0x02, 0xfe, 0x44,
12132 0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a,
12133 0xaa, 0x18, 0x06, 0x14,
12134 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
12135 0x1e, 0x1c, 0xfe, 0xe9,
12136 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce,
12137 0x09, 0x70, 0x01, 0xa8,
12138 0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70,
12139 0x01, 0x87, 0xfe, 0xbd,
12140 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
12141 0x58, 0x1c, 0x18, 0x06,
12142 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23,
12143 0xfe, 0x98, 0x02, 0xfe,
12144 0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2,
12145 0x01, 0xfe, 0x48, 0x10,
12146 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
12147 0x69, 0x10, 0x18, 0x06,
12148 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05,
12149 0xf6, 0xce, 0x01, 0xfe,
12150 0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe,
12151 0x82, 0x16, 0x02, 0x2b,
12152 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
12153 0xfe, 0x41, 0x58, 0x09,
12154 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe,
12155 0x82, 0x16, 0x02, 0x2b,
12156 0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43,
12157 0xfe, 0x77, 0x57, 0xfe,
12158 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
12159 0xfe, 0x40, 0x1c, 0x1c,
12160 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48,
12161 0x03, 0xfe, 0x11, 0xf0,
12162 0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10,
12163 0xfe, 0x11, 0x00, 0x02,
12164 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
12165 0x21, 0x22, 0xa3, 0xb7,
12166 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16,
12167 0x12, 0xd1, 0x1c, 0xd9,
12168 0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12,
12169 0xfe, 0xe4, 0x00, 0x27,
12170 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
12171 0x06, 0xf0, 0xfe, 0xc8,
12172 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03,
12173 0x70, 0x28, 0x17, 0xfe,
12174 0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8,
12175 0xf9, 0x2c, 0x99, 0x19,
12176 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
12177 0x74, 0x01, 0xaf, 0x8c,
12178 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e,
12179 0x8d, 0x51, 0x64, 0x79,
12180 0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b,
12181 0xfe, 0x6a, 0x02, 0x02,
12182 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
12183 0xfe, 0x3c, 0x04, 0x3b,
12184 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02,
12185 0x00, 0x10, 0x01, 0x0b,
12186 0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde,
12187 0xfe, 0x4c, 0x44, 0xfe,
12188 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
12189 0xda, 0x4f, 0x79, 0x2a,
12190 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b,
12191 0xfe, 0x2a, 0x13, 0x32,
12192 0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c,
12193 0x54, 0x6b, 0xda, 0xfe,
12194 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
12195 0x08, 0x13, 0x32, 0x07,
12196 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d,
12197 0x08, 0x05, 0x06, 0x4d,
12198 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24,
12199 0x2d, 0x12, 0xfe, 0xe6,
12200 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
12201 0x02, 0x2b, 0xfe, 0x42,
12202 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
12203 0xfe, 0x87, 0x80, 0xfe,
12204 0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80,
12205 0x07, 0x19, 0xfe, 0x7c,
12206 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
12207 0x17, 0xfe, 0x90, 0x05,
12208 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe,
12209 0xa0, 0x00, 0x28, 0xfe,
12210 0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c,
12211 0x34, 0xfe, 0x89, 0x48,
12212 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
12213 0x12, 0xfe, 0xe3, 0x00,
12214 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe,
12215 0x70, 0x05, 0x88, 0x25,
12216 0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe,
12217 0x09, 0x48, 0xff, 0x02,
12218 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
12219 0x08, 0x53, 0x05, 0xcb,
12220 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08,
12221 0x05, 0x1b, 0xfe, 0x22,
12222 0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe,
12223 0x0d, 0x00, 0x01, 0x36,
12224 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
12225 0x03, 0x5c, 0x28, 0xfe,
12226 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53,
12227 0x05, 0x1f, 0xfe, 0x02,
12228 0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5,
12229 0x01, 0x4b, 0x12, 0xfe,
12230 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
12231 0x12, 0x03, 0x45, 0x28,
12232 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe,
12233 0x43, 0x48, 0xc4, 0xcc,
12234 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4,
12235 0x6e, 0x41, 0x01, 0xb2,
12236 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
12237 0xfe, 0xcc, 0x15, 0x1d,
12238 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03,
12239 0x45, 0xc1, 0x0c, 0x45,
12240 0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe,
12241 0xe2, 0x00, 0x27, 0xdb,
12242 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
12243 0xfe, 0x06, 0xf0, 0xfe,
12244 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12,
12245 0x16, 0x19, 0x01, 0x0b,
12246 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
12247 0xfe, 0x99, 0xa4, 0x01,
12248 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
12249 0x12, 0x08, 0x05, 0x1a,
12250 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
12251 0x0b, 0x16, 0x00, 0x01,
12252 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02,
12253 0xe2, 0x6c, 0x58, 0xbe,
12254 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
12255 0xfe, 0x09, 0x6f, 0xba,
12256 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27,
12257 0xfe, 0x54, 0x07, 0x1c,
12258 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c,
12259 0x07, 0x02, 0x24, 0x01,
12260 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
12261 0x2c, 0x90, 0xfe, 0xae,
12262 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a,
12263 0x37, 0x22, 0x20, 0x07,
12264 0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a,
12265 0xfe, 0x06, 0x10, 0xfe,
12266 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
12267 0x37, 0x01, 0xb3, 0xb8,
12268 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a,
12269 0x50, 0xfe, 0x44, 0x51,
12270 0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e,
12271 0x14, 0x5f, 0xfe, 0x0c,
12272 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
12273 0x14, 0x3e, 0xfe, 0x4a,
12274 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
12275 0x90, 0x0c, 0x60, 0x14,
12276 0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62,
12277 0xfe, 0x44, 0x90, 0xfe,
12278 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
12279 0x0c, 0x5e, 0x14, 0x5f,
12280 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e,
12281 0x14, 0x3c, 0x21, 0x0c,
12282 0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11,
12283 0x27, 0xdd, 0xfe, 0x9e,
12284 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
12285 0x9a, 0x08, 0xc6, 0xfe,
12286 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08,
12287 0x95, 0x86, 0x02, 0x24,
12288 0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05,
12289 0x06, 0xfe, 0x10, 0x12,
12290 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
12291 0x1c, 0x02, 0xfe, 0x18,
12292 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe,
12293 0x2c, 0x1c, 0xfe, 0xaa,
12294 0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe,
12295 0xde, 0x09, 0xfe, 0xb7,
12296 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
12297 0xfe, 0xf1, 0x18, 0xfe,
12298 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe,
12299 0x14, 0x59, 0xfe, 0x95,
12300 0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0,
12301 0xfe, 0xf0, 0x08, 0xb5,
12302 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
12303 0x0b, 0xb6, 0xfe, 0xbf,
12304 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c,
12305 0x12, 0xc2, 0xfe, 0xd2,
12306 0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e,
12307 0x06, 0x17, 0x85, 0xc5,
12308 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
12309 0x9d, 0x01, 0x36, 0x10,
12310 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe,
12311 0x98, 0x80, 0xfe, 0x19,
12312 0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18,
12313 0xfe, 0x44, 0x54, 0xbe,
12314 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
12315 0x02, 0x4a, 0x08, 0x05,
12316 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e,
12317 0x9c, 0x3c, 0xfe, 0x6c,
12318 0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f,
12319 0x3b, 0x40, 0x03, 0x49,
12320 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
12321 0x8f, 0xfe, 0xe3, 0x54,
12322 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe,
12323 0xda, 0x09, 0xfe, 0x8b,
12324 0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa,
12325 0x0a, 0x3a, 0x49, 0x3b,
12326 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
12327 0xad, 0xfe, 0x01, 0x59,
12328 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a,
12329 0x49, 0x8f, 0xfe, 0xe3,
12330 0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02,
12331 0x4a, 0x3a, 0x49, 0x3b,
12332 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
12333 0x02, 0x4a, 0x08, 0x05,
12334 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62,
12335 0xb7, 0xfe, 0x03, 0xa1,
12336 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
12337 0xfe, 0x86, 0x91, 0x6a,
12338 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
12339 0x61, 0x0c, 0x7f, 0x14,
12340 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62,
12341 0x9b, 0x2e, 0x9c, 0x3c,
12342 0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05,
12343 0xfa, 0x3c, 0x01, 0xef,
12344 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
12345 0xe4, 0x08, 0x05, 0x1f,
12346 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37,
12347 0x03, 0x5e, 0x29, 0x5f,
12348 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe,
12349 0xf4, 0x09, 0x08, 0x05,
12350 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
12351 0x81, 0x50, 0xfe, 0x10,
12352 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe,
12353 0x08, 0x09, 0x12, 0xa6,
12354 0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe,
12355 0x08, 0x09, 0xfe, 0x0c,
12356 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
12357 0x08, 0x05, 0x0a, 0xfe,
12358 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1,
12359 0xf0, 0xe2, 0x15, 0x7e,
12360 0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19,
12361 0x57, 0x3d, 0xfe, 0xed,
12362 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
12363 0x00, 0xff, 0x35, 0xfe,
12364 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18,
12365 0x1e, 0x19, 0x8a, 0x03,
12366 0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65,
12367 0xfe, 0xd1, 0xf0, 0xfe,
12368 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
12369 0x10, 0xfe, 0xce, 0xf0,
12370 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b,
12371 0x10, 0xfe, 0x22, 0x00,
12372 0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00,
12373 0x02, 0x65, 0xfe, 0xd0,
12374 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
12375 0x0b, 0x10, 0x58, 0xfe,
12376 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe,
12377 0x12, 0x00, 0x2c, 0x0f,
12378 0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14,
12379 0x0c, 0xbc, 0x17, 0x34,
12380 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
12381 0x0c, 0x1c, 0x34, 0x94,
12382 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01,
12383 0x4b, 0xfe, 0xdb, 0x10,
12384 0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe,
12385 0x89, 0xf0, 0x24, 0x33,
12386 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
12387 0x33, 0x31, 0xdf, 0xbc,
12388 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49,
12389 0x17, 0xfe, 0x2c, 0x0d,
12390 0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54,
12391 0x12, 0x55, 0xfe, 0x28,
12392 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
12393 0x44, 0xfe, 0x28, 0x00,
12394 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26,
12395 0x0f, 0x64, 0x12, 0x2f,
12396 0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44,
12397 0x0a, 0xfe, 0xb4, 0x10,
12398 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
12399 0xfe, 0x34, 0x46, 0xac,
12400 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a,
12401 0x37, 0x01, 0xf5, 0x01,
12402 0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02,
12403 0xfe, 0x2e, 0x03, 0x08,
12404 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
12405 0x1a, 0xfe, 0x58, 0x12,
12406 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
12407 0xfe, 0x50, 0x0d, 0xfe,
12408 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37,
12409 0xfe, 0xa9, 0x10, 0x10,
12410 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
12411 0xfe, 0x13, 0x00, 0xfe,
12412 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe,
12413 0x24, 0x00, 0x8c, 0xb5,
12414 0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a,
12415 0xfe, 0x9d, 0x41, 0xfe,
12416 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
12417 0xb4, 0x15, 0xfe, 0x31,
12418 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06,
12419 0xec, 0xd0, 0xfc, 0x44,
12420 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47,
12421 0x4b, 0x91, 0xfe, 0x75,
12422 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
12423 0x0e, 0xfe, 0x44, 0x48,
12424 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41,
12425 0xfe, 0x41, 0x58, 0x09,
12426 0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe,
12427 0x2e, 0x03, 0x09, 0x5d,
12428 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
12429 0xce, 0x47, 0xfe, 0xad,
12430 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13,
12431 0x59, 0x13, 0x9f, 0x13,
12432 0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe,
12433 0xe0, 0x0e, 0x0f, 0x06,
12434 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
12435 0x3a, 0x01, 0x56, 0xfe,
12436 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec,
12437 0x20, 0x4f, 0xfe, 0x05,
12438 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe,
12439 0x48, 0xf4, 0x0d, 0xfe,
12440 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
12441 0x15, 0x1a, 0x39, 0xa0,
12442 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff,
12443 0x0c, 0xfe, 0x60, 0x01,
12444 0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25,
12445 0x06, 0x13, 0x2f, 0x12,
12446 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
12447 0x22, 0x9f, 0xb7, 0x13,
12448 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39,
12449 0xa0, 0xb4, 0xfe, 0xd9,
12450 0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04,
12451 0xc3, 0xfe, 0x03, 0xdc,
12452 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
12453 0xfe, 0x00, 0xcc, 0x04,
12454 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13,
12455 0xfe, 0x1c, 0x80, 0x07,
12456 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae,
12457 0xfe, 0x0c, 0x90, 0xfe,
12458 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
12459 0x0a, 0xfe, 0x3c, 0x50,
12460 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4,
12461 0x16, 0x08, 0x05, 0x1b,
12462 0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58,
12463 0xfe, 0x2c, 0x13, 0x01,
12464 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
12465 0x0c, 0xfe, 0x64, 0x01,
12466 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03,
12467 0x80, 0x8d, 0xfe, 0x01,
12468 0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64,
12469 0x22, 0x20, 0xfb, 0x79,
12470 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
12471 0x03, 0xfe, 0xae, 0x00,
12473 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe,
12474 0xb2, 0x00, 0xfe, 0x09,
12475 0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c,
12476 0x45, 0x0f, 0x46, 0x52,
12477 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
12478 0x0f, 0x44, 0x11, 0x0f,
12479 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4,
12480 0x25, 0x11, 0x13, 0x20,
12481 0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14,
12482 0x56, 0xfe, 0xd6, 0xf0,
12483 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
12484 0x18, 0x1c, 0x04, 0x42,
12485 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe,
12486 0xf5, 0x13, 0x04, 0x01,
12487 0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
12488 0x13, 0x32, 0x07, 0x2f,
12489 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
12490 0x41, 0x48, 0xfe, 0x45,
12491 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78,
12492 0x07, 0x11, 0xac, 0x09,
12493 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07,
12494 0x82, 0x4e, 0xfe, 0x14,
12495 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
12496 0xfe, 0x01, 0xec, 0xa2,
12497 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79,
12498 0x2a, 0x01, 0xe3, 0xfe,
12499 0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a,
12500 0xfe, 0x48, 0x12, 0x07,
12501 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
12502 0xfe, 0x32, 0x12, 0x07,
12503 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07,
12504 0x1f, 0xfe, 0x12, 0x12,
12505 0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b,
12506 0x94, 0x4b, 0x04, 0x2d,
12507 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
12508 0x32, 0x07, 0xa6, 0xfe,
12509 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05,
12510 0x5a, 0xfe, 0x72, 0x12,
12511 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62,
12512 0xfe, 0x26, 0x13, 0x03,
12513 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
12514 0x0c, 0x7f, 0x0c, 0x80,
12515 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c,
12516 0x3c, 0xfe, 0x04, 0x55,
12517 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe,
12518 0x91, 0x10, 0x03, 0x3f,
12519 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
12520 0x88, 0x9b, 0x2e, 0x9c,
12521 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
12522 0x56, 0x0c, 0x5e, 0x14,
12523 0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40,
12524 0x03, 0x60, 0x29, 0x61,
12525 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
12526 0x50, 0xfe, 0xc6, 0x50,
12527 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d,
12528 0x29, 0x3e, 0xfe, 0x40,
12529 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72,
12530 0x2d, 0x01, 0x0b, 0x1d,
12531 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
12532 0x72, 0x01, 0xaf, 0x1e,
12533 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe,
12534 0x0a, 0x55, 0x35, 0xfe,
12535 0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51,
12536 0x02, 0x72, 0xfe, 0x19,
12537 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
12538 0x1d, 0xe8, 0x33, 0x31,
12539 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01,
12540 0x0b, 0x1c, 0x34, 0x1d,
12541 0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8,
12542 0x33, 0x31, 0xfe, 0xe8,
12543 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
12544 0x05, 0x1f, 0x35, 0xa9,
12545 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda,
12546 0x14, 0x01, 0xaf, 0x8c,
12547 0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a,
12548 0x03, 0x45, 0x28, 0x35,
12549 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
12550 0x03, 0x5c, 0xc1, 0x0c,
12551 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02,
12552 0x89, 0x01, 0x0b, 0x1c,
12553 0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1,
12554 0xfe, 0x42, 0x58, 0xf1,
12555 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
12556 0xf4, 0x06, 0xea, 0x32,
12557 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d,
12558 0x01, 0x0b, 0x26, 0x89,
12559 0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13,
12560 0x26, 0xfe, 0xd4, 0x13,
12561 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
12562 0x13, 0x1c, 0xfe, 0xd0,
12563 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10,
12564 0x0f, 0x71, 0xff, 0x02,
12565 0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe,
12566 0x00, 0x5c, 0x04, 0x0f,
12567 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
12568 0xfe, 0x00, 0x5c, 0x04,
12569 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff,
12570 0x02, 0x00, 0x57, 0x52,
12571 0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01,
12572 0x87, 0x04, 0xfe, 0x03,
12573 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
12574 0xfe, 0x00, 0x7d, 0xfe,
12575 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e,
12576 0x14, 0x5f, 0x57, 0x3f,
12577 0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83,
12578 0x5a, 0x8d, 0x04, 0x01,
12579 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
12580 0xfe, 0x96, 0x15, 0x33,
12581 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8,
12582 0x0a, 0xfe, 0xc1, 0x59,
12583 0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13,
12584 0x21, 0x69, 0x1a, 0xee,
12585 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
12586 0x30, 0xfe, 0x78, 0x10,
12587 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae,
12588 0x98, 0xfe, 0x30, 0x00,
12589 0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed,
12590 0x98, 0xfe, 0x64, 0x00,
12591 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
12592 0x10, 0x69, 0x06, 0xfe,
12593 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00,
12594 0x18, 0x59, 0x0f, 0x06,
12595 0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe,
12596 0x43, 0xf4, 0x9f, 0xfe,
12597 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
12598 0x9e, 0xfe, 0xf3, 0x10,
12599 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00,
12600 0x17, 0xfe, 0x4d, 0xe4,
12601 0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00,
12602 0x17, 0xfe, 0x4d, 0xe4,
12603 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
12604 0xf4, 0x00, 0xe9, 0x91,
12605 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a,
12606 0x04, 0x16, 0x06, 0x01,
12607 0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01,
12608 0x0b, 0x26, 0xf3, 0x76,
12609 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
12610 0x16, 0x19, 0x01, 0x0b,
12611 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01,
12612 0x0b, 0x26, 0xb1, 0x76,
12613 0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06,
12614 0xfe, 0x48, 0x13, 0xb8,
12615 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
12616 0xec, 0xfe, 0x27, 0x01,
12617 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32,
12618 0x07, 0xfe, 0xe3, 0x00,
12619 0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b,
12620 0x22, 0xd4, 0x07, 0x06,
12621 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
12622 0x07, 0x11, 0xae, 0x09,
12623 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01,
12624 0x0e, 0x8e, 0xfe, 0x80,
12625 0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04,
12626 0x09, 0x48, 0x01, 0x0e,
12627 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
12628 0x80, 0xfe, 0x80, 0x4c,
12629 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c,
12630 0x09, 0x5d, 0x01, 0x87,
12631 0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe,
12632 0x19, 0xde, 0xfe, 0x24,
12633 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
12634 0x17, 0xad, 0x9a, 0x1b,
12635 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde,
12636 0x16, 0xfe, 0xda, 0x10,
12637 0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe,
12638 0x18, 0x58, 0x03, 0xfe,
12639 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
12640 0xf4, 0x06, 0xfe, 0x3c,
12641 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f,
12642 0x97, 0xfe, 0x38, 0x17,
12643 0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c,
12644 0x10, 0x18, 0x11, 0x75,
12645 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
12646 0x2e, 0x97, 0xfe, 0x5a,
12647 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19,
12648 0xfe, 0x98, 0xe7, 0x00,
12649 0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75,
12650 0xfe, 0x30, 0xbc, 0xfe,
12651 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
12652 0xcb, 0x97, 0xfe, 0x92,
12653 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe,
12654 0x42, 0x10, 0xfe, 0x02,
12655 0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe,
12656 0x03, 0xa1, 0xfe, 0x1d,
12657 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
12658 0x9a, 0x5b, 0x41, 0xfe,
12659 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7,
12660 0x11, 0x12, 0xfe, 0xdd,
12661 0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8,
12662 0x17, 0x15, 0x06, 0x39,
12663 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
12664 0xfe, 0x7e, 0x18, 0x1e,
12665 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef,
12666 0x12, 0xfe, 0xe1, 0x10,
12667 0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42,
12668 0x13, 0x42, 0x92, 0x09,
12669 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
12670 0xf0, 0xfe, 0x00, 0xcc,
12671 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01,
12672 0x0e, 0xfe, 0x80, 0x4c,
12673 0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe,
12674 0x24, 0x12, 0xfe, 0x14,
12675 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
12676 0xe7, 0x0a, 0x10, 0xfe,
12677 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92,
12678 0x08, 0x54, 0x1b, 0x37,
12679 0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba,
12680 0x90, 0x3a, 0xce, 0x3b,
12681 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
12682 0x13, 0xa3, 0x04, 0x09,
12683 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49,
12684 0x44, 0x17, 0xfe, 0xe8,
12685 0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09,
12686 0x5d, 0x01, 0xa8, 0x09,
12687 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
12688 0x1c, 0x19, 0x03, 0xfe,
12689 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9,
12690 0x6b, 0xfe, 0x2e, 0x19,
12691 0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4,
12692 0xfe, 0x0b, 0x00, 0x6b,
12693 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
12694 0x08, 0x10, 0x03, 0xfe,
12695 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff,
12696 0x04, 0x68, 0x54, 0xe7,
12697 0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe,
12698 0x1a, 0xf4, 0xfe, 0x00,
12699 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
12700 0x04, 0x07, 0x7e, 0xfe,
12701 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
12702 0x07, 0x1a, 0xfe, 0x5a,
12703 0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66,
12704 0x25, 0x6d, 0xe5, 0x07,
12705 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
12706 0xa9, 0xb8, 0x04, 0x15,
12707 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe,
12708 0x40, 0x5c, 0x04, 0x1c,
12709 0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b,
12710 0xf7, 0xfe, 0x82, 0xf0,
12711 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
12714 static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
12715 static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
12717 /* Microcode buffer is kept after initialization for error recovery. */
12718 static unsigned char _adv_asc38C1600_buf[] = {
12719 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
12720 0x18, 0xe4, 0x01, 0x00,
12721 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00,
12722 0x07, 0x17, 0xc0, 0x5f,
12723 0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7,
12724 0x85, 0xf0, 0x86, 0xf0,
12725 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
12726 0x98, 0x57, 0x01, 0xe6,
12727 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d,
12728 0x38, 0x54, 0x32, 0xf0,
12729 0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4,
12730 0x00, 0xe6, 0xb1, 0xf0,
12731 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
12732 0x06, 0x13, 0x0c, 0x1c,
12733 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12,
12734 0xb9, 0x54, 0x00, 0x80,
12735 0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56,
12736 0x03, 0xe6, 0x01, 0xea,
12737 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
12738 0x04, 0x13, 0xbb, 0x55,
12739 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00,
12740 0xbb, 0x00, 0xc0, 0x00,
12741 0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12,
12742 0x4c, 0x1c, 0x4e, 0x1c,
12743 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
12744 0x24, 0x01, 0x3c, 0x01,
12745 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01,
12746 0x78, 0x01, 0x7c, 0x01,
12747 0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c,
12748 0x6e, 0x1e, 0x02, 0x48,
12749 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
12750 0x03, 0xfc, 0x06, 0x00,
12751 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a,
12752 0x30, 0x1c, 0x38, 0x1c,
12753 0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea,
12754 0x5d, 0xf0, 0xa7, 0xf0,
12755 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
12756 0x33, 0x00, 0x34, 0x00,
12757 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01,
12758 0x79, 0x01, 0x3c, 0x09,
12759 0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13,
12760 0x40, 0x16, 0x50, 0x16,
12761 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
12762 0x05, 0xf0, 0x09, 0xf0,
12763 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00,
12764 0x9c, 0x00, 0xa4, 0x00,
12765 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08,
12766 0xe9, 0x09, 0x5c, 0x0c,
12767 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
12768 0x42, 0x1d, 0x08, 0x44,
12769 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54,
12770 0x83, 0x55, 0x83, 0x59,
12771 0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0,
12772 0x4b, 0xf4, 0x04, 0xf8,
12773 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
12774 0xa8, 0x00, 0xaa, 0x00,
12775 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01,
12776 0x7a, 0x01, 0x82, 0x01,
12777 0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07,
12778 0x68, 0x08, 0x10, 0x0d,
12779 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
12780 0xf3, 0x10, 0x06, 0x12,
12781 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c,
12782 0xf0, 0x35, 0x05, 0xfe,
12783 0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8,
12784 0xfe, 0x88, 0x01, 0xff,
12785 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
12786 0x00, 0xfe, 0x57, 0x24,
12787 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09,
12788 0x00, 0x00, 0xff, 0x08,
12789 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10,
12790 0xff, 0xff, 0xff, 0x13,
12791 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
12792 0xfe, 0x04, 0xf7, 0xe8,
12793 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d,
12794 0x0d, 0x51, 0x37, 0xfe,
12795 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0,
12796 0xfe, 0xf8, 0x01, 0xfe,
12797 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
12798 0x05, 0xfe, 0x08, 0x0f,
12799 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe,
12800 0x28, 0x1c, 0x03, 0xfe,
12801 0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe,
12802 0x48, 0xf0, 0xfe, 0x90,
12803 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
12804 0x02, 0xfe, 0x46, 0xf0,
12805 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0,
12806 0xfe, 0x4e, 0x02, 0xfe,
12807 0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c,
12808 0x0d, 0xa2, 0x1c, 0x07,
12809 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
12810 0x1c, 0xf5, 0xfe, 0x1e,
12811 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc,
12812 0xde, 0x0a, 0x81, 0x01,
12813 0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a,
12814 0x81, 0x01, 0x5c, 0xfe,
12815 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
12816 0xfe, 0x58, 0x1c, 0x1c,
12817 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02,
12818 0x2b, 0xfe, 0x9e, 0x02,
12819 0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30,
12820 0x00, 0x47, 0xb8, 0x01,
12821 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
12822 0x1a, 0x31, 0xfe, 0x69,
12823 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe,
12824 0x1e, 0x1e, 0x20, 0x2c,
12825 0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a,
12826 0x44, 0x15, 0x56, 0x51,
12827 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
12828 0x01, 0x18, 0x09, 0x00,
12829 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01,
12830 0x18, 0xfe, 0xc8, 0x54,
12831 0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60,
12832 0xfe, 0x02, 0xe8, 0x30,
12833 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
12834 0xfe, 0xe4, 0x01, 0xfe,
12835 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe,
12836 0x26, 0xf0, 0xfe, 0x66,
12837 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe,
12838 0xef, 0x10, 0xfe, 0x9f,
12839 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
12840 0x70, 0x37, 0xfe, 0x48,
12841 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26,
12842 0x21, 0xb9, 0xc7, 0x20,
12843 0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15,
12844 0xe1, 0x2a, 0xeb, 0xfe,
12845 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
12846 0x15, 0xfe, 0xe4, 0x00,
12847 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41,
12848 0xfe, 0x06, 0xf0, 0xfe,
12849 0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29,
12850 0x03, 0x81, 0x1e, 0x1b,
12851 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
12852 0xea, 0xfe, 0x46, 0x1c,
12853 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57,
12854 0xfe, 0x48, 0x1c, 0x75,
12855 0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a,
12856 0xe1, 0x01, 0x18, 0x77,
12857 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
12858 0x8f, 0xfe, 0x70, 0x02,
12859 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04,
12860 0x16, 0xfe, 0x4a, 0x04,
12861 0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff,
12862 0x02, 0x00, 0x10, 0x01,
12863 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
12864 0xee, 0xfe, 0x4c, 0x44,
12865 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54,
12866 0x7b, 0xec, 0x60, 0x8d,
12867 0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01,
12868 0x0c, 0x06, 0x28, 0xfe,
12869 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
12870 0x13, 0x34, 0xfe, 0x4c,
12871 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54,
12872 0x13, 0x01, 0x0c, 0x06,
12873 0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06,
12874 0x28, 0xf9, 0x1f, 0x7f,
12875 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
12876 0xfe, 0xa4, 0x0e, 0x05,
12877 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe,
12878 0x9c, 0x93, 0x3a, 0x0b,
12879 0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b,
12880 0x7d, 0x1d, 0xfe, 0x46,
12881 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
12882 0xfe, 0x87, 0x83, 0xfe,
12883 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98,
12884 0x13, 0x0f, 0xfe, 0x20,
12885 0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84,
12886 0x12, 0x01, 0x38, 0x06,
12887 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
12888 0x05, 0xd0, 0x54, 0x01,
12889 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe,
12890 0x50, 0x12, 0x5e, 0xff,
12891 0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02,
12892 0x00, 0x10, 0x2f, 0xfe,
12893 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
12894 0x38, 0xfe, 0x4a, 0xf0,
12895 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe,
12896 0x21, 0x00, 0xf1, 0x2e,
12897 0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00,
12898 0x10, 0x2f, 0xfe, 0xd0,
12899 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
12900 0x1c, 0x00, 0x4d, 0x01,
12901 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06,
12902 0x28, 0xfe, 0x24, 0x12,
12903 0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe,
12904 0x0d, 0x00, 0x01, 0x42,
12905 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
12906 0x03, 0xb6, 0x1e, 0xfe,
12907 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17,
12908 0xfe, 0x72, 0x06, 0x0a,
12909 0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56,
12910 0x19, 0x16, 0xfe, 0x68,
12911 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
12912 0x03, 0x9a, 0x1e, 0xfe,
12913 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12,
12914 0x48, 0xfe, 0x92, 0x06,
12915 0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13,
12916 0x58, 0xff, 0x02, 0x00,
12917 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
12918 0xfe, 0xea, 0x06, 0x01,
12919 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16,
12920 0xfe, 0xe0, 0x06, 0x15,
12921 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07,
12922 0x01, 0x84, 0xfe, 0xae,
12923 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
12924 0x1e, 0xfe, 0x1a, 0x12,
12925 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
12926 0x43, 0x48, 0x62, 0x80,
12927 0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24,
12928 0x36, 0xfe, 0x02, 0xf6,
12929 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
12930 0xd0, 0x0d, 0x17, 0xfe,
12931 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20,
12932 0x9e, 0x15, 0x82, 0x01,
12933 0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58,
12934 0x57, 0x10, 0xe6, 0x05,
12935 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
12936 0xfe, 0x9c, 0x32, 0x5f,
12937 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c,
12938 0xfe, 0x0a, 0xf0, 0xfe,
12939 0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08,
12940 0xaf, 0xa0, 0x05, 0x29,
12941 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
12942 0x00, 0x01, 0x08, 0x14,
12943 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08,
12944 0x14, 0x00, 0x05, 0xfe,
12945 0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06,
12946 0x12, 0xfe, 0x30, 0x13,
12947 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
12948 0x01, 0x08, 0x14, 0x00,
12949 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a,
12950 0x78, 0x4f, 0x0f, 0xfe,
12951 0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d,
12952 0x28, 0x48, 0xfe, 0x6c,
12953 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
12954 0x12, 0x53, 0x63, 0x4e,
12955 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe,
12956 0x6c, 0x08, 0xaf, 0xa0,
12957 0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24,
12958 0x05, 0xed, 0xfe, 0x9c,
12959 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
12960 0x1e, 0xfe, 0x99, 0x58,
12961 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a,
12962 0x22, 0x6b, 0x01, 0x0c,
12963 0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e,
12964 0x1e, 0x47, 0x2c, 0x7a,
12965 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
12966 0x01, 0x0c, 0x61, 0x65,
12967 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a,
12968 0x16, 0xfe, 0x08, 0x50,
12969 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10,
12970 0x01, 0xfe, 0xce, 0x1e,
12971 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
12972 0x01, 0xfe, 0xfe, 0x1e,
12973 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a,
12974 0x10, 0x01, 0x0c, 0x06,
12975 0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e,
12976 0x10, 0x6a, 0x22, 0x6b,
12977 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
12978 0xfe, 0x9f, 0x83, 0x33,
12979 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93,
12980 0x3a, 0x0b, 0xfe, 0xc6,
12981 0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d,
12982 0x01, 0xfe, 0xce, 0x1e,
12983 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
12984 0x04, 0xfe, 0xc0, 0x93,
12985 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e,
12986 0x10, 0x4b, 0x22, 0x4c,
12987 0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe,
12988 0x4e, 0x11, 0x2f, 0xfe,
12989 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
12990 0x3c, 0x37, 0x88, 0xf5,
12991 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a,
12992 0xd3, 0xfe, 0x42, 0x0a,
12993 0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0,
12994 0x05, 0x29, 0x01, 0x41,
12995 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
12996 0xfe, 0x14, 0x12, 0x01,
12997 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe,
12998 0x2e, 0x1c, 0x05, 0xfe,
12999 0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41,
13000 0xfe, 0x2c, 0x1c, 0xfe,
13001 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
13002 0x92, 0x10, 0xc4, 0xf6,
13003 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe,
13004 0xe7, 0x10, 0xfe, 0x2b,
13005 0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12,
13006 0xac, 0xfe, 0xd2, 0xf0,
13007 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
13008 0x1b, 0xbf, 0xd4, 0x5b,
13009 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75,
13010 0x5e, 0x32, 0x1f, 0x7f,
13011 0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98,
13012 0x05, 0x70, 0xfe, 0x74,
13013 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
13014 0x0f, 0x4d, 0x01, 0xfe,
13015 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06,
13016 0x0d, 0x2b, 0xfe, 0xe2,
13017 0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24,
13018 0xfe, 0x88, 0x13, 0x21,
13019 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
13020 0x83, 0x83, 0xfe, 0xc9,
13021 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04,
13022 0x91, 0x04, 0xfe, 0x84,
13023 0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93,
13024 0xfe, 0xcb, 0x57, 0x0b,
13025 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
13026 0x6a, 0x3b, 0x6b, 0x10,
13027 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30,
13028 0x20, 0x6e, 0xdb, 0x64,
13029 0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55,
13030 0xfe, 0x04, 0xfa, 0x64,
13031 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
13032 0x10, 0x98, 0x91, 0x6c,
13033 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91,
13034 0x4b, 0x7e, 0x4c, 0x01,
13035 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10,
13036 0x58, 0xfe, 0x91, 0x58,
13037 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
13038 0x1b, 0x40, 0x01, 0x0c,
13039 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f,
13040 0xfe, 0x10, 0x90, 0x04,
13041 0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93,
13042 0x79, 0x0b, 0x0e, 0xfe,
13043 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
13044 0x01, 0x0c, 0x06, 0x0d,
13045 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe,
13046 0x0c, 0x58, 0xfe, 0x8d,
13047 0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99,
13048 0x83, 0x33, 0x0b, 0x0e,
13049 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
13050 0x19, 0xfe, 0x19, 0x41,
13051 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42,
13052 0x19, 0xfe, 0x44, 0x00,
13053 0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda,
13054 0x4c, 0xfe, 0x0c, 0x51,
13055 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
13056 0x76, 0x10, 0xac, 0xfe,
13057 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03,
13058 0xe3, 0x23, 0x07, 0xfe,
13059 0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe,
13060 0xcc, 0x0c, 0x1f, 0x92,
13061 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
13062 0x0c, 0xfe, 0x3e, 0x10,
13063 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70,
13064 0xfe, 0xcb, 0xf0, 0xfe,
13065 0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe,
13066 0xf4, 0x0c, 0x19, 0x94,
13067 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
13068 0xfe, 0xcc, 0xf0, 0xef,
13069 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe,
13070 0x4e, 0x11, 0x2f, 0xfe,
13071 0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b,
13072 0x3c, 0x37, 0x88, 0xf5,
13073 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
13074 0x2f, 0xfe, 0x3e, 0x0d,
13075 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f,
13076 0xd2, 0x9f, 0xd3, 0x9f,
13077 0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4,
13078 0xc5, 0x75, 0xd7, 0x99,
13079 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
13080 0x9c, 0x2f, 0xfe, 0x8c,
13081 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe,
13082 0x42, 0x00, 0x05, 0x70,
13083 0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06,
13084 0x0d, 0xfe, 0x44, 0x13,
13085 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
13086 0xfe, 0xda, 0x0e, 0x0a,
13087 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa,
13088 0x10, 0x01, 0xfe, 0xf4,
13089 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40,
13090 0x15, 0x56, 0x01, 0x85,
13091 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
13092 0xcc, 0x10, 0x01, 0xa7,
13093 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04,
13094 0xfe, 0x99, 0x83, 0xfe,
13095 0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe,
13096 0x43, 0x00, 0xfe, 0xa2,
13097 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
13098 0x00, 0x1d, 0x40, 0x15,
13099 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05,
13100 0xfe, 0x3a, 0x03, 0x01,
13101 0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01,
13102 0x76, 0x06, 0x12, 0xfe,
13103 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
13104 0xfe, 0x9d, 0xf0, 0xfe,
13105 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01,
13106 0x0c, 0x61, 0x12, 0x44,
13107 0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f,
13108 0xfe, 0x2e, 0x10, 0x19,
13109 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
13110 0xfe, 0x41, 0x00, 0xa2,
13111 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b,
13112 0xea, 0x4f, 0xfe, 0x04,
13113 0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05,
13114 0x35, 0xfe, 0x12, 0x1c,
13115 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
13116 0xfe, 0xd4, 0x11, 0x05,
13117 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe,
13118 0xce, 0x45, 0x31, 0x51,
13119 0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03,
13120 0x67, 0xfe, 0x98, 0x56,
13121 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
13122 0x0c, 0x06, 0x28, 0xfe,
13123 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba,
13124 0xfe, 0xfa, 0x14, 0xfe,
13125 0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67,
13126 0xfe, 0xe0, 0x14, 0xfe,
13127 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
13128 0xfe, 0xad, 0x13, 0x05,
13129 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20,
13130 0xe7, 0xfe, 0x08, 0x1c,
13131 0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe,
13132 0x48, 0x55, 0xa5, 0x3b,
13133 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
13134 0xf0, 0x1a, 0x03, 0xfe,
13135 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02,
13136 0xec, 0xe7, 0x53, 0x00,
13137 0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
13138 0x01, 0xfe, 0x62, 0x1b,
13139 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
13140 0xea, 0xe7, 0x53, 0x92,
13141 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03,
13142 0xfe, 0x38, 0x01, 0x23,
13143 0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62,
13144 0x01, 0x01, 0xfe, 0x1e,
13145 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
13146 0x26, 0x02, 0x21, 0x96,
13147 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5,
13148 0xc3, 0xfe, 0xe1, 0x10,
13149 0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf,
13150 0xfe, 0x03, 0xdc, 0xfe,
13151 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
13152 0x00, 0xcc, 0x02, 0xfe,
13153 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13,
13154 0x0f, 0xfe, 0x1c, 0x80,
13155 0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13,
13156 0x0f, 0xfe, 0x1e, 0x80,
13157 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
13158 0x1d, 0x80, 0x04, 0xfe,
13159 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee,
13160 0x1e, 0xac, 0xfe, 0x14,
13161 0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e,
13162 0x1f, 0xfe, 0x30, 0xf4,
13163 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
13164 0x56, 0xfb, 0x01, 0xfe,
13165 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01,
13166 0xfe, 0x00, 0x1d, 0x15,
13167 0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe,
13168 0x22, 0x1b, 0xfe, 0x1e,
13169 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
13170 0x96, 0x90, 0x04, 0xfe,
13171 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66,
13172 0x01, 0x01, 0x0c, 0x06,
13173 0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b,
13174 0x0e, 0x77, 0xfe, 0x01,
13175 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
13176 0x21, 0x2c, 0xfe, 0x00,
13177 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe,
13178 0x06, 0x58, 0x03, 0xfe,
13179 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58,
13180 0x03, 0xfe, 0xb2, 0x00,
13181 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
13182 0x66, 0x10, 0x55, 0x10,
13183 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91,
13184 0x54, 0x2b, 0xfe, 0x88,
13185 0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe,
13186 0x91, 0x54, 0x2b, 0xfe,
13187 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
13188 0x00, 0x40, 0x8d, 0x2c,
13189 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe,
13190 0x12, 0x1c, 0x75, 0xfe,
13191 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c,
13192 0x14, 0xfe, 0x0e, 0x47,
13193 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
13194 0xa7, 0x90, 0x34, 0x60,
13195 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80,
13196 0x09, 0x56, 0xfe, 0x34,
13197 0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48,
13198 0xfe, 0x45, 0x48, 0x01,
13199 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
13200 0x09, 0x1a, 0xa5, 0x0a,
13201 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4,
13202 0xfe, 0x14, 0x56, 0xfe,
13203 0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01,
13204 0xec, 0xb8, 0xfe, 0x9e,
13205 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
13206 0xf4, 0xfe, 0xdd, 0x10,
13207 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48,
13208 0x12, 0x09, 0x0d, 0xfe,
13209 0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4,
13210 0x13, 0x09, 0xfe, 0x23,
13211 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
13212 0x24, 0xfe, 0x12, 0x12,
13213 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08,
13214 0xae, 0x41, 0x02, 0x32,
13215 0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05,
13216 0x35, 0x32, 0x01, 0x43,
13217 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
13218 0x13, 0x01, 0x0c, 0x06,
13219 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe,
13220 0xe5, 0x55, 0xb0, 0xfe,
13221 0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e,
13222 0xfe, 0xb6, 0x0e, 0x10,
13223 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
13224 0x88, 0x20, 0x6e, 0x01,
13225 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5,
13226 0x55, 0xfe, 0x04, 0xfa,
13227 0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d,
13228 0xfe, 0x40, 0x56, 0xfe,
13229 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
13230 0x44, 0x55, 0xfe, 0xe5,
13231 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10,
13232 0x68, 0x22, 0x69, 0x01,
13233 0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b,
13234 0x6b, 0xfe, 0x2c, 0x50,
13235 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
13236 0x50, 0x03, 0x68, 0x3b,
13237 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe,
13238 0x40, 0x50, 0xfe, 0xc2,
13239 0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08,
13240 0x16, 0x3d, 0x27, 0x25,
13241 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
13242 0xa6, 0x23, 0x3f, 0x1b,
13243 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c,
13244 0xfe, 0x0a, 0x55, 0x31,
13245 0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e,
13246 0x51, 0x05, 0x72, 0x01,
13247 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
13248 0x2a, 0x3c, 0x16, 0xc0,
13249 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b,
13250 0xfe, 0x66, 0x15, 0x05,
13251 0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d,
13252 0x2b, 0x3d, 0x01, 0x08,
13253 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
13254 0xb6, 0x1e, 0x83, 0x01,
13255 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46,
13256 0x07, 0x90, 0x3f, 0x01,
13257 0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13,
13258 0x01, 0x43, 0x09, 0x82,
13259 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
13260 0x05, 0x72, 0xfe, 0xc0,
13261 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e,
13262 0x32, 0x01, 0x08, 0x17,
13263 0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16,
13264 0x3d, 0x27, 0x25, 0xbd,
13265 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
13266 0xe8, 0x14, 0x01, 0xa6,
13267 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe,
13268 0x0e, 0x12, 0x01, 0x43,
13269 0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32,
13270 0x01, 0x08, 0x17, 0x73,
13271 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
13272 0x27, 0x25, 0xbd, 0x09,
13273 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe,
13274 0xb6, 0x14, 0x86, 0xa8,
13275 0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09,
13276 0x82, 0x4e, 0x05, 0x72,
13277 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
13278 0xfe, 0xc0, 0x19, 0x05,
13279 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f,
13280 0xcc, 0x01, 0x08, 0x26,
13281 0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe,
13282 0xcc, 0x15, 0x5e, 0x32,
13283 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
13284 0xad, 0x23, 0xfe, 0xff,
13285 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02,
13286 0x00, 0x57, 0x52, 0xad,
13287 0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff,
13288 0x02, 0x00, 0x57, 0x52,
13289 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
13290 0x02, 0x13, 0x58, 0xff,
13291 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01,
13292 0x5c, 0x0a, 0x55, 0x01,
13293 0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a,
13294 0xff, 0x03, 0x00, 0x54,
13295 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
13296 0x7c, 0x3a, 0x0b, 0x0e,
13297 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19,
13298 0xfe, 0x1a, 0xf7, 0x00,
13299 0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c,
13300 0xda, 0x6d, 0x02, 0xfe,
13301 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
13302 0x02, 0x01, 0xc6, 0xfe,
13303 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27,
13304 0x25, 0xbe, 0x01, 0x08,
13305 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59,
13306 0x03, 0x9a, 0x1e, 0xfe,
13307 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
13308 0x48, 0xfe, 0x08, 0x17,
13309 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26,
13310 0x17, 0x4d, 0x13, 0x07,
13311 0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1,
13312 0xff, 0x02, 0x83, 0x55,
13313 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
13314 0x17, 0x1c, 0x63, 0x13,
13315 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64,
13316 0x00, 0xb0, 0xfe, 0x80,
13317 0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10,
13318 0x53, 0x07, 0xfe, 0x60,
13319 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
13320 0x00, 0x1c, 0x95, 0x13,
13321 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3,
13322 0xfe, 0x43, 0xf4, 0x96,
13323 0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43,
13324 0xf4, 0x94, 0xf6, 0x8b,
13325 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
13326 0xda, 0x17, 0x62, 0x49,
13327 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80,
13328 0x71, 0x50, 0x26, 0xfe,
13329 0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3,
13330 0x58, 0x02, 0x50, 0x13,
13331 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
13332 0x25, 0xbe, 0xfe, 0x03,
13333 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9,
13334 0x0a, 0x01, 0x08, 0x16,
13335 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01,
13336 0x01, 0x08, 0x16, 0xa9,
13337 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
13338 0x08, 0x16, 0xa9, 0x27,
13339 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83,
13340 0x01, 0x38, 0x06, 0x24,
13341 0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1,
13342 0x78, 0x03, 0x9a, 0x1e,
13343 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
13344 0xfe, 0x40, 0x5a, 0x23,
13345 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c,
13346 0x80, 0x48, 0xfe, 0xaa,
13347 0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01,
13348 0xfe, 0xac, 0x1d, 0xfe,
13349 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
13350 0x43, 0x48, 0x2d, 0x93,
13351 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4,
13352 0x36, 0xfe, 0x34, 0xf4,
13353 0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe,
13354 0x28, 0x10, 0xfe, 0xc0,
13355 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
13356 0x18, 0x45, 0xfe, 0x1c,
13357 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c,
13358 0x19, 0xfe, 0x04, 0xf4,
13359 0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d,
13360 0x21, 0xfe, 0x7f, 0x01,
13361 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
13362 0x7e, 0x01, 0xfe, 0xc8,
13363 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa,
13364 0x21, 0xfe, 0x81, 0x01,
13365 0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50,
13366 0x13, 0x0d, 0x02, 0x14,
13367 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
13368 0xfe, 0x82, 0x19, 0x14,
13369 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01,
13370 0x08, 0x02, 0x14, 0x07,
13371 0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07,
13372 0x01, 0x08, 0x17, 0xc1,
13373 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
13374 0x08, 0x02, 0x50, 0x02,
13375 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74,
13376 0x14, 0x12, 0x01, 0x08,
13377 0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01,
13378 0x08, 0x17, 0x74, 0xfe,
13379 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
13380 0x74, 0x5f, 0xcc, 0x01,
13381 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4,
13382 0xfe, 0x49, 0xf4, 0x00,
13383 0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff,
13384 0x02, 0x00, 0x10, 0x2f,
13385 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
13386 0x16, 0xfe, 0x64, 0x1a,
13387 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c,
13388 0x61, 0x07, 0x44, 0x02,
13389 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12,
13390 0x13, 0x0a, 0x9d, 0x01,
13391 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
13392 0xfe, 0x80, 0xe7, 0x1a,
13393 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02,
13394 0x0a, 0x5a, 0x01, 0x18,
13395 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe,
13396 0x7e, 0x1e, 0xfe, 0x80,
13397 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
13398 0xfe, 0x80, 0x4c, 0x0a,
13399 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf,
13400 0xfe, 0x19, 0xde, 0xfe,
13401 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe,
13402 0x2a, 0x1c, 0xfa, 0xb3,
13403 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
13404 0xf4, 0x1a, 0xfe, 0xfa,
13405 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24,
13406 0xfe, 0x18, 0x58, 0x03,
13407 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f,
13408 0xfe, 0x30, 0xf4, 0x07,
13409 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
13410 0xf7, 0x24, 0xb1, 0xfe,
13411 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b,
13412 0xfe, 0xba, 0x10, 0x1c,
13413 0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
13414 0x1d, 0xf7, 0x54, 0xb1,
13415 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
13416 0xaf, 0x19, 0xfe, 0x98,
13417 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c,
13418 0x1a, 0x87, 0x8b, 0x0f,
13419 0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58,
13420 0xfe, 0x32, 0x90, 0x04,
13421 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
13422 0x7c, 0x12, 0xfe, 0x0f,
13423 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14,
13424 0x31, 0x02, 0xc9, 0x2b,
13425 0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe,
13426 0x6a, 0xfe, 0x19, 0xfe,
13427 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
13428 0x1b, 0xfe, 0x36, 0x14,
13429 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19,
13430 0xfe, 0x80, 0xe7, 0x1a,
13431 0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a,
13432 0x30, 0xfe, 0x12, 0x45,
13433 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
13434 0x39, 0xf0, 0x75, 0x26,
13435 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03,
13436 0xe3, 0x23, 0x07, 0xfe,
13437 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09,
13438 0x56, 0xfe, 0x3c, 0x13,
13439 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
13440 0x01, 0x18, 0xcb, 0xfe,
13441 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16,
13442 0xfe, 0x00, 0xcc, 0xcb,
13443 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18,
13444 0xfe, 0x80, 0x4c, 0x01,
13445 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
13446 0x12, 0xfe, 0x14, 0x56,
13447 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7,
13448 0x0d, 0x19, 0xfe, 0x15,
13449 0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06,
13450 0x83, 0xfe, 0x18, 0x80,
13451 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
13452 0x90, 0xfe, 0xba, 0x90,
13453 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02,
13454 0x21, 0xb9, 0x88, 0x20,
13455 0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01,
13456 0x18, 0xfe, 0x49, 0x44,
13457 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
13458 0x1a, 0xa4, 0x0a, 0x67,
13459 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4,
13460 0x1d, 0x7b, 0xfe, 0x52,
13461 0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe,
13462 0x4e, 0xe4, 0xdd, 0x7b,
13463 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
13464 0xfe, 0x4e, 0xe4, 0xfe,
13465 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24,
13466 0xfe, 0x08, 0x10, 0x03,
13467 0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04,
13468 0x68, 0x54, 0xfe, 0xf1,
13469 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
13470 0xfe, 0x1a, 0xf4, 0xfe,
13471 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02,
13472 0x09, 0x92, 0xfe, 0x5a,
13473 0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe,
13474 0x5a, 0xf0, 0xfe, 0xc8,
13475 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
13476 0x1a, 0x10, 0x09, 0x0d,
13477 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02,
13478 0x1f, 0x93, 0x01, 0x42,
13479 0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e,
13480 0xfe, 0x14, 0xf0, 0x08,
13481 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
13482 0xfe, 0x82, 0xf0, 0xfe,
13483 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e,
13484 0x02, 0x0f, 0xfe, 0x18,
13485 0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02,
13486 0x80, 0x04, 0xfe, 0x82,
13487 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
13488 0x83, 0x33, 0x0b, 0x0e,
13489 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e,
13490 0x02, 0x0f, 0xfe, 0x04,
13491 0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80,
13492 0x80, 0x04, 0xfe, 0x80,
13493 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
13494 0xfe, 0x99, 0x83, 0xfe,
13495 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86,
13496 0x83, 0xfe, 0xce, 0x47,
13497 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a,
13498 0x0b, 0x0e, 0x02, 0x0f,
13499 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13500 0xfe, 0x08, 0x90, 0x04,
13501 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04,
13502 0xfe, 0x8a, 0x93, 0x79,
13503 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a,
13504 0x0b, 0x0e, 0x02, 0x0f,
13505 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
13506 0xfe, 0x3c, 0x90, 0x04,
13507 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80,
13508 0x04, 0xfe, 0x83, 0x83,
13509 0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
13512 static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
13513 static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
13515 /* a_init.c */
13517 * EEPROM Configuration.
13519 * All drivers should use this structure to set the default EEPROM
13520 * configuration. The BIOS now uses this structure when it is built.
13521 * Additional structure information can be found in a_condor.h where
13522 * the structure is defined.
13524 * The *_Field_IsChar structs are needed to correct for endianness.
13525 * These values are read from the board 16 bits at a time directly
13526 * into the structs. Because some fields are char, the values will be
13527 * in the wrong order. The *_Field_IsChar tells when to flip the
13528 * bytes. Data read and written to PCI memory is automatically swapped
13529 * on big-endian platforms so char fields read as words are actually being
13530 * unswapped on big-endian platforms.
13532 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = {
13533 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
13534 0x0000, /* cfg_msw */
13535 0xFFFF, /* disc_enable */
13536 0xFFFF, /* wdtr_able */
13537 0xFFFF, /* sdtr_able */
13538 0xFFFF, /* start_motor */
13539 0xFFFF, /* tagqng_able */
13540 0xFFFF, /* bios_scan */
13541 0, /* scam_tolerant */
13542 7, /* adapter_scsi_id */
13543 0, /* bios_boot_delay */
13544 3, /* scsi_reset_delay */
13545 0, /* bios_id_lun */
13546 0, /* termination */
13547 0, /* reserved1 */
13548 0xFFE7, /* bios_ctrl */
13549 0xFFFF, /* ultra_able */
13550 0, /* reserved2 */
13551 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
13552 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13553 0, /* dvc_cntl */
13554 0, /* bug_fix */
13555 0, /* serial_number_word1 */
13556 0, /* serial_number_word2 */
13557 0, /* serial_number_word3 */
13558 0, /* check_sum */
13559 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13560 , /* oem_name[16] */
13561 0, /* dvc_err_code */
13562 0, /* adv_err_code */
13563 0, /* adv_err_addr */
13564 0, /* saved_dvc_err_code */
13565 0, /* saved_adv_err_code */
13566 0, /* saved_adv_err_addr */
13567 0 /* num_of_err */
13570 static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = {
13571 0, /* cfg_lsw */
13572 0, /* cfg_msw */
13573 0, /* -disc_enable */
13574 0, /* wdtr_able */
13575 0, /* sdtr_able */
13576 0, /* start_motor */
13577 0, /* tagqng_able */
13578 0, /* bios_scan */
13579 0, /* scam_tolerant */
13580 1, /* adapter_scsi_id */
13581 1, /* bios_boot_delay */
13582 1, /* scsi_reset_delay */
13583 1, /* bios_id_lun */
13584 1, /* termination */
13585 1, /* reserved1 */
13586 0, /* bios_ctrl */
13587 0, /* ultra_able */
13588 0, /* reserved2 */
13589 1, /* max_host_qng */
13590 1, /* max_dvc_qng */
13591 0, /* dvc_cntl */
13592 0, /* bug_fix */
13593 0, /* serial_number_word1 */
13594 0, /* serial_number_word2 */
13595 0, /* serial_number_word3 */
13596 0, /* check_sum */
13597 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13598 , /* oem_name[16] */
13599 0, /* dvc_err_code */
13600 0, /* adv_err_code */
13601 0, /* adv_err_addr */
13602 0, /* saved_dvc_err_code */
13603 0, /* saved_adv_err_code */
13604 0, /* saved_adv_err_addr */
13605 0 /* num_of_err */
13608 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = {
13609 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13610 0x0000, /* 01 cfg_msw */
13611 0xFFFF, /* 02 disc_enable */
13612 0xFFFF, /* 03 wdtr_able */
13613 0x4444, /* 04 sdtr_speed1 */
13614 0xFFFF, /* 05 start_motor */
13615 0xFFFF, /* 06 tagqng_able */
13616 0xFFFF, /* 07 bios_scan */
13617 0, /* 08 scam_tolerant */
13618 7, /* 09 adapter_scsi_id */
13619 0, /* bios_boot_delay */
13620 3, /* 10 scsi_reset_delay */
13621 0, /* bios_id_lun */
13622 0, /* 11 termination_se */
13623 0, /* termination_lvd */
13624 0xFFE7, /* 12 bios_ctrl */
13625 0x4444, /* 13 sdtr_speed2 */
13626 0x4444, /* 14 sdtr_speed3 */
13627 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
13628 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13629 0, /* 16 dvc_cntl */
13630 0x4444, /* 17 sdtr_speed4 */
13631 0, /* 18 serial_number_word1 */
13632 0, /* 19 serial_number_word2 */
13633 0, /* 20 serial_number_word3 */
13634 0, /* 21 check_sum */
13635 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13636 , /* 22-29 oem_name[16] */
13637 0, /* 30 dvc_err_code */
13638 0, /* 31 adv_err_code */
13639 0, /* 32 adv_err_addr */
13640 0, /* 33 saved_dvc_err_code */
13641 0, /* 34 saved_adv_err_code */
13642 0, /* 35 saved_adv_err_addr */
13643 0, /* 36 reserved */
13644 0, /* 37 reserved */
13645 0, /* 38 reserved */
13646 0, /* 39 reserved */
13647 0, /* 40 reserved */
13648 0, /* 41 reserved */
13649 0, /* 42 reserved */
13650 0, /* 43 reserved */
13651 0, /* 44 reserved */
13652 0, /* 45 reserved */
13653 0, /* 46 reserved */
13654 0, /* 47 reserved */
13655 0, /* 48 reserved */
13656 0, /* 49 reserved */
13657 0, /* 50 reserved */
13658 0, /* 51 reserved */
13659 0, /* 52 reserved */
13660 0, /* 53 reserved */
13661 0, /* 54 reserved */
13662 0, /* 55 reserved */
13663 0, /* 56 cisptr_lsw */
13664 0, /* 57 cisprt_msw */
13665 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
13666 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
13667 0, /* 60 reserved */
13668 0, /* 61 reserved */
13669 0, /* 62 reserved */
13670 0 /* 63 reserved */
13673 static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = {
13674 0, /* 00 cfg_lsw */
13675 0, /* 01 cfg_msw */
13676 0, /* 02 disc_enable */
13677 0, /* 03 wdtr_able */
13678 0, /* 04 sdtr_speed1 */
13679 0, /* 05 start_motor */
13680 0, /* 06 tagqng_able */
13681 0, /* 07 bios_scan */
13682 0, /* 08 scam_tolerant */
13683 1, /* 09 adapter_scsi_id */
13684 1, /* bios_boot_delay */
13685 1, /* 10 scsi_reset_delay */
13686 1, /* bios_id_lun */
13687 1, /* 11 termination_se */
13688 1, /* termination_lvd */
13689 0, /* 12 bios_ctrl */
13690 0, /* 13 sdtr_speed2 */
13691 0, /* 14 sdtr_speed3 */
13692 1, /* 15 max_host_qng */
13693 1, /* max_dvc_qng */
13694 0, /* 16 dvc_cntl */
13695 0, /* 17 sdtr_speed4 */
13696 0, /* 18 serial_number_word1 */
13697 0, /* 19 serial_number_word2 */
13698 0, /* 20 serial_number_word3 */
13699 0, /* 21 check_sum */
13700 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13701 , /* 22-29 oem_name[16] */
13702 0, /* 30 dvc_err_code */
13703 0, /* 31 adv_err_code */
13704 0, /* 32 adv_err_addr */
13705 0, /* 33 saved_dvc_err_code */
13706 0, /* 34 saved_adv_err_code */
13707 0, /* 35 saved_adv_err_addr */
13708 0, /* 36 reserved */
13709 0, /* 37 reserved */
13710 0, /* 38 reserved */
13711 0, /* 39 reserved */
13712 0, /* 40 reserved */
13713 0, /* 41 reserved */
13714 0, /* 42 reserved */
13715 0, /* 43 reserved */
13716 0, /* 44 reserved */
13717 0, /* 45 reserved */
13718 0, /* 46 reserved */
13719 0, /* 47 reserved */
13720 0, /* 48 reserved */
13721 0, /* 49 reserved */
13722 0, /* 50 reserved */
13723 0, /* 51 reserved */
13724 0, /* 52 reserved */
13725 0, /* 53 reserved */
13726 0, /* 54 reserved */
13727 0, /* 55 reserved */
13728 0, /* 56 cisptr_lsw */
13729 0, /* 57 cisprt_msw */
13730 0, /* 58 subsysvid */
13731 0, /* 59 subsysid */
13732 0, /* 60 reserved */
13733 0, /* 61 reserved */
13734 0, /* 62 reserved */
13735 0 /* 63 reserved */
13738 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = {
13739 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
13740 0x0000, /* 01 cfg_msw */
13741 0xFFFF, /* 02 disc_enable */
13742 0xFFFF, /* 03 wdtr_able */
13743 0x5555, /* 04 sdtr_speed1 */
13744 0xFFFF, /* 05 start_motor */
13745 0xFFFF, /* 06 tagqng_able */
13746 0xFFFF, /* 07 bios_scan */
13747 0, /* 08 scam_tolerant */
13748 7, /* 09 adapter_scsi_id */
13749 0, /* bios_boot_delay */
13750 3, /* 10 scsi_reset_delay */
13751 0, /* bios_id_lun */
13752 0, /* 11 termination_se */
13753 0, /* termination_lvd */
13754 0xFFE7, /* 12 bios_ctrl */
13755 0x5555, /* 13 sdtr_speed2 */
13756 0x5555, /* 14 sdtr_speed3 */
13757 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
13758 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
13759 0, /* 16 dvc_cntl */
13760 0x5555, /* 17 sdtr_speed4 */
13761 0, /* 18 serial_number_word1 */
13762 0, /* 19 serial_number_word2 */
13763 0, /* 20 serial_number_word3 */
13764 0, /* 21 check_sum */
13765 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
13766 , /* 22-29 oem_name[16] */
13767 0, /* 30 dvc_err_code */
13768 0, /* 31 adv_err_code */
13769 0, /* 32 adv_err_addr */
13770 0, /* 33 saved_dvc_err_code */
13771 0, /* 34 saved_adv_err_code */
13772 0, /* 35 saved_adv_err_addr */
13773 0, /* 36 reserved */
13774 0, /* 37 reserved */
13775 0, /* 38 reserved */
13776 0, /* 39 reserved */
13777 0, /* 40 reserved */
13778 0, /* 41 reserved */
13779 0, /* 42 reserved */
13780 0, /* 43 reserved */
13781 0, /* 44 reserved */
13782 0, /* 45 reserved */
13783 0, /* 46 reserved */
13784 0, /* 47 reserved */
13785 0, /* 48 reserved */
13786 0, /* 49 reserved */
13787 0, /* 50 reserved */
13788 0, /* 51 reserved */
13789 0, /* 52 reserved */
13790 0, /* 53 reserved */
13791 0, /* 54 reserved */
13792 0, /* 55 reserved */
13793 0, /* 56 cisptr_lsw */
13794 0, /* 57 cisprt_msw */
13795 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
13796 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
13797 0, /* 60 reserved */
13798 0, /* 61 reserved */
13799 0, /* 62 reserved */
13800 0 /* 63 reserved */
13803 static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = {
13804 0, /* 00 cfg_lsw */
13805 0, /* 01 cfg_msw */
13806 0, /* 02 disc_enable */
13807 0, /* 03 wdtr_able */
13808 0, /* 04 sdtr_speed1 */
13809 0, /* 05 start_motor */
13810 0, /* 06 tagqng_able */
13811 0, /* 07 bios_scan */
13812 0, /* 08 scam_tolerant */
13813 1, /* 09 adapter_scsi_id */
13814 1, /* bios_boot_delay */
13815 1, /* 10 scsi_reset_delay */
13816 1, /* bios_id_lun */
13817 1, /* 11 termination_se */
13818 1, /* termination_lvd */
13819 0, /* 12 bios_ctrl */
13820 0, /* 13 sdtr_speed2 */
13821 0, /* 14 sdtr_speed3 */
13822 1, /* 15 max_host_qng */
13823 1, /* max_dvc_qng */
13824 0, /* 16 dvc_cntl */
13825 0, /* 17 sdtr_speed4 */
13826 0, /* 18 serial_number_word1 */
13827 0, /* 19 serial_number_word2 */
13828 0, /* 20 serial_number_word3 */
13829 0, /* 21 check_sum */
13830 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
13831 , /* 22-29 oem_name[16] */
13832 0, /* 30 dvc_err_code */
13833 0, /* 31 adv_err_code */
13834 0, /* 32 adv_err_addr */
13835 0, /* 33 saved_dvc_err_code */
13836 0, /* 34 saved_adv_err_code */
13837 0, /* 35 saved_adv_err_addr */
13838 0, /* 36 reserved */
13839 0, /* 37 reserved */
13840 0, /* 38 reserved */
13841 0, /* 39 reserved */
13842 0, /* 40 reserved */
13843 0, /* 41 reserved */
13844 0, /* 42 reserved */
13845 0, /* 43 reserved */
13846 0, /* 44 reserved */
13847 0, /* 45 reserved */
13848 0, /* 46 reserved */
13849 0, /* 47 reserved */
13850 0, /* 48 reserved */
13851 0, /* 49 reserved */
13852 0, /* 50 reserved */
13853 0, /* 51 reserved */
13854 0, /* 52 reserved */
13855 0, /* 53 reserved */
13856 0, /* 54 reserved */
13857 0, /* 55 reserved */
13858 0, /* 56 cisptr_lsw */
13859 0, /* 57 cisprt_msw */
13860 0, /* 58 subsysvid */
13861 0, /* 59 subsysid */
13862 0, /* 60 reserved */
13863 0, /* 61 reserved */
13864 0, /* 62 reserved */
13865 0 /* 63 reserved */
13869 * Initialize the ADV_DVC_VAR structure.
13871 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
13873 * For a non-fatal error return a warning code. If there are no warnings
13874 * then 0 is returned.
13876 static int __devinit AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
13878 ushort warn_code;
13879 AdvPortAddr iop_base;
13880 uchar pci_cmd_reg;
13881 int status;
13883 warn_code = 0;
13884 asc_dvc->err_code = 0;
13885 iop_base = asc_dvc->iop_base;
13888 * PCI Command Register
13890 * Note: AscPCICmdRegBits_BusMastering definition (0x0007) includes
13891 * I/O Space Control, Memory Space Control and Bus Master Control bits.
13894 if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
13895 AscPCIConfigCommandRegister))
13896 & AscPCICmdRegBits_BusMastering)
13897 != AscPCICmdRegBits_BusMastering) {
13898 pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
13900 DvcAdvWritePCIConfigByte(asc_dvc,
13901 AscPCIConfigCommandRegister,
13902 pci_cmd_reg);
13904 if (((DvcAdvReadPCIConfigByte
13905 (asc_dvc, AscPCIConfigCommandRegister))
13906 & AscPCICmdRegBits_BusMastering)
13907 != AscPCICmdRegBits_BusMastering) {
13908 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
13913 * PCI Latency Timer
13915 * If the "latency timer" register is 0x20 or above, then we don't need
13916 * to change it. Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
13917 * comes up less than 0x20).
13919 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
13920 DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer,
13921 0x20);
13922 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) <
13923 0x20) {
13924 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
13929 * Save the state of the PCI Configuration Command Register
13930 * "Parity Error Response Control" Bit. If the bit is clear (0),
13931 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
13932 * DMA parity errors.
13934 asc_dvc->cfg->control_flag = 0;
13935 if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
13936 & AscPCICmdRegBits_ParErrRespCtrl)) == 0) {
13937 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
13940 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
13941 ADV_LIB_VERSION_MINOR;
13942 asc_dvc->cfg->chip_version =
13943 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
13945 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
13946 (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
13947 (ushort)ADV_CHIP_ID_BYTE);
13949 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
13950 (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
13951 (ushort)ADV_CHIP_ID_WORD);
13954 * Reset the chip to start and allow register writes.
13956 if (AdvFindSignature(iop_base) == 0) {
13957 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
13958 return ADV_ERROR;
13959 } else {
13961 * The caller must set 'chip_type' to a valid setting.
13963 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
13964 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
13965 asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
13966 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
13967 return ADV_ERROR;
13971 * Reset Chip.
13973 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13974 ADV_CTRL_REG_CMD_RESET);
13975 DvcSleepMilliSecond(100);
13976 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
13977 ADV_CTRL_REG_CMD_WR_IO_REG);
13979 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
13980 if ((status =
13981 AdvInitFrom38C1600EEP(asc_dvc)) == ADV_ERROR) {
13982 return ADV_ERROR;
13984 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
13985 if ((status =
13986 AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR) {
13987 return ADV_ERROR;
13989 } else {
13990 if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR) {
13991 return ADV_ERROR;
13994 warn_code |= status;
13997 return warn_code;
14001 * Initialize the ASC-3550.
14003 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14005 * For a non-fatal error return a warning code. If there are no warnings
14006 * then 0 is returned.
14008 * Needed after initialization for error recovery.
14010 static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
14012 AdvPortAddr iop_base;
14013 ushort warn_code;
14014 ADV_DCNT sum;
14015 int begin_addr;
14016 int end_addr;
14017 ushort code_sum;
14018 int word;
14019 int j;
14020 int adv_asc3550_expanded_size;
14021 ADV_CARR_T *carrp;
14022 ADV_DCNT contig_len;
14023 ADV_SDCNT buf_size;
14024 ADV_PADDR carr_paddr;
14025 int i;
14026 ushort scsi_cfg1;
14027 uchar tid;
14028 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
14029 ushort wdtr_able = 0, sdtr_able, tagqng_able;
14030 uchar max_cmd[ADV_MAX_TID + 1];
14032 /* If there is already an error, don't continue. */
14033 if (asc_dvc->err_code != 0) {
14034 return ADV_ERROR;
14038 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
14040 if (asc_dvc->chip_type != ADV_CHIP_ASC3550) {
14041 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14042 return ADV_ERROR;
14045 warn_code = 0;
14046 iop_base = asc_dvc->iop_base;
14049 * Save the RISC memory BIOS region before writing the microcode.
14050 * The BIOS may already be loaded and using its RISC LRAM region
14051 * so its region must be saved and restored.
14053 * Note: This code makes the assumption, which is currently true,
14054 * that a chip reset does not clear RISC LRAM.
14056 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14057 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14058 bios_mem[i]);
14062 * Save current per TID negotiated values.
14064 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) {
14065 ushort bios_version, major, minor;
14067 bios_version =
14068 bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2];
14069 major = (bios_version >> 12) & 0xF;
14070 minor = (bios_version >> 8) & 0xF;
14071 if (major < 3 || (major == 3 && minor == 1)) {
14072 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
14073 AdvReadWordLram(iop_base, 0x120, wdtr_able);
14074 } else {
14075 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14078 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14079 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14080 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14081 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14082 max_cmd[tid]);
14086 * Load the Microcode
14088 * Write the microcode image to RISC memory starting at address 0.
14090 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14091 /* Assume the following compressed format of the microcode buffer:
14093 * 254 word (508 byte) table indexed by byte code followed
14094 * by the following byte codes:
14096 * 1-Byte Code:
14097 * 00: Emit word 0 in table.
14098 * 01: Emit word 1 in table.
14100 * FD: Emit word 253 in table.
14102 * Multi-Byte Code:
14103 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14104 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14106 word = 0;
14107 for (i = 253 * 2; i < _adv_asc3550_size; i++) {
14108 if (_adv_asc3550_buf[i] == 0xff) {
14109 for (j = 0; j < _adv_asc3550_buf[i + 1]; j++) {
14110 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14111 _adv_asc3550_buf
14112 [i +
14113 3] << 8) |
14114 _adv_asc3550_buf
14115 [i + 2]));
14116 word++;
14118 i += 3;
14119 } else if (_adv_asc3550_buf[i] == 0xfe) {
14120 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14121 _adv_asc3550_buf[i +
14123 << 8) |
14124 _adv_asc3550_buf[i +
14125 1]));
14126 i += 2;
14127 word++;
14128 } else {
14129 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14130 _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) | _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
14131 word++;
14136 * Set 'word' for later use to clear the rest of memory and save
14137 * the expanded mcode size.
14139 word *= 2;
14140 adv_asc3550_expanded_size = word;
14143 * Clear the rest of ASC-3550 Internal RAM (8KB).
14145 for (; word < ADV_3550_MEMSIZE; word += 2) {
14146 AdvWriteWordAutoIncLram(iop_base, 0);
14150 * Verify the microcode checksum.
14152 sum = 0;
14153 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14155 for (word = 0; word < adv_asc3550_expanded_size; word += 2) {
14156 sum += AdvReadWordAutoIncLram(iop_base);
14159 if (sum != _adv_asc3550_chksum) {
14160 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14161 return ADV_ERROR;
14165 * Restore the RISC memory BIOS region.
14167 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14168 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14169 bios_mem[i]);
14173 * Calculate and write the microcode code checksum to the microcode
14174 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14176 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14177 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14178 code_sum = 0;
14179 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14180 for (word = begin_addr; word < end_addr; word += 2) {
14181 code_sum += AdvReadWordAutoIncLram(iop_base);
14183 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14186 * Read and save microcode version and date.
14188 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
14189 asc_dvc->cfg->mcode_date);
14190 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
14191 asc_dvc->cfg->mcode_version);
14194 * Set the chip type to indicate the ASC3550.
14196 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
14199 * If the PCI Configuration Command Register "Parity Error Response
14200 * Control" Bit was clear (0), then set the microcode variable
14201 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14202 * to ignore DMA parity errors.
14204 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
14205 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14206 word |= CONTROL_FLAG_IGNORE_PERR;
14207 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14211 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
14212 * threshold of 128 bytes. This register is only accessible to the host.
14214 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14215 START_CTL_EMFU | READ_CMD_MRM);
14218 * Microcode operating variables for WDTR, SDTR, and command tag
14219 * queuing will be set in AdvInquiryHandling() based on what a
14220 * device reports it is capable of in Inquiry byte 7.
14222 * If SCSI Bus Resets have been disabled, then directly set
14223 * SDTR and WDTR from the EEPROM configuration. This will allow
14224 * the BIOS and warm boot to work without a SCSI bus hang on
14225 * the Inquiry caused by host and target mismatched DTR values.
14226 * Without the SCSI Bus Reset, before an Inquiry a device can't
14227 * be assumed to be in Asynchronous, Narrow mode.
14229 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
14230 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
14231 asc_dvc->wdtr_able);
14232 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
14233 asc_dvc->sdtr_able);
14237 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
14238 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
14239 * bitmask. These values determine the maximum SDTR speed negotiated
14240 * with a device.
14242 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14243 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14244 * without determining here whether the device supports SDTR.
14246 * 4-bit speed SDTR speed name
14247 * =========== ===============
14248 * 0000b (0x0) SDTR disabled
14249 * 0001b (0x1) 5 Mhz
14250 * 0010b (0x2) 10 Mhz
14251 * 0011b (0x3) 20 Mhz (Ultra)
14252 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
14253 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
14254 * 0110b (0x6) Undefined
14256 * 1111b (0xF) Undefined
14258 word = 0;
14259 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14260 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) {
14261 /* Set Ultra speed for TID 'tid'. */
14262 word |= (0x3 << (4 * (tid % 4)));
14263 } else {
14264 /* Set Fast speed for TID 'tid'. */
14265 word |= (0x2 << (4 * (tid % 4)));
14267 if (tid == 3) { /* Check if done with sdtr_speed1. */
14268 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
14269 word = 0;
14270 } else if (tid == 7) { /* Check if done with sdtr_speed2. */
14271 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
14272 word = 0;
14273 } else if (tid == 11) { /* Check if done with sdtr_speed3. */
14274 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
14275 word = 0;
14276 } else if (tid == 15) { /* Check if done with sdtr_speed4. */
14277 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
14278 /* End of loop. */
14283 * Set microcode operating variable for the disconnect per TID bitmask.
14285 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
14286 asc_dvc->cfg->disc_enable);
14289 * Set SCSI_CFG0 Microcode Default Value.
14291 * The microcode will set the SCSI_CFG0 register using this value
14292 * after it is started below.
14294 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14295 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14296 asc_dvc->chip_scsi_id);
14299 * Determine SCSI_CFG1 Microcode Default Value.
14301 * The microcode will set the SCSI_CFG1 register using this value
14302 * after it is started below.
14305 /* Read current SCSI_CFG1 Register value. */
14306 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14309 * If all three connectors are in use, return an error.
14311 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
14312 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) {
14313 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
14314 return ADV_ERROR;
14318 * If the internal narrow cable is reversed all of the SCSI_CTRL
14319 * register signals will be set. Check for and return an error if
14320 * this condition is found.
14322 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
14323 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14324 return ADV_ERROR;
14328 * If this is a differential board and a single-ended device
14329 * is attached to one of the connectors, return an error.
14331 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) {
14332 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
14333 return ADV_ERROR;
14337 * If automatic termination control is enabled, then set the
14338 * termination value based on a table listed in a_condor.h.
14340 * If manual termination was specified with an EEPROM setting
14341 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
14342 * is ready to be 'ored' into SCSI_CFG1.
14344 if (asc_dvc->cfg->termination == 0) {
14346 * The software always controls termination by setting TERM_CTL_SEL.
14347 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
14349 asc_dvc->cfg->termination |= TERM_CTL_SEL;
14351 switch (scsi_cfg1 & CABLE_DETECT) {
14352 /* TERM_CTL_H: on, TERM_CTL_L: on */
14353 case 0x3:
14354 case 0x7:
14355 case 0xB:
14356 case 0xD:
14357 case 0xE:
14358 case 0xF:
14359 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
14360 break;
14362 /* TERM_CTL_H: on, TERM_CTL_L: off */
14363 case 0x1:
14364 case 0x5:
14365 case 0x9:
14366 case 0xA:
14367 case 0xC:
14368 asc_dvc->cfg->termination |= TERM_CTL_H;
14369 break;
14371 /* TERM_CTL_H: off, TERM_CTL_L: off */
14372 case 0x2:
14373 case 0x6:
14374 break;
14379 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
14381 scsi_cfg1 &= ~TERM_CTL;
14384 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
14385 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
14386 * referenced, because the hardware internally inverts
14387 * the Termination High and Low bits if TERM_POL is set.
14389 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
14392 * Set SCSI_CFG1 Microcode Default Value
14394 * Set filter value and possibly modified termination control
14395 * bits in the Microcode SCSI_CFG1 Register Value.
14397 * The microcode will set the SCSI_CFG1 register using this value
14398 * after it is started below.
14400 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
14401 FLTR_DISABLE | scsi_cfg1);
14404 * Set MEM_CFG Microcode Default Value
14406 * The microcode will set the MEM_CFG register using this value
14407 * after it is started below.
14409 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
14410 * are defined.
14412 * ASC-3550 has 8KB internal memory.
14414 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
14415 BIOS_EN | RAM_SZ_8KB);
14418 * Set SEL_MASK Microcode Default Value
14420 * The microcode will set the SEL_MASK register using this value
14421 * after it is started below.
14423 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
14424 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
14427 * Build carrier freelist.
14429 * Driver must have already allocated memory and set 'carrier_buf'.
14431 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
14433 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
14434 asc_dvc->carr_freelist = NULL;
14435 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
14436 buf_size = ADV_CARRIER_BUFSIZE;
14437 } else {
14438 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
14441 do {
14443 * Get physical address of the carrier 'carrp'.
14445 contig_len = sizeof(ADV_CARR_T);
14446 carr_paddr =
14447 cpu_to_le32(DvcGetPhyAddr
14448 (asc_dvc, NULL, (uchar *)carrp,
14449 (ADV_SDCNT *)&contig_len,
14450 ADV_IS_CARRIER_FLAG));
14452 buf_size -= sizeof(ADV_CARR_T);
14455 * If the current carrier is not physically contiguous, then
14456 * maybe there was a page crossing. Try the next carrier aligned
14457 * start address.
14459 if (contig_len < sizeof(ADV_CARR_T)) {
14460 carrp++;
14461 continue;
14464 carrp->carr_pa = carr_paddr;
14465 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
14468 * Insert the carrier at the beginning of the freelist.
14470 carrp->next_vpa =
14471 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
14472 asc_dvc->carr_freelist = carrp;
14474 carrp++;
14476 while (buf_size > 0);
14479 * Set-up the Host->RISC Initiator Command Queue (ICQ).
14482 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
14483 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14484 return ADV_ERROR;
14486 asc_dvc->carr_freelist = (ADV_CARR_T *)
14487 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
14490 * The first command issued will be placed in the stopper carrier.
14492 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14495 * Set RISC ICQ physical address start value.
14497 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
14500 * Set-up the RISC->Host Initiator Response Queue (IRQ).
14502 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
14503 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
14504 return ADV_ERROR;
14506 asc_dvc->carr_freelist = (ADV_CARR_T *)
14507 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
14510 * The first command completed by the RISC will be placed in
14511 * the stopper.
14513 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
14514 * completed the RISC will set the ASC_RQ_STOPPER bit.
14516 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
14519 * Set RISC IRQ physical address start value.
14521 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
14522 asc_dvc->carr_pending_cnt = 0;
14524 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
14525 (ADV_INTR_ENABLE_HOST_INTR |
14526 ADV_INTR_ENABLE_GLOBAL_INTR));
14528 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
14529 AdvWriteWordRegister(iop_base, IOPW_PC, word);
14531 /* finally, finally, gentlemen, start your engine */
14532 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
14535 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
14536 * Resets should be performed. The RISC has to be running
14537 * to issue a SCSI Bus Reset.
14539 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
14541 * If the BIOS Signature is present in memory, restore the
14542 * BIOS Handshake Configuration Table and do not perform
14543 * a SCSI Bus Reset.
14545 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
14546 0x55AA) {
14548 * Restore per TID negotiated values.
14550 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14551 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14552 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
14553 tagqng_able);
14554 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14555 AdvWriteByteLram(iop_base,
14556 ASC_MC_NUMBER_OF_MAX_CMD + tid,
14557 max_cmd[tid]);
14559 } else {
14560 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
14561 warn_code = ASC_WARN_BUSRESET_ERROR;
14566 return warn_code;
14570 * Initialize the ASC-38C0800.
14572 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14574 * For a non-fatal error return a warning code. If there are no warnings
14575 * then 0 is returned.
14577 * Needed after initialization for error recovery.
14579 static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
14581 AdvPortAddr iop_base;
14582 ushort warn_code;
14583 ADV_DCNT sum;
14584 int begin_addr;
14585 int end_addr;
14586 ushort code_sum;
14587 int word;
14588 int j;
14589 int adv_asc38C0800_expanded_size;
14590 ADV_CARR_T *carrp;
14591 ADV_DCNT contig_len;
14592 ADV_SDCNT buf_size;
14593 ADV_PADDR carr_paddr;
14594 int i;
14595 ushort scsi_cfg1;
14596 uchar byte;
14597 uchar tid;
14598 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
14599 ushort wdtr_able, sdtr_able, tagqng_able;
14600 uchar max_cmd[ADV_MAX_TID + 1];
14602 /* If there is already an error, don't continue. */
14603 if (asc_dvc->err_code != 0) {
14604 return ADV_ERROR;
14608 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
14610 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) {
14611 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
14612 return ADV_ERROR;
14615 warn_code = 0;
14616 iop_base = asc_dvc->iop_base;
14619 * Save the RISC memory BIOS region before writing the microcode.
14620 * The BIOS may already be loaded and using its RISC LRAM region
14621 * so its region must be saved and restored.
14623 * Note: This code makes the assumption, which is currently true,
14624 * that a chip reset does not clear RISC LRAM.
14626 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14627 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14628 bios_mem[i]);
14632 * Save current per TID negotiated values.
14634 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14635 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14636 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14637 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
14638 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14639 max_cmd[tid]);
14643 * RAM BIST (RAM Built-In Self Test)
14645 * Address : I/O base + offset 0x38h register (byte).
14646 * Function: Bit 7-6(RW) : RAM mode
14647 * Normal Mode : 0x00
14648 * Pre-test Mode : 0x40
14649 * RAM Test Mode : 0x80
14650 * Bit 5 : unused
14651 * Bit 4(RO) : Done bit
14652 * Bit 3-0(RO) : Status
14653 * Host Error : 0x08
14654 * Int_RAM Error : 0x04
14655 * RISC Error : 0x02
14656 * SCSI Error : 0x01
14657 * No Error : 0x00
14659 * Note: RAM BIST code should be put right here, before loading the
14660 * microcode and after saving the RISC memory BIOS region.
14664 * LRAM Pre-test
14666 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
14667 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
14668 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
14669 * to NORMAL_MODE, return an error too.
14671 for (i = 0; i < 2; i++) {
14672 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
14673 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14674 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14675 if ((byte & RAM_TEST_DONE) == 0
14676 || (byte & 0x0F) != PRE_TEST_VALUE) {
14677 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14678 return ADV_ERROR;
14681 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14682 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
14683 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
14684 != NORMAL_VALUE) {
14685 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
14686 return ADV_ERROR;
14691 * LRAM Test - It takes about 1.5 ms to run through the test.
14693 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
14694 * If Done bit not set or Status not 0, save register byte, set the
14695 * err_code, and return an error.
14697 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
14698 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
14700 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
14701 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
14702 /* Get here if Done bit not set or Status not 0. */
14703 asc_dvc->bist_err_code = byte; /* for BIOS display message */
14704 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
14705 return ADV_ERROR;
14708 /* We need to reset back to normal mode after LRAM test passes. */
14709 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
14712 * Load the Microcode
14714 * Write the microcode image to RISC memory starting at address 0.
14717 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14719 /* Assume the following compressed format of the microcode buffer:
14721 * 254 word (508 byte) table indexed by byte code followed
14722 * by the following byte codes:
14724 * 1-Byte Code:
14725 * 00: Emit word 0 in table.
14726 * 01: Emit word 1 in table.
14728 * FD: Emit word 253 in table.
14730 * Multi-Byte Code:
14731 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14732 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14734 word = 0;
14735 for (i = 253 * 2; i < _adv_asc38C0800_size; i++) {
14736 if (_adv_asc38C0800_buf[i] == 0xff) {
14737 for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++) {
14738 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14739 _adv_asc38C0800_buf
14740 [i +
14741 3] << 8) |
14742 _adv_asc38C0800_buf
14743 [i + 2]));
14744 word++;
14746 i += 3;
14747 } else if (_adv_asc38C0800_buf[i] == 0xfe) {
14748 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14749 _adv_asc38C0800_buf
14750 [i +
14751 2] << 8) |
14752 _adv_asc38C0800_buf[i
14754 1]));
14755 i += 2;
14756 word++;
14757 } else {
14758 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14759 _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) | _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
14760 word++;
14765 * Set 'word' for later use to clear the rest of memory and save
14766 * the expanded mcode size.
14768 word *= 2;
14769 adv_asc38C0800_expanded_size = word;
14772 * Clear the rest of ASC-38C0800 Internal RAM (16KB).
14774 for (; word < ADV_38C0800_MEMSIZE; word += 2) {
14775 AdvWriteWordAutoIncLram(iop_base, 0);
14779 * Verify the microcode checksum.
14781 sum = 0;
14782 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14784 for (word = 0; word < adv_asc38C0800_expanded_size; word += 2) {
14785 sum += AdvReadWordAutoIncLram(iop_base);
14787 ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
14789 ASC_DBG2(1,
14790 "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
14791 (ulong)sum, (ulong)_adv_asc38C0800_chksum);
14793 if (sum != _adv_asc38C0800_chksum) {
14794 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14795 return ADV_ERROR;
14799 * Restore the RISC memory BIOS region.
14801 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
14802 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
14803 bios_mem[i]);
14807 * Calculate and write the microcode code checksum to the microcode
14808 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14810 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14811 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14812 code_sum = 0;
14813 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14814 for (word = begin_addr; word < end_addr; word += 2) {
14815 code_sum += AdvReadWordAutoIncLram(iop_base);
14817 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14820 * Read microcode version and date.
14822 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
14823 asc_dvc->cfg->mcode_date);
14824 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
14825 asc_dvc->cfg->mcode_version);
14828 * Set the chip type to indicate the ASC38C0800.
14830 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
14833 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
14834 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
14835 * cable detection and then we are able to read C_DET[3:0].
14837 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
14838 * Microcode Default Value' section below.
14840 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14841 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
14842 scsi_cfg1 | DIS_TERM_DRV);
14845 * If the PCI Configuration Command Register "Parity Error Response
14846 * Control" Bit was clear (0), then set the microcode variable
14847 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14848 * to ignore DMA parity errors.
14850 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
14851 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14852 word |= CONTROL_FLAG_IGNORE_PERR;
14853 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14857 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
14858 * bits for the default FIFO threshold.
14860 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
14862 * For DMA Errata #4 set the BC_THRESH_ENB bit.
14864 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14865 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH |
14866 READ_CMD_MRM);
14869 * Microcode operating variables for WDTR, SDTR, and command tag
14870 * queuing will be set in AdvInquiryHandling() based on what a
14871 * device reports it is capable of in Inquiry byte 7.
14873 * If SCSI Bus Resets have been disabled, then directly set
14874 * SDTR and WDTR from the EEPROM configuration. This will allow
14875 * the BIOS and warm boot to work without a SCSI bus hang on
14876 * the Inquiry caused by host and target mismatched DTR values.
14877 * Without the SCSI Bus Reset, before an Inquiry a device can't
14878 * be assumed to be in Asynchronous, Narrow mode.
14880 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
14881 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
14882 asc_dvc->wdtr_able);
14883 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
14884 asc_dvc->sdtr_able);
14888 * Set microcode operating variables for DISC and SDTR_SPEED1,
14889 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
14890 * configuration values.
14892 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14893 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14894 * without determining here whether the device supports SDTR.
14896 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
14897 asc_dvc->cfg->disc_enable);
14898 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
14899 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
14900 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
14901 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
14904 * Set SCSI_CFG0 Microcode Default Value.
14906 * The microcode will set the SCSI_CFG0 register using this value
14907 * after it is started below.
14909 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14910 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14911 asc_dvc->chip_scsi_id);
14914 * Determine SCSI_CFG1 Microcode Default Value.
14916 * The microcode will set the SCSI_CFG1 register using this value
14917 * after it is started below.
14920 /* Read current SCSI_CFG1 Register value. */
14921 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14924 * If the internal narrow cable is reversed all of the SCSI_CTRL
14925 * register signals will be set. Check for and return an error if
14926 * this condition is found.
14928 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
14929 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14930 return ADV_ERROR;
14934 * All kind of combinations of devices attached to one of four connectors
14935 * are acceptable except HVD device attached. For example, LVD device can
14936 * be attached to SE connector while SE device attached to LVD connector.
14937 * If LVD device attached to SE connector, it only runs up to Ultra speed.
14939 * If an HVD device is attached to one of LVD connectors, return an error.
14940 * However, there is no way to detect HVD device attached to SE connectors.
14942 if (scsi_cfg1 & HVD) {
14943 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
14944 return ADV_ERROR;
14948 * If either SE or LVD automatic termination control is enabled, then
14949 * set the termination value based on a table listed in a_condor.h.
14951 * If manual termination was specified with an EEPROM setting then
14952 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
14953 * be 'ored' into SCSI_CFG1.
14955 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
14956 /* SE automatic termination control is enabled. */
14957 switch (scsi_cfg1 & C_DET_SE) {
14958 /* TERM_SE_HI: on, TERM_SE_LO: on */
14959 case 0x1:
14960 case 0x2:
14961 case 0x3:
14962 asc_dvc->cfg->termination |= TERM_SE;
14963 break;
14965 /* TERM_SE_HI: on, TERM_SE_LO: off */
14966 case 0x0:
14967 asc_dvc->cfg->termination |= TERM_SE_HI;
14968 break;
14972 if ((asc_dvc->cfg->termination & TERM_LVD) == 0) {
14973 /* LVD automatic termination control is enabled. */
14974 switch (scsi_cfg1 & C_DET_LVD) {
14975 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
14976 case 0x4:
14977 case 0x8:
14978 case 0xC:
14979 asc_dvc->cfg->termination |= TERM_LVD;
14980 break;
14982 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
14983 case 0x0:
14984 break;
14989 * Clear any set TERM_SE and TERM_LVD bits.
14991 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
14994 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
14996 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
14999 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
15000 * and set possibly modified termination control bits in the Microcode
15001 * SCSI_CFG1 Register Value.
15003 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
15006 * Set SCSI_CFG1 Microcode Default Value
15008 * Set possibly modified termination control and reset DIS_TERM_DRV
15009 * bits in the Microcode SCSI_CFG1 Register Value.
15011 * The microcode will set the SCSI_CFG1 register using this value
15012 * after it is started below.
15014 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15017 * Set MEM_CFG Microcode Default Value
15019 * The microcode will set the MEM_CFG register using this value
15020 * after it is started below.
15022 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15023 * are defined.
15025 * ASC-38C0800 has 16KB internal memory.
15027 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15028 BIOS_EN | RAM_SZ_16KB);
15031 * Set SEL_MASK Microcode Default Value
15033 * The microcode will set the SEL_MASK register using this value
15034 * after it is started below.
15036 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15037 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15040 * Build the carrier freelist.
15042 * Driver must have already allocated memory and set 'carrier_buf'.
15044 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15046 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15047 asc_dvc->carr_freelist = NULL;
15048 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
15049 buf_size = ADV_CARRIER_BUFSIZE;
15050 } else {
15051 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15054 do {
15056 * Get physical address for the carrier 'carrp'.
15058 contig_len = sizeof(ADV_CARR_T);
15059 carr_paddr =
15060 cpu_to_le32(DvcGetPhyAddr
15061 (asc_dvc, NULL, (uchar *)carrp,
15062 (ADV_SDCNT *)&contig_len,
15063 ADV_IS_CARRIER_FLAG));
15065 buf_size -= sizeof(ADV_CARR_T);
15068 * If the current carrier is not physically contiguous, then
15069 * maybe there was a page crossing. Try the next carrier aligned
15070 * start address.
15072 if (contig_len < sizeof(ADV_CARR_T)) {
15073 carrp++;
15074 continue;
15077 carrp->carr_pa = carr_paddr;
15078 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15081 * Insert the carrier at the beginning of the freelist.
15083 carrp->next_vpa =
15084 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15085 asc_dvc->carr_freelist = carrp;
15087 carrp++;
15089 while (buf_size > 0);
15092 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15095 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
15096 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15097 return ADV_ERROR;
15099 asc_dvc->carr_freelist = (ADV_CARR_T *)
15100 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15103 * The first command issued will be placed in the stopper carrier.
15105 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15108 * Set RISC ICQ physical address start value.
15109 * carr_pa is LE, must be native before write
15111 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15114 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15116 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
15117 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15118 return ADV_ERROR;
15120 asc_dvc->carr_freelist = (ADV_CARR_T *)
15121 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15124 * The first command completed by the RISC will be placed in
15125 * the stopper.
15127 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15128 * completed the RISC will set the ASC_RQ_STOPPER bit.
15130 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15133 * Set RISC IRQ physical address start value.
15135 * carr_pa is LE, must be native before write *
15137 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15138 asc_dvc->carr_pending_cnt = 0;
15140 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15141 (ADV_INTR_ENABLE_HOST_INTR |
15142 ADV_INTR_ENABLE_GLOBAL_INTR));
15144 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15145 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15147 /* finally, finally, gentlemen, start your engine */
15148 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15151 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15152 * Resets should be performed. The RISC has to be running
15153 * to issue a SCSI Bus Reset.
15155 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
15157 * If the BIOS Signature is present in memory, restore the
15158 * BIOS Handshake Configuration Table and do not perform
15159 * a SCSI Bus Reset.
15161 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
15162 0x55AA) {
15164 * Restore per TID negotiated values.
15166 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15167 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15168 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
15169 tagqng_able);
15170 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
15171 AdvWriteByteLram(iop_base,
15172 ASC_MC_NUMBER_OF_MAX_CMD + tid,
15173 max_cmd[tid]);
15175 } else {
15176 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
15177 warn_code = ASC_WARN_BUSRESET_ERROR;
15182 return warn_code;
15186 * Initialize the ASC-38C1600.
15188 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
15190 * For a non-fatal error return a warning code. If there are no warnings
15191 * then 0 is returned.
15193 * Needed after initialization for error recovery.
15195 static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
15197 AdvPortAddr iop_base;
15198 ushort warn_code;
15199 ADV_DCNT sum;
15200 int begin_addr;
15201 int end_addr;
15202 ushort code_sum;
15203 long word;
15204 int j;
15205 int adv_asc38C1600_expanded_size;
15206 ADV_CARR_T *carrp;
15207 ADV_DCNT contig_len;
15208 ADV_SDCNT buf_size;
15209 ADV_PADDR carr_paddr;
15210 int i;
15211 ushort scsi_cfg1;
15212 uchar byte;
15213 uchar tid;
15214 ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
15215 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
15216 uchar max_cmd[ASC_MAX_TID + 1];
15218 /* If there is already an error, don't continue. */
15219 if (asc_dvc->err_code != 0) {
15220 return ADV_ERROR;
15224 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
15226 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) {
15227 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
15228 return ADV_ERROR;
15231 warn_code = 0;
15232 iop_base = asc_dvc->iop_base;
15235 * Save the RISC memory BIOS region before writing the microcode.
15236 * The BIOS may already be loaded and using its RISC LRAM region
15237 * so its region must be saved and restored.
15239 * Note: This code makes the assumption, which is currently true,
15240 * that a chip reset does not clear RISC LRAM.
15242 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15243 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15244 bios_mem[i]);
15248 * Save current per TID negotiated values.
15250 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15251 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15252 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15253 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15254 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15255 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15256 max_cmd[tid]);
15260 * RAM BIST (Built-In Self Test)
15262 * Address : I/O base + offset 0x38h register (byte).
15263 * Function: Bit 7-6(RW) : RAM mode
15264 * Normal Mode : 0x00
15265 * Pre-test Mode : 0x40
15266 * RAM Test Mode : 0x80
15267 * Bit 5 : unused
15268 * Bit 4(RO) : Done bit
15269 * Bit 3-0(RO) : Status
15270 * Host Error : 0x08
15271 * Int_RAM Error : 0x04
15272 * RISC Error : 0x02
15273 * SCSI Error : 0x01
15274 * No Error : 0x00
15276 * Note: RAM BIST code should be put right here, before loading the
15277 * microcode and after saving the RISC memory BIOS region.
15281 * LRAM Pre-test
15283 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15284 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15285 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15286 * to NORMAL_MODE, return an error too.
15288 for (i = 0; i < 2; i++) {
15289 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15290 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15291 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15292 if ((byte & RAM_TEST_DONE) == 0
15293 || (byte & 0x0F) != PRE_TEST_VALUE) {
15294 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15295 return ADV_ERROR;
15298 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15299 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15300 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15301 != NORMAL_VALUE) {
15302 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15303 return ADV_ERROR;
15308 * LRAM Test - It takes about 1.5 ms to run through the test.
15310 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15311 * If Done bit not set or Status not 0, save register byte, set the
15312 * err_code, and return an error.
15314 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15315 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
15317 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15318 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) {
15319 /* Get here if Done bit not set or Status not 0. */
15320 asc_dvc->bist_err_code = byte; /* for BIOS display message */
15321 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15322 return ADV_ERROR;
15325 /* We need to reset back to normal mode after LRAM test passes. */
15326 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15329 * Load the Microcode
15331 * Write the microcode image to RISC memory starting at address 0.
15334 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15337 * Assume the following compressed format of the microcode buffer:
15339 * 254 word (508 byte) table indexed by byte code followed
15340 * by the following byte codes:
15342 * 1-Byte Code:
15343 * 00: Emit word 0 in table.
15344 * 01: Emit word 1 in table.
15346 * FD: Emit word 253 in table.
15348 * Multi-Byte Code:
15349 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15350 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15352 word = 0;
15353 for (i = 253 * 2; i < _adv_asc38C1600_size; i++) {
15354 if (_adv_asc38C1600_buf[i] == 0xff) {
15355 for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++) {
15356 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15357 _adv_asc38C1600_buf
15358 [i +
15359 3] << 8) |
15360 _adv_asc38C1600_buf
15361 [i + 2]));
15362 word++;
15364 i += 3;
15365 } else if (_adv_asc38C1600_buf[i] == 0xfe) {
15366 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15367 _adv_asc38C1600_buf
15368 [i +
15369 2] << 8) |
15370 _adv_asc38C1600_buf[i
15372 1]));
15373 i += 2;
15374 word++;
15375 } else {
15376 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15377 _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) | _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
15378 word++;
15383 * Set 'word' for later use to clear the rest of memory and save
15384 * the expanded mcode size.
15386 word *= 2;
15387 adv_asc38C1600_expanded_size = word;
15390 * Clear the rest of ASC-38C1600 Internal RAM (32KB).
15392 for (; word < ADV_38C1600_MEMSIZE; word += 2) {
15393 AdvWriteWordAutoIncLram(iop_base, 0);
15397 * Verify the microcode checksum.
15399 sum = 0;
15400 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15402 for (word = 0; word < adv_asc38C1600_expanded_size; word += 2) {
15403 sum += AdvReadWordAutoIncLram(iop_base);
15406 if (sum != _adv_asc38C1600_chksum) {
15407 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15408 return ADV_ERROR;
15412 * Restore the RISC memory BIOS region.
15414 for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) {
15415 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i),
15416 bios_mem[i]);
15420 * Calculate and write the microcode code checksum to the microcode
15421 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15423 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15424 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15425 code_sum = 0;
15426 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15427 for (word = begin_addr; word < end_addr; word += 2) {
15428 code_sum += AdvReadWordAutoIncLram(iop_base);
15430 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15433 * Read microcode version and date.
15435 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE,
15436 asc_dvc->cfg->mcode_date);
15437 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM,
15438 asc_dvc->cfg->mcode_version);
15441 * Set the chip type to indicate the ASC38C1600.
15443 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
15446 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15447 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15448 * cable detection and then we are able to read C_DET[3:0].
15450 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15451 * Microcode Default Value' section below.
15453 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15454 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1,
15455 scsi_cfg1 | DIS_TERM_DRV);
15458 * If the PCI Configuration Command Register "Parity Error Response
15459 * Control" Bit was clear (0), then set the microcode variable
15460 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15461 * to ignore DMA parity errors.
15463 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) {
15464 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15465 word |= CONTROL_FLAG_IGNORE_PERR;
15466 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15470 * If the BIOS control flag AIPP (Asynchronous Information
15471 * Phase Protection) disable bit is not set, then set the firmware
15472 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
15473 * AIPP checking and encoding.
15475 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) {
15476 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15477 word |= CONTROL_FLAG_ENABLE_AIPP;
15478 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15482 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
15483 * and START_CTL_TH [3:2].
15485 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15486 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
15489 * Microcode operating variables for WDTR, SDTR, and command tag
15490 * queuing will be set in AdvInquiryHandling() based on what a
15491 * device reports it is capable of in Inquiry byte 7.
15493 * If SCSI Bus Resets have been disabled, then directly set
15494 * SDTR and WDTR from the EEPROM configuration. This will allow
15495 * the BIOS and warm boot to work without a SCSI bus hang on
15496 * the Inquiry caused by host and target mismatched DTR values.
15497 * Without the SCSI Bus Reset, before an Inquiry a device can't
15498 * be assumed to be in Asynchronous, Narrow mode.
15500 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) {
15501 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
15502 asc_dvc->wdtr_able);
15503 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
15504 asc_dvc->sdtr_able);
15508 * Set microcode operating variables for DISC and SDTR_SPEED1,
15509 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15510 * configuration values.
15512 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15513 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15514 * without determining here whether the device supports SDTR.
15516 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE,
15517 asc_dvc->cfg->disc_enable);
15518 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15519 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15520 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15521 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15524 * Set SCSI_CFG0 Microcode Default Value.
15526 * The microcode will set the SCSI_CFG0 register using this value
15527 * after it is started below.
15529 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15530 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15531 asc_dvc->chip_scsi_id);
15534 * Calculate SCSI_CFG1 Microcode Default Value.
15536 * The microcode will set the SCSI_CFG1 register using this value
15537 * after it is started below.
15539 * Each ASC-38C1600 function has only two cable detect bits.
15540 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
15542 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15545 * If the cable is reversed all of the SCSI_CTRL register signals
15546 * will be set. Check for and return an error if this condition is
15547 * found.
15549 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) {
15550 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15551 return ADV_ERROR;
15555 * Each ASC-38C1600 function has two connectors. Only an HVD device
15556 * can not be connected to either connector. An LVD device or SE device
15557 * may be connected to either connecor. If an SE device is connected,
15558 * then at most Ultra speed (20 Mhz) can be used on both connectors.
15560 * If an HVD device is attached, return an error.
15562 if (scsi_cfg1 & HVD) {
15563 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15564 return ADV_ERROR;
15568 * Each function in the ASC-38C1600 uses only the SE cable detect and
15569 * termination because there are two connectors for each function. Each
15570 * function may use either LVD or SE mode. Corresponding the SE automatic
15571 * termination control EEPROM bits are used for each function. Each
15572 * function has its own EEPROM. If SE automatic control is enabled for
15573 * the function, then set the termination value based on a table listed
15574 * in a_condor.h.
15576 * If manual termination is specified in the EEPROM for the function,
15577 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
15578 * ready to be 'ored' into SCSI_CFG1.
15580 if ((asc_dvc->cfg->termination & TERM_SE) == 0) {
15581 /* SE automatic termination control is enabled. */
15582 switch (scsi_cfg1 & C_DET_SE) {
15583 /* TERM_SE_HI: on, TERM_SE_LO: on */
15584 case 0x1:
15585 case 0x2:
15586 case 0x3:
15587 asc_dvc->cfg->termination |= TERM_SE;
15588 break;
15590 case 0x0:
15591 if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0) {
15592 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
15593 } else {
15594 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
15595 asc_dvc->cfg->termination |= TERM_SE_HI;
15597 break;
15602 * Clear any set TERM_SE bits.
15604 scsi_cfg1 &= ~TERM_SE;
15607 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
15609 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
15612 * Clear Big Endian and Terminator Polarity bits and set possibly
15613 * modified termination control bits in the Microcode SCSI_CFG1
15614 * Register Value.
15616 * Big Endian bit is not used even on big endian machines.
15618 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
15621 * Set SCSI_CFG1 Microcode Default Value
15623 * Set possibly modified termination control bits in the Microcode
15624 * SCSI_CFG1 Register Value.
15626 * The microcode will set the SCSI_CFG1 register using this value
15627 * after it is started below.
15629 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15632 * Set MEM_CFG Microcode Default Value
15634 * The microcode will set the MEM_CFG register using this value
15635 * after it is started below.
15637 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15638 * are defined.
15640 * ASC-38C1600 has 32KB internal memory.
15642 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
15643 * out a special 16K Adv Library and Microcode version. After the issue
15644 * resolved, we should turn back to the 32K support. Both a_condor.h and
15645 * mcode.sas files also need to be updated.
15647 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15648 * BIOS_EN | RAM_SZ_32KB);
15650 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15651 BIOS_EN | RAM_SZ_16KB);
15654 * Set SEL_MASK Microcode Default Value
15656 * The microcode will set the SEL_MASK register using this value
15657 * after it is started below.
15659 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15660 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15663 * Build the carrier freelist.
15665 * Driver must have already allocated memory and set 'carrier_buf'.
15668 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15670 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15671 asc_dvc->carr_freelist = NULL;
15672 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) {
15673 buf_size = ADV_CARRIER_BUFSIZE;
15674 } else {
15675 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15678 do {
15680 * Get physical address for the carrier 'carrp'.
15682 contig_len = sizeof(ADV_CARR_T);
15683 carr_paddr =
15684 cpu_to_le32(DvcGetPhyAddr
15685 (asc_dvc, NULL, (uchar *)carrp,
15686 (ADV_SDCNT *)&contig_len,
15687 ADV_IS_CARRIER_FLAG));
15689 buf_size -= sizeof(ADV_CARR_T);
15692 * If the current carrier is not physically contiguous, then
15693 * maybe there was a page crossing. Try the next carrier aligned
15694 * start address.
15696 if (contig_len < sizeof(ADV_CARR_T)) {
15697 carrp++;
15698 continue;
15701 carrp->carr_pa = carr_paddr;
15702 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15705 * Insert the carrier at the beginning of the freelist.
15707 carrp->next_vpa =
15708 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15709 asc_dvc->carr_freelist = carrp;
15711 carrp++;
15713 while (buf_size > 0);
15716 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15718 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) {
15719 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15720 return ADV_ERROR;
15722 asc_dvc->carr_freelist = (ADV_CARR_T *)
15723 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15726 * The first command issued will be placed in the stopper carrier.
15728 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15731 * Set RISC ICQ physical address start value. Initialize the
15732 * COMMA register to the same value otherwise the RISC will
15733 * prematurely detect a command is available.
15735 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15736 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
15737 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
15740 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15742 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) {
15743 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15744 return ADV_ERROR;
15746 asc_dvc->carr_freelist = (ADV_CARR_T *)
15747 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15750 * The first command completed by the RISC will be placed in
15751 * the stopper.
15753 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15754 * completed the RISC will set the ASC_RQ_STOPPER bit.
15756 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15759 * Set RISC IRQ physical address start value.
15761 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15762 asc_dvc->carr_pending_cnt = 0;
15764 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15765 (ADV_INTR_ENABLE_HOST_INTR |
15766 ADV_INTR_ENABLE_GLOBAL_INTR));
15767 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15768 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15770 /* finally, finally, gentlemen, start your engine */
15771 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15774 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15775 * Resets should be performed. The RISC has to be running
15776 * to issue a SCSI Bus Reset.
15778 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) {
15780 * If the BIOS Signature is present in memory, restore the
15781 * per TID microcode operating variables.
15783 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] ==
15784 0x55AA) {
15786 * Restore per TID negotiated values.
15788 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15789 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15790 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15791 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
15792 tagqng_able);
15793 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
15794 AdvWriteByteLram(iop_base,
15795 ASC_MC_NUMBER_OF_MAX_CMD + tid,
15796 max_cmd[tid]);
15798 } else {
15799 if (AdvResetSB(asc_dvc) != ADV_TRUE) {
15800 warn_code = ASC_WARN_BUSRESET_ERROR;
15805 return warn_code;
15809 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
15810 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
15811 * all of this is done.
15813 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15815 * For a non-fatal error return a warning code. If there are no warnings
15816 * then 0 is returned.
15818 * Note: Chip is stopped on entry.
15820 static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
15822 AdvPortAddr iop_base;
15823 ushort warn_code;
15824 ADVEEP_3550_CONFIG eep_config;
15825 int i;
15827 iop_base = asc_dvc->iop_base;
15829 warn_code = 0;
15832 * Read the board's EEPROM configuration.
15834 * Set default values if a bad checksum is found.
15836 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum) {
15837 warn_code |= ASC_WARN_EEPROM_CHKSUM;
15840 * Set EEPROM default values.
15842 for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++) {
15843 *((uchar *)&eep_config + i) =
15844 *((uchar *)&Default_3550_EEPROM_Config + i);
15848 * Assume the 6 byte board serial number that was read
15849 * from EEPROM is correct even if the EEPROM checksum
15850 * failed.
15852 eep_config.serial_number_word3 =
15853 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
15855 eep_config.serial_number_word2 =
15856 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
15858 eep_config.serial_number_word1 =
15859 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
15861 AdvSet3550EEPConfig(iop_base, &eep_config);
15864 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
15865 * EEPROM configuration that was read.
15867 * This is the mapping of EEPROM fields to Adv Library fields.
15869 asc_dvc->wdtr_able = eep_config.wdtr_able;
15870 asc_dvc->sdtr_able = eep_config.sdtr_able;
15871 asc_dvc->ultra_able = eep_config.ultra_able;
15872 asc_dvc->tagqng_able = eep_config.tagqng_able;
15873 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
15874 asc_dvc->max_host_qng = eep_config.max_host_qng;
15875 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15876 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
15877 asc_dvc->start_motor = eep_config.start_motor;
15878 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
15879 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
15880 asc_dvc->no_scam = eep_config.scam_tolerant;
15881 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
15882 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
15883 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
15886 * Set the host maximum queuing (max. 253, min. 16) and the per device
15887 * maximum queuing (max. 63, min. 4).
15889 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
15890 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15891 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
15892 /* If the value is zero, assume it is uninitialized. */
15893 if (eep_config.max_host_qng == 0) {
15894 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
15895 } else {
15896 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
15900 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
15901 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15902 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
15903 /* If the value is zero, assume it is uninitialized. */
15904 if (eep_config.max_dvc_qng == 0) {
15905 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
15906 } else {
15907 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
15912 * If 'max_dvc_qng' is greater than 'max_host_qng', then
15913 * set 'max_dvc_qng' to 'max_host_qng'.
15915 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
15916 eep_config.max_dvc_qng = eep_config.max_host_qng;
15920 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
15921 * values based on possibly adjusted EEPROM values.
15923 asc_dvc->max_host_qng = eep_config.max_host_qng;
15924 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
15927 * If the EEPROM 'termination' field is set to automatic (0), then set
15928 * the ADV_DVC_CFG 'termination' field to automatic also.
15930 * If the termination is specified with a non-zero 'termination'
15931 * value check that a legal value is set and set the ADV_DVC_CFG
15932 * 'termination' field appropriately.
15934 if (eep_config.termination == 0) {
15935 asc_dvc->cfg->termination = 0; /* auto termination */
15936 } else {
15937 /* Enable manual control with low off / high off. */
15938 if (eep_config.termination == 1) {
15939 asc_dvc->cfg->termination = TERM_CTL_SEL;
15941 /* Enable manual control with low off / high on. */
15942 } else if (eep_config.termination == 2) {
15943 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
15945 /* Enable manual control with low on / high on. */
15946 } else if (eep_config.termination == 3) {
15947 asc_dvc->cfg->termination =
15948 TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
15949 } else {
15951 * The EEPROM 'termination' field contains a bad value. Use
15952 * automatic termination instead.
15954 asc_dvc->cfg->termination = 0;
15955 warn_code |= ASC_WARN_EEPROM_TERMINATION;
15959 return warn_code;
15963 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
15964 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
15965 * all of this is done.
15967 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15969 * For a non-fatal error return a warning code. If there are no warnings
15970 * then 0 is returned.
15972 * Note: Chip is stopped on entry.
15974 static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
15976 AdvPortAddr iop_base;
15977 ushort warn_code;
15978 ADVEEP_38C0800_CONFIG eep_config;
15979 int i;
15980 uchar tid, termination;
15981 ushort sdtr_speed = 0;
15983 iop_base = asc_dvc->iop_base;
15985 warn_code = 0;
15988 * Read the board's EEPROM configuration.
15990 * Set default values if a bad checksum is found.
15992 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) !=
15993 eep_config.check_sum) {
15994 warn_code |= ASC_WARN_EEPROM_CHKSUM;
15997 * Set EEPROM default values.
15999 for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++) {
16000 *((uchar *)&eep_config + i) =
16001 *((uchar *)&Default_38C0800_EEPROM_Config + i);
16005 * Assume the 6 byte board serial number that was read
16006 * from EEPROM is correct even if the EEPROM checksum
16007 * failed.
16009 eep_config.serial_number_word3 =
16010 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16012 eep_config.serial_number_word2 =
16013 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16015 eep_config.serial_number_word1 =
16016 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16018 AdvSet38C0800EEPConfig(iop_base, &eep_config);
16021 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
16022 * EEPROM configuration that was read.
16024 * This is the mapping of EEPROM fields to Adv Library fields.
16026 asc_dvc->wdtr_able = eep_config.wdtr_able;
16027 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16028 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16029 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16030 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16031 asc_dvc->tagqng_able = eep_config.tagqng_able;
16032 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16033 asc_dvc->max_host_qng = eep_config.max_host_qng;
16034 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16035 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16036 asc_dvc->start_motor = eep_config.start_motor;
16037 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16038 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16039 asc_dvc->no_scam = eep_config.scam_tolerant;
16040 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16041 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16042 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16045 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16046 * are set, then set an 'sdtr_able' bit for it.
16048 asc_dvc->sdtr_able = 0;
16049 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
16050 if (tid == 0) {
16051 sdtr_speed = asc_dvc->sdtr_speed1;
16052 } else if (tid == 4) {
16053 sdtr_speed = asc_dvc->sdtr_speed2;
16054 } else if (tid == 8) {
16055 sdtr_speed = asc_dvc->sdtr_speed3;
16056 } else if (tid == 12) {
16057 sdtr_speed = asc_dvc->sdtr_speed4;
16059 if (sdtr_speed & ADV_MAX_TID) {
16060 asc_dvc->sdtr_able |= (1 << tid);
16062 sdtr_speed >>= 4;
16066 * Set the host maximum queuing (max. 253, min. 16) and the per device
16067 * maximum queuing (max. 63, min. 4).
16069 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
16070 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16071 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
16072 /* If the value is zero, assume it is uninitialized. */
16073 if (eep_config.max_host_qng == 0) {
16074 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16075 } else {
16076 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16080 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
16081 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16082 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
16083 /* If the value is zero, assume it is uninitialized. */
16084 if (eep_config.max_dvc_qng == 0) {
16085 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16086 } else {
16087 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16092 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16093 * set 'max_dvc_qng' to 'max_host_qng'.
16095 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
16096 eep_config.max_dvc_qng = eep_config.max_host_qng;
16100 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16101 * values based on possibly adjusted EEPROM values.
16103 asc_dvc->max_host_qng = eep_config.max_host_qng;
16104 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16107 * If the EEPROM 'termination' field is set to automatic (0), then set
16108 * the ADV_DVC_CFG 'termination' field to automatic also.
16110 * If the termination is specified with a non-zero 'termination'
16111 * value check that a legal value is set and set the ADV_DVC_CFG
16112 * 'termination' field appropriately.
16114 if (eep_config.termination_se == 0) {
16115 termination = 0; /* auto termination for SE */
16116 } else {
16117 /* Enable manual control with low off / high off. */
16118 if (eep_config.termination_se == 1) {
16119 termination = 0;
16121 /* Enable manual control with low off / high on. */
16122 } else if (eep_config.termination_se == 2) {
16123 termination = TERM_SE_HI;
16125 /* Enable manual control with low on / high on. */
16126 } else if (eep_config.termination_se == 3) {
16127 termination = TERM_SE;
16128 } else {
16130 * The EEPROM 'termination_se' field contains a bad value.
16131 * Use automatic termination instead.
16133 termination = 0;
16134 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16138 if (eep_config.termination_lvd == 0) {
16139 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
16140 } else {
16141 /* Enable manual control with low off / high off. */
16142 if (eep_config.termination_lvd == 1) {
16143 asc_dvc->cfg->termination = termination;
16145 /* Enable manual control with low off / high on. */
16146 } else if (eep_config.termination_lvd == 2) {
16147 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16149 /* Enable manual control with low on / high on. */
16150 } else if (eep_config.termination_lvd == 3) {
16151 asc_dvc->cfg->termination = termination | TERM_LVD;
16152 } else {
16154 * The EEPROM 'termination_lvd' field contains a bad value.
16155 * Use automatic termination instead.
16157 asc_dvc->cfg->termination = termination;
16158 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16162 return warn_code;
16166 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
16167 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
16168 * all of this is done.
16170 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
16172 * For a non-fatal error return a warning code. If there are no warnings
16173 * then 0 is returned.
16175 * Note: Chip is stopped on entry.
16177 static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
16179 AdvPortAddr iop_base;
16180 ushort warn_code;
16181 ADVEEP_38C1600_CONFIG eep_config;
16182 int i;
16183 uchar tid, termination;
16184 ushort sdtr_speed = 0;
16186 iop_base = asc_dvc->iop_base;
16188 warn_code = 0;
16191 * Read the board's EEPROM configuration.
16193 * Set default values if a bad checksum is found.
16195 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) !=
16196 eep_config.check_sum) {
16197 warn_code |= ASC_WARN_EEPROM_CHKSUM;
16200 * Set EEPROM default values.
16202 for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++) {
16203 if (i == 1
16204 && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) !=
16205 0) {
16207 * Set Function 1 EEPROM Word 0 MSB
16209 * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11)
16210 * EEPROM bits.
16212 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and
16213 * old Mac system booting problem. The Expansion ROM must
16214 * be disabled in Function 1 for these systems.
16217 *((uchar *)&eep_config + i) =
16219 ((uchar *)&Default_38C1600_EEPROM_Config
16221 i)) &
16223 (((ADV_EEPROM_BIOS_ENABLE |
16224 ADV_EEPROM_INTAB) >> 8) & 0xFF)));
16227 * Set the INTAB (bit 11) if the GPIO 0 input indicates
16228 * the Function 1 interrupt line is wired to INTA.
16230 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
16231 * 1 - Function 1 interrupt line wired to INT A.
16232 * 0 - Function 1 interrupt line wired to INT B.
16234 * Note: Adapter boards always have Function 0 wired to INTA.
16235 * Put all 5 GPIO bits in input mode and then read
16236 * their input values.
16238 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL,
16240 if (AdvReadByteRegister
16241 (iop_base, IOPB_GPIO_DATA) & 0x01) {
16242 /* Function 1 interrupt wired to INTA; Set EEPROM bit. */
16243 *((uchar *)&eep_config + i) |=
16244 ((ADV_EEPROM_INTAB >> 8) & 0xFF);
16246 } else {
16247 *((uchar *)&eep_config + i) =
16248 *((uchar *)&Default_38C1600_EEPROM_Config
16249 + i);
16254 * Assume the 6 byte board serial number that was read
16255 * from EEPROM is correct even if the EEPROM checksum
16256 * failed.
16258 eep_config.serial_number_word3 =
16259 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16261 eep_config.serial_number_word2 =
16262 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16264 eep_config.serial_number_word1 =
16265 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16267 AdvSet38C1600EEPConfig(iop_base, &eep_config);
16271 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16272 * EEPROM configuration that was read.
16274 * This is the mapping of EEPROM fields to Adv Library fields.
16276 asc_dvc->wdtr_able = eep_config.wdtr_able;
16277 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16278 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16279 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16280 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16281 asc_dvc->ppr_able = 0;
16282 asc_dvc->tagqng_able = eep_config.tagqng_able;
16283 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16284 asc_dvc->max_host_qng = eep_config.max_host_qng;
16285 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16286 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
16287 asc_dvc->start_motor = eep_config.start_motor;
16288 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16289 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16290 asc_dvc->no_scam = eep_config.scam_tolerant;
16293 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16294 * are set, then set an 'sdtr_able' bit for it.
16296 asc_dvc->sdtr_able = 0;
16297 for (tid = 0; tid <= ASC_MAX_TID; tid++) {
16298 if (tid == 0) {
16299 sdtr_speed = asc_dvc->sdtr_speed1;
16300 } else if (tid == 4) {
16301 sdtr_speed = asc_dvc->sdtr_speed2;
16302 } else if (tid == 8) {
16303 sdtr_speed = asc_dvc->sdtr_speed3;
16304 } else if (tid == 12) {
16305 sdtr_speed = asc_dvc->sdtr_speed4;
16307 if (sdtr_speed & ASC_MAX_TID) {
16308 asc_dvc->sdtr_able |= (1 << tid);
16310 sdtr_speed >>= 4;
16314 * Set the host maximum queuing (max. 253, min. 16) and the per device
16315 * maximum queuing (max. 63, min. 4).
16317 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) {
16318 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16319 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) {
16320 /* If the value is zero, assume it is uninitialized. */
16321 if (eep_config.max_host_qng == 0) {
16322 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16323 } else {
16324 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16328 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) {
16329 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16330 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) {
16331 /* If the value is zero, assume it is uninitialized. */
16332 if (eep_config.max_dvc_qng == 0) {
16333 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16334 } else {
16335 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16340 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16341 * set 'max_dvc_qng' to 'max_host_qng'.
16343 if (eep_config.max_dvc_qng > eep_config.max_host_qng) {
16344 eep_config.max_dvc_qng = eep_config.max_host_qng;
16348 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
16349 * values based on possibly adjusted EEPROM values.
16351 asc_dvc->max_host_qng = eep_config.max_host_qng;
16352 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16355 * If the EEPROM 'termination' field is set to automatic (0), then set
16356 * the ASC_DVC_CFG 'termination' field to automatic also.
16358 * If the termination is specified with a non-zero 'termination'
16359 * value check that a legal value is set and set the ASC_DVC_CFG
16360 * 'termination' field appropriately.
16362 if (eep_config.termination_se == 0) {
16363 termination = 0; /* auto termination for SE */
16364 } else {
16365 /* Enable manual control with low off / high off. */
16366 if (eep_config.termination_se == 1) {
16367 termination = 0;
16369 /* Enable manual control with low off / high on. */
16370 } else if (eep_config.termination_se == 2) {
16371 termination = TERM_SE_HI;
16373 /* Enable manual control with low on / high on. */
16374 } else if (eep_config.termination_se == 3) {
16375 termination = TERM_SE;
16376 } else {
16378 * The EEPROM 'termination_se' field contains a bad value.
16379 * Use automatic termination instead.
16381 termination = 0;
16382 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16386 if (eep_config.termination_lvd == 0) {
16387 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
16388 } else {
16389 /* Enable manual control with low off / high off. */
16390 if (eep_config.termination_lvd == 1) {
16391 asc_dvc->cfg->termination = termination;
16393 /* Enable manual control with low off / high on. */
16394 } else if (eep_config.termination_lvd == 2) {
16395 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16397 /* Enable manual control with low on / high on. */
16398 } else if (eep_config.termination_lvd == 3) {
16399 asc_dvc->cfg->termination = termination | TERM_LVD;
16400 } else {
16402 * The EEPROM 'termination_lvd' field contains a bad value.
16403 * Use automatic termination instead.
16405 asc_dvc->cfg->termination = termination;
16406 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16410 return warn_code;
16414 * Read EEPROM configuration into the specified buffer.
16416 * Return a checksum based on the EEPROM configuration read.
16418 static ushort __devinit
16419 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16421 ushort wval, chksum;
16422 ushort *wbuf;
16423 int eep_addr;
16424 ushort *charfields;
16426 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16427 wbuf = (ushort *)cfg_buf;
16428 chksum = 0;
16430 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16431 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16432 wval = AdvReadEEPWord(iop_base, eep_addr);
16433 chksum += wval; /* Checksum is calculated from word values. */
16434 if (*charfields++) {
16435 *wbuf = le16_to_cpu(wval);
16436 } else {
16437 *wbuf = wval;
16440 /* Read checksum word. */
16441 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16442 wbuf++;
16443 charfields++;
16445 /* Read rest of EEPROM not covered by the checksum. */
16446 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16447 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16448 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16449 if (*charfields++) {
16450 *wbuf = le16_to_cpu(*wbuf);
16453 return chksum;
16457 * Read EEPROM configuration into the specified buffer.
16459 * Return a checksum based on the EEPROM configuration read.
16461 static ushort __devinit
16462 AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
16464 ushort wval, chksum;
16465 ushort *wbuf;
16466 int eep_addr;
16467 ushort *charfields;
16469 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16470 wbuf = (ushort *)cfg_buf;
16471 chksum = 0;
16473 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16474 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16475 wval = AdvReadEEPWord(iop_base, eep_addr);
16476 chksum += wval; /* Checksum is calculated from word values. */
16477 if (*charfields++) {
16478 *wbuf = le16_to_cpu(wval);
16479 } else {
16480 *wbuf = wval;
16483 /* Read checksum word. */
16484 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16485 wbuf++;
16486 charfields++;
16488 /* Read rest of EEPROM not covered by the checksum. */
16489 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16490 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16491 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16492 if (*charfields++) {
16493 *wbuf = le16_to_cpu(*wbuf);
16496 return chksum;
16500 * Read EEPROM configuration into the specified buffer.
16502 * Return a checksum based on the EEPROM configuration read.
16504 static ushort __devinit
16505 AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
16507 ushort wval, chksum;
16508 ushort *wbuf;
16509 int eep_addr;
16510 ushort *charfields;
16512 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16513 wbuf = (ushort *)cfg_buf;
16514 chksum = 0;
16516 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
16517 eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) {
16518 wval = AdvReadEEPWord(iop_base, eep_addr);
16519 chksum += wval; /* Checksum is calculated from word values. */
16520 if (*charfields++) {
16521 *wbuf = le16_to_cpu(wval);
16522 } else {
16523 *wbuf = wval;
16526 /* Read checksum word. */
16527 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16528 wbuf++;
16529 charfields++;
16531 /* Read rest of EEPROM not covered by the checksum. */
16532 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
16533 eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) {
16534 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
16535 if (*charfields++) {
16536 *wbuf = le16_to_cpu(*wbuf);
16539 return chksum;
16543 * Read the EEPROM from specified location
16545 static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
16547 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16548 ASC_EEP_CMD_READ | eep_word_addr);
16549 AdvWaitEEPCmd(iop_base);
16550 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
16554 * Wait for EEPROM command to complete
16556 static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base)
16558 int eep_delay_ms;
16560 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) {
16561 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) &
16562 ASC_EEP_CMD_DONE) {
16563 break;
16565 DvcSleepMilliSecond(1);
16567 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) ==
16568 0) {
16569 ASC_ASSERT(0);
16571 return;
16575 * Write the EEPROM from 'cfg_buf'.
16577 void __devinit
16578 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
16580 ushort *wbuf;
16581 ushort addr, chksum;
16582 ushort *charfields;
16584 wbuf = (ushort *)cfg_buf;
16585 charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar;
16586 chksum = 0;
16588 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16589 AdvWaitEEPCmd(iop_base);
16592 * Write EEPROM from word 0 to word 20.
16594 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16595 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16596 ushort word;
16598 if (*charfields++) {
16599 word = cpu_to_le16(*wbuf);
16600 } else {
16601 word = *wbuf;
16603 chksum += *wbuf; /* Checksum is calculated from word values. */
16604 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16605 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16606 ASC_EEP_CMD_WRITE | addr);
16607 AdvWaitEEPCmd(iop_base);
16608 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16612 * Write EEPROM checksum at word 21.
16614 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16615 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16616 AdvWaitEEPCmd(iop_base);
16617 wbuf++;
16618 charfields++;
16621 * Write EEPROM OEM name at words 22 to 29.
16623 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16624 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16625 ushort word;
16627 if (*charfields++) {
16628 word = cpu_to_le16(*wbuf);
16629 } else {
16630 word = *wbuf;
16632 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16633 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16634 ASC_EEP_CMD_WRITE | addr);
16635 AdvWaitEEPCmd(iop_base);
16637 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16638 AdvWaitEEPCmd(iop_base);
16639 return;
16643 * Write the EEPROM from 'cfg_buf'.
16645 void __devinit
16646 AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf)
16648 ushort *wbuf;
16649 ushort *charfields;
16650 ushort addr, chksum;
16652 wbuf = (ushort *)cfg_buf;
16653 charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar;
16654 chksum = 0;
16656 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16657 AdvWaitEEPCmd(iop_base);
16660 * Write EEPROM from word 0 to word 20.
16662 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16663 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16664 ushort word;
16666 if (*charfields++) {
16667 word = cpu_to_le16(*wbuf);
16668 } else {
16669 word = *wbuf;
16671 chksum += *wbuf; /* Checksum is calculated from word values. */
16672 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16673 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16674 ASC_EEP_CMD_WRITE | addr);
16675 AdvWaitEEPCmd(iop_base);
16676 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16680 * Write EEPROM checksum at word 21.
16682 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16683 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16684 AdvWaitEEPCmd(iop_base);
16685 wbuf++;
16686 charfields++;
16689 * Write EEPROM OEM name at words 22 to 29.
16691 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16692 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16693 ushort word;
16695 if (*charfields++) {
16696 word = cpu_to_le16(*wbuf);
16697 } else {
16698 word = *wbuf;
16700 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16701 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16702 ASC_EEP_CMD_WRITE | addr);
16703 AdvWaitEEPCmd(iop_base);
16705 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16706 AdvWaitEEPCmd(iop_base);
16707 return;
16711 * Write the EEPROM from 'cfg_buf'.
16713 void __devinit
16714 AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf)
16716 ushort *wbuf;
16717 ushort *charfields;
16718 ushort addr, chksum;
16720 wbuf = (ushort *)cfg_buf;
16721 charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar;
16722 chksum = 0;
16724 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
16725 AdvWaitEEPCmd(iop_base);
16728 * Write EEPROM from word 0 to word 20.
16730 for (addr = ADV_EEP_DVC_CFG_BEGIN;
16731 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) {
16732 ushort word;
16734 if (*charfields++) {
16735 word = cpu_to_le16(*wbuf);
16736 } else {
16737 word = *wbuf;
16739 chksum += *wbuf; /* Checksum is calculated from word values. */
16740 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16741 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16742 ASC_EEP_CMD_WRITE | addr);
16743 AdvWaitEEPCmd(iop_base);
16744 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
16748 * Write EEPROM checksum at word 21.
16750 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
16751 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
16752 AdvWaitEEPCmd(iop_base);
16753 wbuf++;
16754 charfields++;
16757 * Write EEPROM OEM name at words 22 to 29.
16759 for (addr = ADV_EEP_DVC_CTL_BEGIN;
16760 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) {
16761 ushort word;
16763 if (*charfields++) {
16764 word = cpu_to_le16(*wbuf);
16765 } else {
16766 word = *wbuf;
16768 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
16769 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
16770 ASC_EEP_CMD_WRITE | addr);
16771 AdvWaitEEPCmd(iop_base);
16773 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
16774 AdvWaitEEPCmd(iop_base);
16775 return;
16778 /* a_advlib.c */
16780 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
16782 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
16783 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
16784 * RISC to notify it a new command is ready to be executed.
16786 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
16787 * set to SCSI_MAX_RETRY.
16789 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
16790 * for DMA addresses or math operations are byte swapped to little-endian
16791 * order.
16793 * Return:
16794 * ADV_SUCCESS(1) - The request was successfully queued.
16795 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
16796 * request completes.
16797 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
16798 * host IC error.
16800 static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
16802 ulong last_int_level;
16803 AdvPortAddr iop_base;
16804 ADV_DCNT req_size;
16805 ADV_PADDR req_paddr;
16806 ADV_CARR_T *new_carrp;
16808 ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
16811 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
16813 if (scsiq->target_id > ADV_MAX_TID) {
16814 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
16815 scsiq->done_status = QD_WITH_ERROR;
16816 return ADV_ERROR;
16819 iop_base = asc_dvc->iop_base;
16821 last_int_level = DvcEnterCritical();
16824 * Allocate a carrier ensuring at least one carrier always
16825 * remains on the freelist and initialize fields.
16827 if ((new_carrp = asc_dvc->carr_freelist) == NULL) {
16828 DvcLeaveCritical(last_int_level);
16829 return ADV_BUSY;
16831 asc_dvc->carr_freelist = (ADV_CARR_T *)
16832 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
16833 asc_dvc->carr_pending_cnt++;
16836 * Set the carrier to be a stopper by setting 'next_vpa'
16837 * to the stopper value. The current stopper will be changed
16838 * below to point to the new stopper.
16840 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16843 * Clear the ADV_SCSI_REQ_Q done flag.
16845 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
16847 req_size = sizeof(ADV_SCSI_REQ_Q);
16848 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq,
16849 (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG);
16851 ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
16852 ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
16854 /* Wait for assertion before making little-endian */
16855 req_paddr = cpu_to_le32(req_paddr);
16857 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
16858 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
16859 scsiq->scsiq_rptr = req_paddr;
16861 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
16863 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
16864 * order during initialization.
16866 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
16869 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
16870 * the microcode. The newly allocated stopper will become the new
16871 * stopper.
16873 asc_dvc->icq_sp->areq_vpa = req_paddr;
16876 * Set the 'next_vpa' pointer for the old stopper to be the
16877 * physical address of the new stopper. The RISC can only
16878 * follow physical addresses.
16880 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
16883 * Set the host adapter stopper pointer to point to the new carrier.
16885 asc_dvc->icq_sp = new_carrp;
16887 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
16888 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
16890 * Tickle the RISC to tell it to read its Command Queue Head pointer.
16892 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
16893 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
16895 * Clear the tickle value. In the ASC-3550 the RISC flag
16896 * command 'clr_tickle_a' does not work unless the host
16897 * value is cleared.
16899 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
16900 ADV_TICKLE_NOP);
16902 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16904 * Notify the RISC a carrier is ready by writing the physical
16905 * address of the new carrier stopper to the COMMA register.
16907 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
16908 le32_to_cpu(new_carrp->carr_pa));
16911 DvcLeaveCritical(last_int_level);
16913 return ADV_SUCCESS;
16917 * Reset SCSI Bus and purge all outstanding requests.
16919 * Return Value:
16920 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
16921 * ADV_FALSE(0) - Microcode command failed.
16922 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
16923 * may be hung which requires driver recovery.
16925 static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
16927 int status;
16930 * Send the SCSI Bus Reset idle start idle command which asserts
16931 * the SCSI Bus Reset signal.
16933 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L);
16934 if (status != ADV_TRUE) {
16935 return status;
16939 * Delay for the specified SCSI Bus Reset hold time.
16941 * The hold time delay is done on the host because the RISC has no
16942 * microsecond accurate timer.
16944 DvcDelayMicroSecond(asc_dvc, (ushort)ASC_SCSI_RESET_HOLD_TIME_US);
16947 * Send the SCSI Bus Reset end idle command which de-asserts
16948 * the SCSI Bus Reset signal and purges any pending requests.
16950 status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L);
16951 if (status != ADV_TRUE) {
16952 return status;
16955 DvcSleepMilliSecond((ADV_DCNT)asc_dvc->scsi_reset_wait * 1000);
16957 return status;
16961 * Reset chip and SCSI Bus.
16963 * Return Value:
16964 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
16965 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
16967 static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
16969 int status;
16970 ushort wdtr_able, sdtr_able, tagqng_able;
16971 ushort ppr_able = 0;
16972 uchar tid, max_cmd[ADV_MAX_TID + 1];
16973 AdvPortAddr iop_base;
16974 ushort bios_sig;
16976 iop_base = asc_dvc->iop_base;
16979 * Save current per TID negotiated values.
16981 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16982 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16983 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
16984 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16986 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16987 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
16988 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16989 max_cmd[tid]);
16993 * Force the AdvInitAsc3550/38C0800Driver() function to
16994 * perform a SCSI Bus Reset by clearing the BIOS signature word.
16995 * The initialization functions assumes a SCSI Bus Reset is not
16996 * needed if the BIOS signature word is present.
16998 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
16999 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
17002 * Stop chip and reset it.
17004 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
17005 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
17006 DvcSleepMilliSecond(100);
17007 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
17008 ADV_CTRL_REG_CMD_WR_IO_REG);
17011 * Reset Adv Library error code, if any, and try
17012 * re-initializing the chip.
17014 asc_dvc->err_code = 0;
17015 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17016 status = AdvInitAsc38C1600Driver(asc_dvc);
17017 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
17018 status = AdvInitAsc38C0800Driver(asc_dvc);
17019 } else {
17020 status = AdvInitAsc3550Driver(asc_dvc);
17023 /* Translate initialization return value to status value. */
17024 if (status == 0) {
17025 status = ADV_TRUE;
17026 } else {
17027 status = ADV_FALSE;
17031 * Restore the BIOS signature word.
17033 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17036 * Restore per TID negotiated values.
17038 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17039 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17040 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) {
17041 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17043 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17044 for (tid = 0; tid <= ADV_MAX_TID; tid++) {
17045 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17046 max_cmd[tid]);
17049 return status;
17053 * Adv Library Interrupt Service Routine
17055 * This function is called by a driver's interrupt service routine.
17056 * The function disables and re-enables interrupts.
17058 * When a microcode idle command is completed, the ADV_DVC_VAR
17059 * 'idle_cmd_done' field is set to ADV_TRUE.
17061 * Note: AdvISR() can be called when interrupts are disabled or even
17062 * when there is no hardware interrupt condition present. It will
17063 * always check for completed idle commands and microcode requests.
17064 * This is an important feature that shouldn't be changed because it
17065 * allows commands to be completed from polling mode loops.
17067 * Return:
17068 * ADV_TRUE(1) - interrupt was pending
17069 * ADV_FALSE(0) - no interrupt was pending
17071 static int AdvISR(ADV_DVC_VAR *asc_dvc)
17073 AdvPortAddr iop_base;
17074 uchar int_stat;
17075 ushort target_bit;
17076 ADV_CARR_T *free_carrp;
17077 ADV_VADDR irq_next_vpa;
17078 int flags;
17079 ADV_SCSI_REQ_Q *scsiq;
17081 flags = DvcEnterCritical();
17083 iop_base = asc_dvc->iop_base;
17085 /* Reading the register clears the interrupt. */
17086 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
17088 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
17089 ADV_INTR_STATUS_INTRC)) == 0) {
17090 DvcLeaveCritical(flags);
17091 return ADV_FALSE;
17095 * Notify the driver of an asynchronous microcode condition by
17096 * calling the ADV_DVC_VAR.async_callback function. The function
17097 * is passed the microcode ASC_MC_INTRB_CODE byte value.
17099 if (int_stat & ADV_INTR_STATUS_INTRB) {
17100 uchar intrb_code;
17102 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
17104 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17105 asc_dvc->chip_type == ADV_CHIP_ASC38C0800) {
17106 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
17107 asc_dvc->carr_pending_cnt != 0) {
17108 AdvWriteByteRegister(iop_base, IOPB_TICKLE,
17109 ADV_TICKLE_A);
17110 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
17111 AdvWriteByteRegister(iop_base,
17112 IOPB_TICKLE,
17113 ADV_TICKLE_NOP);
17118 if (asc_dvc->async_callback != 0) {
17119 (*asc_dvc->async_callback) (asc_dvc, intrb_code);
17124 * Check if the IRQ stopper carrier contains a completed request.
17126 while (((irq_next_vpa =
17127 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) {
17129 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
17130 * The RISC will have set 'areq_vpa' to a virtual address.
17132 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
17133 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
17134 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
17135 * in AdvExeScsiQueue().
17137 scsiq = (ADV_SCSI_REQ_Q *)
17138 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
17141 * Request finished with good status and the queue was not
17142 * DMAed to host memory by the firmware. Set all status fields
17143 * to indicate good status.
17145 if ((irq_next_vpa & ASC_RQ_GOOD) != 0) {
17146 scsiq->done_status = QD_NO_ERROR;
17147 scsiq->host_status = scsiq->scsi_status = 0;
17148 scsiq->data_cnt = 0L;
17152 * Advance the stopper pointer to the next carrier
17153 * ignoring the lower four bits. Free the previous
17154 * stopper carrier.
17156 free_carrp = asc_dvc->irq_sp;
17157 asc_dvc->irq_sp = (ADV_CARR_T *)
17158 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
17160 free_carrp->next_vpa =
17161 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
17162 asc_dvc->carr_freelist = free_carrp;
17163 asc_dvc->carr_pending_cnt--;
17165 ASC_ASSERT(scsiq != NULL);
17166 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
17169 * Clear request microcode control flag.
17171 scsiq->cntl = 0;
17174 * If the command that completed was a SCSI INQUIRY and
17175 * LUN 0 was sent the command, then process the INQUIRY
17176 * command information for the device.
17178 * Note: If data returned were either VPD or CmdDt data,
17179 * don't process the INQUIRY command information for
17180 * the device, otherwise may erroneously set *_able bits.
17182 if (scsiq->done_status == QD_NO_ERROR &&
17183 scsiq->cdb[0] == INQUIRY &&
17184 scsiq->target_lun == 0 &&
17185 (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
17186 == ADV_INQ_RTN_STD_INQUIRY_DATA) {
17187 AdvInquiryHandling(asc_dvc, scsiq);
17191 * Notify the driver of the completed request by passing
17192 * the ADV_SCSI_REQ_Q pointer to its callback function.
17194 scsiq->a_flag |= ADV_SCSIQ_DONE;
17195 (*asc_dvc->isr_callback) (asc_dvc, scsiq);
17197 * Note: After the driver callback function is called, 'scsiq'
17198 * can no longer be referenced.
17200 * Fall through and continue processing other completed
17201 * requests...
17205 * Disable interrupts again in case the driver inadvertently
17206 * enabled interrupts in its callback function.
17208 * The DvcEnterCritical() return value is ignored, because
17209 * the 'flags' saved when AdvISR() was first entered will be
17210 * used to restore the interrupt flag on exit.
17212 (void)DvcEnterCritical();
17214 DvcLeaveCritical(flags);
17215 return ADV_TRUE;
17219 * Send an idle command to the chip and wait for completion.
17221 * Command completion is polled for once per microsecond.
17223 * The function can be called from anywhere including an interrupt handler.
17224 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
17225 * functions to prevent reentrancy.
17227 * Return Values:
17228 * ADV_TRUE - command completed successfully
17229 * ADV_FALSE - command failed
17230 * ADV_ERROR - command timed out
17232 static int
17233 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
17234 ushort idle_cmd, ADV_DCNT idle_cmd_parameter)
17236 ulong last_int_level;
17237 int result;
17238 ADV_DCNT i, j;
17239 AdvPortAddr iop_base;
17241 last_int_level = DvcEnterCritical();
17243 iop_base = asc_dvc->iop_base;
17246 * Clear the idle command status which is set by the microcode
17247 * to a non-zero value to indicate when the command is completed.
17248 * The non-zero result is one of the IDLE_CMD_STATUS_* values
17249 * defined in a_advlib.h.
17251 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0);
17254 * Write the idle command value after the idle command parameter
17255 * has been written to avoid a race condition. If the order is not
17256 * followed, the microcode may process the idle command before the
17257 * parameters have been written to LRAM.
17259 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
17260 cpu_to_le32(idle_cmd_parameter));
17261 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
17264 * Tickle the RISC to tell it to process the idle command.
17266 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
17267 if (asc_dvc->chip_type == ADV_CHIP_ASC3550) {
17269 * Clear the tickle value. In the ASC-3550 the RISC flag
17270 * command 'clr_tickle_b' does not work unless the host
17271 * value is cleared.
17273 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17276 /* Wait for up to 100 millisecond for the idle command to timeout. */
17277 for (i = 0; i < SCSI_WAIT_100_MSEC; i++) {
17278 /* Poll once each microsecond for command completion. */
17279 for (j = 0; j < SCSI_US_PER_MSEC; j++) {
17280 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS,
17281 result);
17282 if (result != 0) {
17283 DvcLeaveCritical(last_int_level);
17284 return result;
17286 DvcDelayMicroSecond(asc_dvc, (ushort)1);
17290 ASC_ASSERT(0); /* The idle command should never timeout. */
17291 DvcLeaveCritical(last_int_level);
17292 return ADV_ERROR;
17296 * Inquiry Information Byte 7 Handling
17298 * Handle SCSI Inquiry Command information for a device by setting
17299 * microcode operating variables that affect WDTR, SDTR, and Tag
17300 * Queuing.
17302 static void AdvInquiryHandling(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
17304 AdvPortAddr iop_base;
17305 uchar tid;
17306 ADV_SCSI_INQUIRY *inq;
17307 ushort tidmask;
17308 ushort cfg_word;
17311 * AdvInquiryHandling() requires up to INQUIRY information Byte 7
17312 * to be available.
17314 * If less than 8 bytes of INQUIRY information were requested or less
17315 * than 8 bytes were transferred, then return. cdb[4] is the request
17316 * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
17317 * microcode to the transfer residual count.
17320 if (scsiq->cdb[4] < 8 ||
17321 (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8) {
17322 return;
17325 iop_base = asc_dvc->iop_base;
17326 tid = scsiq->target_id;
17328 inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr;
17331 * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
17333 if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2) {
17334 return;
17335 } else {
17337 * INQUIRY Byte 7 Handling
17339 * Use a device's INQUIRY byte 7 to determine whether it
17340 * supports WDTR, SDTR, and Tag Queuing. If the feature
17341 * is enabled in the EEPROM and the device supports the
17342 * feature, then enable it in the microcode.
17345 tidmask = ADV_TID_TO_TIDMASK(tid);
17348 * Wide Transfers
17350 * If the EEPROM enabled WDTR for the device and the device
17351 * supports wide bus (16 bit) transfers, then turn on the
17352 * device's 'wdtr_able' bit and write the new value to the
17353 * microcode.
17355 if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq)) {
17356 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
17357 if ((cfg_word & tidmask) == 0) {
17358 cfg_word |= tidmask;
17359 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE,
17360 cfg_word);
17363 * Clear the microcode "SDTR negotiation" and "WDTR
17364 * negotiation" done indicators for the target to cause
17365 * it to negotiate with the new setting set above.
17366 * WDTR when accepted causes the target to enter
17367 * asynchronous mode, so SDTR must be negotiated.
17369 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE,
17370 cfg_word);
17371 cfg_word &= ~tidmask;
17372 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE,
17373 cfg_word);
17374 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE,
17375 cfg_word);
17376 cfg_word &= ~tidmask;
17377 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE,
17378 cfg_word);
17383 * Synchronous Transfers
17385 * If the EEPROM enabled SDTR for the device and the device
17386 * supports synchronous transfers, then turn on the device's
17387 * 'sdtr_able' bit. Write the new value to the microcode.
17389 if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq)) {
17390 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
17391 if ((cfg_word & tidmask) == 0) {
17392 cfg_word |= tidmask;
17393 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE,
17394 cfg_word);
17397 * Clear the microcode "SDTR negotiation" done indicator
17398 * for the target to cause it to negotiate with the new
17399 * setting set above.
17401 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE,
17402 cfg_word);
17403 cfg_word &= ~tidmask;
17404 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE,
17405 cfg_word);
17409 * If the Inquiry data included enough space for the SPI-3
17410 * Clocking field, then check if DT mode is supported.
17412 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 &&
17413 (scsiq->cdb[4] >= 57 ||
17414 (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57)) {
17416 * PPR (Parallel Protocol Request) Capable
17418 * If the device supports DT mode, then it must be PPR capable.
17419 * The PPR message will be used in place of the SDTR and WDTR
17420 * messages to negotiate synchronous speed and offset, transfer
17421 * width, and protocol options.
17423 if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY) {
17424 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE,
17425 asc_dvc->ppr_able);
17426 asc_dvc->ppr_able |= tidmask;
17427 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE,
17428 asc_dvc->ppr_able);
17433 * If the EEPROM enabled Tag Queuing for the device and the
17434 * device supports Tag Queueing, then turn on the device's
17435 * 'tagqng_enable' bit in the microcode and set the microcode
17436 * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
17437 * value.
17439 * Tag Queuing is disabled for the BIOS which runs in polled
17440 * mode and would see no benefit from Tag Queuing. Also by
17441 * disabling Tag Queuing in the BIOS devices with Tag Queuing
17442 * bugs will at least work with the BIOS.
17444 if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq)) {
17445 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
17446 cfg_word |= tidmask;
17447 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE,
17448 cfg_word);
17450 AdvWriteByteLram(iop_base,
17451 ASC_MC_NUMBER_OF_MAX_CMD + tid,
17452 asc_dvc->max_dvc_qng);
17457 static int __devinit
17458 advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
17460 int req_cnt = 0;
17461 adv_req_t *reqp = NULL;
17462 int sg_cnt = 0;
17463 adv_sgblk_t *sgp;
17464 int warn_code, err_code;
17467 * Allocate buffer carrier structures. The total size
17468 * is about 4 KB, so allocate all at once.
17470 boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
17471 ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp);
17473 if (!boardp->carrp)
17474 goto kmalloc_failed;
17477 * Allocate up to 'max_host_qng' request structures for the Wide
17478 * board. The total size is about 16 KB, so allocate all at once.
17479 * If the allocation fails decrement and try again.
17481 for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
17482 reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
17484 ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, "
17485 "bytes %lu\n", reqp, req_cnt,
17486 (ulong)sizeof(adv_req_t) * req_cnt);
17488 if (reqp)
17489 break;
17492 if (!reqp)
17493 goto kmalloc_failed;
17495 boardp->orig_reqp = reqp;
17498 * Allocate up to ADV_TOT_SG_BLOCK request structures for
17499 * the Wide board. Each structure is about 136 bytes.
17501 boardp->adv_sgblkp = NULL;
17502 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
17503 sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
17505 if (!sgp)
17506 break;
17508 sgp->next_sgblkp = boardp->adv_sgblkp;
17509 boardp->adv_sgblkp = sgp;
17513 ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n",
17514 sg_cnt, sizeof(adv_sgblk_t),
17515 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
17517 if (!boardp->adv_sgblkp)
17518 goto kmalloc_failed;
17520 adv_dvc_varp->carrier_buf = boardp->carrp;
17523 * Point 'adv_reqp' to the request structures and
17524 * link them together.
17526 req_cnt--;
17527 reqp[req_cnt].next_reqp = NULL;
17528 for (; req_cnt > 0; req_cnt--) {
17529 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
17531 boardp->adv_reqp = &reqp[0];
17533 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17534 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n");
17535 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
17536 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17537 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()"
17538 "\n");
17539 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
17540 } else {
17541 ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()"
17542 "\n");
17543 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
17545 err_code = adv_dvc_varp->err_code;
17547 if (warn_code || err_code) {
17548 ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
17549 " error 0x%x\n", boardp->id, warn_code, err_code);
17552 goto exit;
17554 kmalloc_failed:
17555 ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
17556 "failed\n", boardp->id);
17557 err_code = ADV_ERROR;
17558 exit:
17559 return err_code;
17562 static void advansys_wide_free_mem(asc_board_t *boardp)
17564 kfree(boardp->carrp);
17565 boardp->carrp = NULL;
17566 kfree(boardp->orig_reqp);
17567 boardp->orig_reqp = boardp->adv_reqp = NULL;
17568 while (boardp->adv_sgblkp) {
17569 adv_sgblk_t *sgp = boardp->adv_sgblkp;
17570 boardp->adv_sgblkp = sgp->next_sgblkp;
17571 kfree(sgp);
17575 static struct Scsi_Host *__devinit
17576 advansys_board_found(int iop, struct device *dev, int bus_type)
17578 struct Scsi_Host *shost;
17579 struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL;
17580 asc_board_t *boardp;
17581 ASC_DVC_VAR *asc_dvc_varp = NULL;
17582 ADV_DVC_VAR *adv_dvc_varp = NULL;
17583 int share_irq;
17584 int iolen = 0;
17585 ADV_PADDR pci_memory_address;
17586 int warn_code, err_code;
17587 int ret;
17590 * Adapter found.
17592 * Register the adapter, get its configuration, and
17593 * initialize it.
17595 ASC_DBG(2, "advansys_board_found: scsi_host_alloc()\n");
17596 shost = scsi_host_alloc(&advansys_template, sizeof(asc_board_t));
17598 if (!shost)
17599 return NULL;
17601 /* Initialize private per board data */
17602 boardp = ASC_BOARDP(shost);
17603 memset(boardp, 0, sizeof(asc_board_t));
17604 boardp->id = asc_board_count++;
17606 /* Initialize spinlock. */
17607 spin_lock_init(&boardp->lock);
17610 * Handle both narrow and wide boards.
17612 * If a Wide board was detected, set the board structure
17613 * wide board flag. Set-up the board structure based on
17614 * the board type.
17616 #ifdef CONFIG_PCI
17617 if (bus_type == ASC_IS_PCI &&
17618 (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW ||
17619 pdev->device == PCI_DEVICE_ID_38C0800_REV1 ||
17620 pdev->device == PCI_DEVICE_ID_38C1600_REV1)) {
17621 boardp->flags |= ASC_IS_WIDE_BOARD;
17623 #endif /* CONFIG_PCI */
17625 if (ASC_NARROW_BOARD(boardp)) {
17626 ASC_DBG(1, "advansys_board_found: narrow board\n");
17627 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
17628 asc_dvc_varp->bus_type = bus_type;
17629 asc_dvc_varp->drv_ptr = boardp;
17630 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
17631 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
17632 asc_dvc_varp->iop_base = iop;
17633 asc_dvc_varp->isr_callback = asc_isr_callback;
17634 } else {
17635 ASC_DBG(1, "advansys_board_found: wide board\n");
17636 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
17637 adv_dvc_varp->drv_ptr = boardp;
17638 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
17639 adv_dvc_varp->isr_callback = adv_isr_callback;
17640 adv_dvc_varp->async_callback = adv_async_callback;
17641 #ifdef CONFIG_PCI
17642 if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) {
17643 ASC_DBG(1, "advansys_board_found: ASC-3550\n");
17644 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
17645 } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) {
17646 ASC_DBG(1, "advansys_board_found: ASC-38C0800\n");
17647 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
17648 } else {
17649 ASC_DBG(1, "advansys_board_found: ASC-38C1600\n");
17650 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
17652 #endif /* CONFIG_PCI */
17655 * Map the board's registers into virtual memory for
17656 * PCI slave access. Only memory accesses are used to
17657 * access the board's registers.
17659 * Note: The PCI register base address is not always
17660 * page aligned, but the address passed to ioremap()
17661 * must be page aligned. It is guaranteed that the
17662 * PCI register base address will not cross a page
17663 * boundary.
17665 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17666 iolen = ADV_3550_IOLEN;
17667 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17668 iolen = ADV_38C0800_IOLEN;
17669 } else {
17670 iolen = ADV_38C1600_IOLEN;
17672 #ifdef CONFIG_PCI
17673 pci_memory_address = pci_resource_start(pdev, 1);
17674 ASC_DBG1(1,
17675 "advansys_board_found: pci_memory_address: 0x%lx\n",
17676 (ulong)pci_memory_address);
17677 if ((boardp->ioremap_addr =
17678 ioremap(pci_memory_address & PAGE_MASK, PAGE_SIZE)) == 0) {
17679 ASC_PRINT3
17680 ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
17681 boardp->id, pci_memory_address, iolen);
17682 goto err_shost;
17684 ASC_DBG1(1,
17685 "advansys_board_found: ioremap_addr: 0x%lx\n",
17686 (ulong)boardp->ioremap_addr);
17687 adv_dvc_varp->iop_base = (AdvPortAddr)
17688 (boardp->ioremap_addr +
17689 (pci_memory_address - (pci_memory_address & PAGE_MASK)));
17690 ASC_DBG1(1,
17691 "advansys_board_found: iop_base: 0x%lx\n",
17692 adv_dvc_varp->iop_base);
17693 #endif /* CONFIG_PCI */
17696 * Even though it isn't used to access wide boards, other
17697 * than for the debug line below, save I/O Port address so
17698 * that it can be reported.
17700 boardp->ioport = iop;
17702 ASC_DBG2(1,
17703 "advansys_board_found: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
17704 (ushort)inp(iop + 1), (ushort)inpw(iop));
17707 #ifdef CONFIG_PROC_FS
17709 * Allocate buffer for printing information from
17710 * /proc/scsi/advansys/[0...].
17712 boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
17713 if (!boardp->prtbuf) {
17714 ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
17715 "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
17716 goto err_unmap;
17718 #endif /* CONFIG_PROC_FS */
17720 if (ASC_NARROW_BOARD(boardp)) {
17721 asc_dvc_varp->cfg->dev = dev;
17723 * Set the board bus type and PCI IRQ before
17724 * calling AscInitGetConfig().
17726 switch (asc_dvc_varp->bus_type) {
17727 #ifdef CONFIG_ISA
17728 case ASC_IS_ISA:
17729 shost->unchecked_isa_dma = TRUE;
17730 share_irq = 0;
17731 break;
17732 case ASC_IS_VL:
17733 shost->unchecked_isa_dma = FALSE;
17734 share_irq = 0;
17735 break;
17736 case ASC_IS_EISA:
17737 shost->unchecked_isa_dma = FALSE;
17738 share_irq = IRQF_SHARED;
17739 break;
17740 #endif /* CONFIG_ISA */
17741 #ifdef CONFIG_PCI
17742 case ASC_IS_PCI:
17743 shost->irq = asc_dvc_varp->irq_no = pdev->irq;
17744 asc_dvc_varp->cfg->pci_slot_info =
17745 ASC_PCI_MKID(pdev->bus->number,
17746 PCI_SLOT(pdev->devfn),
17747 PCI_FUNC(pdev->devfn));
17748 shost->unchecked_isa_dma = FALSE;
17749 share_irq = IRQF_SHARED;
17750 break;
17751 #endif /* CONFIG_PCI */
17752 default:
17753 ASC_PRINT2
17754 ("advansys_board_found: board %d: unknown adapter type: %d\n",
17755 boardp->id, asc_dvc_varp->bus_type);
17756 shost->unchecked_isa_dma = TRUE;
17757 share_irq = 0;
17758 break;
17760 } else {
17761 adv_dvc_varp->cfg->dev = dev;
17763 * For Wide boards set PCI information before calling
17764 * AdvInitGetConfig().
17766 #ifdef CONFIG_PCI
17767 shost->irq = adv_dvc_varp->irq_no = pdev->irq;
17768 adv_dvc_varp->cfg->pci_slot_info =
17769 ASC_PCI_MKID(pdev->bus->number,
17770 PCI_SLOT(pdev->devfn),
17771 PCI_FUNC(pdev->devfn));
17772 shost->unchecked_isa_dma = FALSE;
17773 share_irq = IRQF_SHARED;
17774 #endif /* CONFIG_PCI */
17778 * Read the board configuration.
17780 if (ASC_NARROW_BOARD(boardp)) {
17782 * NOTE: AscInitGetConfig() may change the board's
17783 * bus_type value. The bus_type value should no
17784 * longer be used. If the bus_type field must be
17785 * referenced only use the bit-wise AND operator "&".
17787 ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n");
17788 switch (ret = AscInitGetConfig(asc_dvc_varp)) {
17789 case 0: /* No error */
17790 break;
17791 case ASC_WARN_IO_PORT_ROTATE:
17792 ASC_PRINT1
17793 ("AscInitGetConfig: board %d: I/O port address modified\n",
17794 boardp->id);
17795 break;
17796 case ASC_WARN_AUTO_CONFIG:
17797 ASC_PRINT1
17798 ("AscInitGetConfig: board %d: I/O port increment switch enabled\n",
17799 boardp->id);
17800 break;
17801 case ASC_WARN_EEPROM_CHKSUM:
17802 ASC_PRINT1
17803 ("AscInitGetConfig: board %d: EEPROM checksum error\n",
17804 boardp->id);
17805 break;
17806 case ASC_WARN_IRQ_MODIFIED:
17807 ASC_PRINT1
17808 ("AscInitGetConfig: board %d: IRQ modified\n",
17809 boardp->id);
17810 break;
17811 case ASC_WARN_CMD_QNG_CONFLICT:
17812 ASC_PRINT1
17813 ("AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
17814 boardp->id);
17815 break;
17816 default:
17817 ASC_PRINT2
17818 ("AscInitGetConfig: board %d: unknown warning: 0x%x\n",
17819 boardp->id, ret);
17820 break;
17822 if ((err_code = asc_dvc_varp->err_code) != 0) {
17823 ASC_PRINT3
17824 ("AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
17825 boardp->id,
17826 asc_dvc_varp->init_state, asc_dvc_varp->err_code);
17828 } else {
17829 ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n");
17830 if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
17831 ASC_PRINT2
17832 ("AdvInitGetConfig: board %d: warning: 0x%x\n",
17833 boardp->id, ret);
17835 if ((err_code = adv_dvc_varp->err_code) != 0) {
17836 ASC_PRINT2
17837 ("AdvInitGetConfig: board %d error: err_code 0x%x\n",
17838 boardp->id, adv_dvc_varp->err_code);
17842 if (err_code != 0)
17843 goto err_free_proc;
17846 * Save the EEPROM configuration so that it can be displayed
17847 * from /proc/scsi/advansys/[0...].
17849 if (ASC_NARROW_BOARD(boardp)) {
17851 ASCEEP_CONFIG *ep;
17854 * Set the adapter's target id bit in the 'init_tidmask' field.
17856 boardp->init_tidmask |=
17857 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
17860 * Save EEPROM settings for the board.
17862 ep = &boardp->eep_config.asc_eep;
17864 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
17865 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
17866 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
17867 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
17868 ep->start_motor = asc_dvc_varp->start_motor;
17869 ep->cntl = asc_dvc_varp->dvc_cntl;
17870 ep->no_scam = asc_dvc_varp->no_scam;
17871 ep->max_total_qng = asc_dvc_varp->max_total_qng;
17872 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
17873 /* 'max_tag_qng' is set to the same value for every device. */
17874 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
17875 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
17876 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
17877 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
17878 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
17879 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
17880 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
17883 * Modify board configuration.
17885 ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n");
17886 switch (ret = AscInitSetConfig(asc_dvc_varp)) {
17887 case 0: /* No error. */
17888 break;
17889 case ASC_WARN_IO_PORT_ROTATE:
17890 ASC_PRINT1
17891 ("AscInitSetConfig: board %d: I/O port address modified\n",
17892 boardp->id);
17893 break;
17894 case ASC_WARN_AUTO_CONFIG:
17895 ASC_PRINT1
17896 ("AscInitSetConfig: board %d: I/O port increment switch enabled\n",
17897 boardp->id);
17898 break;
17899 case ASC_WARN_EEPROM_CHKSUM:
17900 ASC_PRINT1
17901 ("AscInitSetConfig: board %d: EEPROM checksum error\n",
17902 boardp->id);
17903 break;
17904 case ASC_WARN_IRQ_MODIFIED:
17905 ASC_PRINT1
17906 ("AscInitSetConfig: board %d: IRQ modified\n",
17907 boardp->id);
17908 break;
17909 case ASC_WARN_CMD_QNG_CONFLICT:
17910 ASC_PRINT1
17911 ("AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
17912 boardp->id);
17913 break;
17914 default:
17915 ASC_PRINT2
17916 ("AscInitSetConfig: board %d: unknown warning: 0x%x\n",
17917 boardp->id, ret);
17918 break;
17920 if (asc_dvc_varp->err_code != 0) {
17921 ASC_PRINT3
17922 ("AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
17923 boardp->id,
17924 asc_dvc_varp->init_state, asc_dvc_varp->err_code);
17925 goto err_free_proc;
17929 * Finish initializing the 'Scsi_Host' structure.
17931 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
17932 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
17933 shost->irq = asc_dvc_varp->irq_no;
17935 } else {
17936 ADVEEP_3550_CONFIG *ep_3550;
17937 ADVEEP_38C0800_CONFIG *ep_38C0800;
17938 ADVEEP_38C1600_CONFIG *ep_38C1600;
17941 * Save Wide EEP Configuration Information.
17943 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
17944 ep_3550 = &boardp->eep_config.adv_3550_eep;
17946 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
17947 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
17948 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17949 ep_3550->termination = adv_dvc_varp->cfg->termination;
17950 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
17951 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
17952 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
17953 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
17954 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
17955 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
17956 ep_3550->start_motor = adv_dvc_varp->start_motor;
17957 ep_3550->scsi_reset_delay =
17958 adv_dvc_varp->scsi_reset_wait;
17959 ep_3550->serial_number_word1 =
17960 adv_dvc_varp->cfg->serial1;
17961 ep_3550->serial_number_word2 =
17962 adv_dvc_varp->cfg->serial2;
17963 ep_3550->serial_number_word3 =
17964 adv_dvc_varp->cfg->serial3;
17965 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
17966 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
17968 ep_38C0800->adapter_scsi_id =
17969 adv_dvc_varp->chip_scsi_id;
17970 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
17971 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
17972 ep_38C0800->termination_lvd =
17973 adv_dvc_varp->cfg->termination;
17974 ep_38C0800->disc_enable =
17975 adv_dvc_varp->cfg->disc_enable;
17976 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
17977 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
17978 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
17979 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
17980 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
17981 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
17982 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
17983 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
17984 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
17985 ep_38C0800->scsi_reset_delay =
17986 adv_dvc_varp->scsi_reset_wait;
17987 ep_38C0800->serial_number_word1 =
17988 adv_dvc_varp->cfg->serial1;
17989 ep_38C0800->serial_number_word2 =
17990 adv_dvc_varp->cfg->serial2;
17991 ep_38C0800->serial_number_word3 =
17992 adv_dvc_varp->cfg->serial3;
17993 } else {
17994 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
17996 ep_38C1600->adapter_scsi_id =
17997 adv_dvc_varp->chip_scsi_id;
17998 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
17999 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
18000 ep_38C1600->termination_lvd =
18001 adv_dvc_varp->cfg->termination;
18002 ep_38C1600->disc_enable =
18003 adv_dvc_varp->cfg->disc_enable;
18004 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
18005 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
18006 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
18007 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
18008 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
18009 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
18010 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
18011 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
18012 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
18013 ep_38C1600->scsi_reset_delay =
18014 adv_dvc_varp->scsi_reset_wait;
18015 ep_38C1600->serial_number_word1 =
18016 adv_dvc_varp->cfg->serial1;
18017 ep_38C1600->serial_number_word2 =
18018 adv_dvc_varp->cfg->serial2;
18019 ep_38C1600->serial_number_word3 =
18020 adv_dvc_varp->cfg->serial3;
18024 * Set the adapter's target id bit in the 'init_tidmask' field.
18026 boardp->init_tidmask |=
18027 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
18030 * Finish initializing the 'Scsi_Host' structure.
18032 shost->irq = adv_dvc_varp->irq_no;
18036 * Channels are numbered beginning with 0. For AdvanSys one host
18037 * structure supports one channel. Multi-channel boards have a
18038 * separate host structure for each channel.
18040 shost->max_channel = 0;
18041 if (ASC_NARROW_BOARD(boardp)) {
18042 shost->max_id = ASC_MAX_TID + 1;
18043 shost->max_lun = ASC_MAX_LUN + 1;
18045 shost->io_port = asc_dvc_varp->iop_base;
18046 boardp->asc_n_io_port = ASC_IOADR_GAP;
18047 shost->this_id = asc_dvc_varp->cfg->chip_scsi_id;
18049 /* Set maximum number of queues the adapter can handle. */
18050 shost->can_queue = asc_dvc_varp->max_total_qng;
18051 } else {
18052 shost->max_id = ADV_MAX_TID + 1;
18053 shost->max_lun = ADV_MAX_LUN + 1;
18056 * Save the I/O Port address and length even though
18057 * I/O ports are not used to access Wide boards.
18058 * Instead the Wide boards are accessed with
18059 * PCI Memory Mapped I/O.
18061 shost->io_port = iop;
18062 boardp->asc_n_io_port = iolen;
18064 shost->this_id = adv_dvc_varp->chip_scsi_id;
18066 /* Set maximum number of queues the adapter can handle. */
18067 shost->can_queue = adv_dvc_varp->max_host_qng;
18071 * 'n_io_port' currently is one byte.
18073 * Set a value to 'n_io_port', but never referenced it because
18074 * it may be truncated.
18076 shost->n_io_port = boardp->asc_n_io_port <= 255 ?
18077 boardp->asc_n_io_port : 255;
18080 * Following v1.3.89, 'cmd_per_lun' is no longer needed
18081 * and should be set to zero.
18083 * But because of a bug introduced in v1.3.89 if the driver is
18084 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
18085 * SCSI function 'allocate_device' will panic. To allow the driver
18086 * to work as a module in these kernels set 'cmd_per_lun' to 1.
18088 * Note: This is wrong. cmd_per_lun should be set to the depth
18089 * you want on untagged devices always.
18090 #ifdef MODULE
18092 shost->cmd_per_lun = 1;
18093 /* #else
18094 shost->cmd_per_lun = 0;
18095 #endif */
18098 * Set the maximum number of scatter-gather elements the
18099 * adapter can handle.
18101 if (ASC_NARROW_BOARD(boardp)) {
18103 * Allow two commands with 'sg_tablesize' scatter-gather
18104 * elements to be executed simultaneously. This value is
18105 * the theoretical hardware limit. It may be decreased
18106 * below.
18108 shost->sg_tablesize =
18109 (((asc_dvc_varp->max_total_qng - 2) / 2) *
18110 ASC_SG_LIST_PER_Q) + 1;
18111 } else {
18112 shost->sg_tablesize = ADV_MAX_SG_LIST;
18116 * The value of 'sg_tablesize' can not exceed the SCSI
18117 * mid-level driver definition of SG_ALL. SG_ALL also
18118 * must not be exceeded, because it is used to define the
18119 * size of the scatter-gather table in 'struct asc_sg_head'.
18121 if (shost->sg_tablesize > SG_ALL) {
18122 shost->sg_tablesize = SG_ALL;
18125 ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize);
18127 /* BIOS start address. */
18128 if (ASC_NARROW_BOARD(boardp)) {
18129 shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
18130 asc_dvc_varp->bus_type);
18131 } else {
18133 * Fill-in BIOS board variables. The Wide BIOS saves
18134 * information in LRAM that is used by the driver.
18136 AdvReadWordLram(adv_dvc_varp->iop_base,
18137 BIOS_SIGNATURE, boardp->bios_signature);
18138 AdvReadWordLram(adv_dvc_varp->iop_base,
18139 BIOS_VERSION, boardp->bios_version);
18140 AdvReadWordLram(adv_dvc_varp->iop_base,
18141 BIOS_CODESEG, boardp->bios_codeseg);
18142 AdvReadWordLram(adv_dvc_varp->iop_base,
18143 BIOS_CODELEN, boardp->bios_codelen);
18145 ASC_DBG2(1,
18146 "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n",
18147 boardp->bios_signature, boardp->bios_version);
18149 ASC_DBG2(1,
18150 "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n",
18151 boardp->bios_codeseg, boardp->bios_codelen);
18154 * If the BIOS saved a valid signature, then fill in
18155 * the BIOS code segment base address.
18157 if (boardp->bios_signature == 0x55AA) {
18159 * Convert x86 realmode code segment to a linear
18160 * address by shifting left 4.
18162 shost->base = ((ulong)boardp->bios_codeseg << 4);
18163 } else {
18164 shost->base = 0;
18169 * Register Board Resources - I/O Port, DMA, IRQ
18173 * Register I/O port range.
18175 * For Wide boards the I/O ports are not used to access
18176 * the board, but request the region anyway.
18178 * 'shost->n_io_port' is not referenced, because it may be truncated.
18180 ASC_DBG2(2,
18181 "advansys_board_found: request_region port 0x%lx, len 0x%x\n",
18182 (ulong)shost->io_port, boardp->asc_n_io_port);
18183 if (request_region(shost->io_port, boardp->asc_n_io_port,
18184 "advansys") == NULL) {
18185 ASC_PRINT3
18186 ("advansys_board_found: board %d: request_region() failed, port 0x%lx, len 0x%x\n",
18187 boardp->id, (ulong)shost->io_port, boardp->asc_n_io_port);
18188 goto err_free_proc;
18191 /* Register DMA Channel for Narrow boards. */
18192 shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
18193 #ifdef CONFIG_ISA
18194 if (ASC_NARROW_BOARD(boardp)) {
18195 /* Register DMA channel for ISA bus. */
18196 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
18197 shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
18198 ret = request_dma(shost->dma_channel, "advansys");
18199 if (ret) {
18200 ASC_PRINT3
18201 ("advansys_board_found: board %d: request_dma() %d failed %d\n",
18202 boardp->id, shost->dma_channel, ret);
18203 goto err_free_region;
18205 AscEnableIsaDma(shost->dma_channel);
18208 #endif /* CONFIG_ISA */
18210 /* Register IRQ Number. */
18211 ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq);
18213 ret = request_irq(shost->irq, advansys_interrupt, share_irq,
18214 "advansys", shost);
18216 if (ret) {
18217 if (ret == -EBUSY) {
18218 ASC_PRINT2
18219 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
18220 boardp->id, shost->irq);
18221 } else if (ret == -EINVAL) {
18222 ASC_PRINT2
18223 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n",
18224 boardp->id, shost->irq);
18225 } else {
18226 ASC_PRINT3
18227 ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
18228 boardp->id, shost->irq, ret);
18230 goto err_free_dma;
18234 * Initialize board RISC chip and enable interrupts.
18236 if (ASC_NARROW_BOARD(boardp)) {
18237 ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n");
18238 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
18239 err_code = asc_dvc_varp->err_code;
18241 if (warn_code || err_code) {
18242 ASC_PRINT4
18243 ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
18244 boardp->id,
18245 asc_dvc_varp->init_state, warn_code, err_code);
18247 } else {
18248 err_code = advansys_wide_init_chip(boardp, adv_dvc_varp);
18251 if (err_code != 0)
18252 goto err_free_wide_mem;
18254 ASC_DBG_PRT_SCSI_HOST(2, shost);
18256 ret = scsi_add_host(shost, dev);
18257 if (ret)
18258 goto err_free_wide_mem;
18260 scsi_scan_host(shost);
18261 return shost;
18263 err_free_wide_mem:
18264 advansys_wide_free_mem(boardp);
18265 free_irq(shost->irq, shost);
18266 err_free_dma:
18267 if (shost->dma_channel != NO_ISA_DMA)
18268 free_dma(shost->dma_channel);
18269 err_free_region:
18270 release_region(shost->io_port, boardp->asc_n_io_port);
18271 err_free_proc:
18272 kfree(boardp->prtbuf);
18273 err_unmap:
18274 if (boardp->ioremap_addr)
18275 iounmap(boardp->ioremap_addr);
18276 err_shost:
18277 scsi_host_put(shost);
18278 return NULL;
18282 * advansys_release()
18284 * Release resources allocated for a single AdvanSys adapter.
18286 static int advansys_release(struct Scsi_Host *shost)
18288 asc_board_t *boardp;
18290 ASC_DBG(1, "advansys_release: begin\n");
18291 scsi_remove_host(shost);
18292 boardp = ASC_BOARDP(shost);
18293 free_irq(shost->irq, shost);
18294 if (shost->dma_channel != NO_ISA_DMA) {
18295 ASC_DBG(1, "advansys_release: free_dma()\n");
18296 free_dma(shost->dma_channel);
18298 release_region(shost->io_port, boardp->asc_n_io_port);
18299 if (ASC_WIDE_BOARD(boardp)) {
18300 iounmap(boardp->ioremap_addr);
18301 advansys_wide_free_mem(boardp);
18303 kfree(boardp->prtbuf);
18304 scsi_host_put(shost);
18305 ASC_DBG(1, "advansys_release: end\n");
18306 return 0;
18309 static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = {
18310 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190,
18311 0x0210, 0x0230, 0x0250, 0x0330
18314 static int __devinit advansys_isa_probe(struct device *dev, unsigned int id)
18316 PortAddr iop_base = _asc_def_iop_base[id];
18317 struct Scsi_Host *shost;
18319 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
18320 ASC_DBG1(1, "advansys_isa_match: check_region() failed "
18321 "I/O port 0x%x\n", iop_base);
18322 return -ENODEV;
18324 ASC_DBG1(1, "advansys_isa_match: probing I/O port 0x%x\n", iop_base);
18325 release_region(iop_base, ASC_IOADR_GAP);
18326 if (!AscFindSignature(iop_base))
18327 goto nodev;
18328 if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT))
18329 goto nodev;
18331 shost = advansys_board_found(iop_base, dev, ASC_IS_ISA);
18333 if (!shost)
18334 goto nodev;
18336 dev_set_drvdata(dev, shost);
18337 return 0;
18339 nodev:
18340 return -ENODEV;
18343 static int __devexit advansys_isa_remove(struct device *dev, unsigned int id)
18345 advansys_release(dev_get_drvdata(dev));
18346 return 0;
18349 static struct isa_driver advansys_isa_driver = {
18350 .probe = advansys_isa_probe,
18351 .remove = __devexit_p(advansys_isa_remove),
18352 .driver = {
18353 .owner = THIS_MODULE,
18354 .name = "advansys",
18358 static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id)
18360 PortAddr iop_base = _asc_def_iop_base[id];
18361 struct Scsi_Host *shost;
18363 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) {
18364 ASC_DBG1(1, "advansys_vlb_match: check_region() failed "
18365 "I/O port 0x%x\n", iop_base);
18366 return -ENODEV;
18368 ASC_DBG1(1, "advansys_vlb_match: probing I/O port 0x%x\n", iop_base);
18369 release_region(iop_base, ASC_IOADR_GAP);
18370 if (!AscFindSignature(iop_base))
18371 goto nodev;
18373 * I don't think this condition can actually happen, but the old
18374 * driver did it, and the chances of finding a VLB setup in 2007
18375 * to do testing with is slight to none.
18377 if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL)
18378 goto nodev;
18380 shost = advansys_board_found(iop_base, dev, ASC_IS_VL);
18382 if (!shost)
18383 goto nodev;
18385 dev_set_drvdata(dev, shost);
18386 return 0;
18388 nodev:
18389 return -ENODEV;
18392 static struct isa_driver advansys_vlb_driver = {
18393 .probe = advansys_vlb_probe,
18394 .remove = __devexit_p(advansys_isa_remove),
18395 .driver = {
18396 .owner = THIS_MODULE,
18397 .name = "advansys",
18401 static struct eisa_device_id advansys_eisa_table[] __devinitdata = {
18402 { "ABP7401" },
18403 { "ABP7501" },
18404 { "" }
18407 MODULE_DEVICE_TABLE(eisa, advansys_eisa_table);
18410 * EISA is a little more tricky than PCI; each EISA device may have two
18411 * channels, and this driver is written to make each channel its own Scsi_Host
18413 struct eisa_scsi_data {
18414 struct Scsi_Host *host[2];
18417 static int __devinit advansys_eisa_probe(struct device *dev)
18419 int i, ioport;
18420 int err;
18421 struct eisa_device *edev = to_eisa_device(dev);
18422 struct eisa_scsi_data *data;
18424 err = -ENOMEM;
18425 data = kzalloc(sizeof(*data), GFP_KERNEL);
18426 if (!data)
18427 goto fail;
18428 ioport = edev->base_addr + 0xc30;
18430 err = -ENODEV;
18431 for (i = 0; i < 2; i++, ioport += 0x20) {
18432 if (!AscFindSignature(ioport))
18433 continue;
18435 * I don't know why we need to do this for EISA chips, but
18436 * not for any others. It looks to be equivalent to
18437 * AscGetChipCfgMsw, but I may have overlooked something,
18438 * so I'm not converting it until I get an EISA board to
18439 * test with.
18441 inw(ioport + 4);
18442 data->host[i] = advansys_board_found(ioport, dev, ASC_IS_EISA);
18443 if (data->host[i])
18444 err = 0;
18447 if (err) {
18448 kfree(data);
18449 } else {
18450 dev_set_drvdata(dev, data);
18453 fail:
18454 return err;
18457 static __devexit int advansys_eisa_remove(struct device *dev)
18459 int i;
18460 struct eisa_scsi_data *data = dev_get_drvdata(dev);
18462 for (i = 0; i < 2; i++) {
18463 struct Scsi_Host *shost = data->host[i];
18464 if (!shost)
18465 continue;
18466 advansys_release(shost);
18469 kfree(data);
18470 return 0;
18473 static struct eisa_driver advansys_eisa_driver = {
18474 .id_table = advansys_eisa_table,
18475 .driver = {
18476 .name = "advansys",
18477 .probe = advansys_eisa_probe,
18478 .remove = __devexit_p(advansys_eisa_remove),
18482 /* PCI Devices supported by this driver */
18483 static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
18484 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
18485 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18486 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
18487 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18488 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
18489 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18490 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
18491 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18492 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
18493 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18494 {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
18495 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18499 MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
18501 static int __devinit
18502 advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
18504 int err, ioport;
18505 struct Scsi_Host *shost;
18507 err = pci_enable_device(pdev);
18508 if (err)
18509 goto fail;
18511 if (pci_resource_len(pdev, 0) == 0)
18512 goto nodev;
18514 ioport = pci_resource_start(pdev, 0);
18515 shost = advansys_board_found(ioport, &pdev->dev, ASC_IS_PCI);
18517 if (!shost)
18518 goto nodev;
18520 pci_set_drvdata(pdev, shost);
18521 return 0;
18523 nodev:
18524 err = -ENODEV;
18525 pci_disable_device(pdev);
18526 fail:
18527 return err;
18530 static void __devexit advansys_pci_remove(struct pci_dev *pdev)
18532 advansys_release(pci_get_drvdata(pdev));
18533 pci_disable_device(pdev);
18536 static struct pci_driver advansys_pci_driver = {
18537 .name = "advansys",
18538 .id_table = advansys_pci_tbl,
18539 .probe = advansys_pci_probe,
18540 .remove = __devexit_p(advansys_pci_remove),
18543 static int __init advansys_init(void)
18545 int error;
18547 error = isa_register_driver(&advansys_isa_driver,
18548 ASC_IOADR_TABLE_MAX_IX);
18549 if (error)
18550 goto fail;
18552 error = isa_register_driver(&advansys_vlb_driver,
18553 ASC_IOADR_TABLE_MAX_IX);
18554 if (error)
18555 goto unregister_isa;
18557 error = eisa_driver_register(&advansys_eisa_driver);
18558 if (error)
18559 goto unregister_vlb;
18561 error = pci_register_driver(&advansys_pci_driver);
18562 if (error)
18563 goto unregister_eisa;
18565 return 0;
18567 unregister_eisa:
18568 eisa_driver_unregister(&advansys_eisa_driver);
18569 unregister_vlb:
18570 isa_unregister_driver(&advansys_vlb_driver);
18571 unregister_isa:
18572 isa_unregister_driver(&advansys_isa_driver);
18573 fail:
18574 return error;
18577 static void __exit advansys_exit(void)
18579 pci_unregister_driver(&advansys_pci_driver);
18580 eisa_driver_unregister(&advansys_eisa_driver);
18581 isa_unregister_driver(&advansys_vlb_driver);
18582 isa_unregister_driver(&advansys_isa_driver);
18585 module_init(advansys_init);
18586 module_exit(advansys_exit);
18588 MODULE_LICENSE("GPL");