RT-AC66 3.0.0.4.374.130 core
[tomato.git] / release / src-rt-6.x / linux / linux-2.6 / drivers / scsi / advansys.c
blobabf9f44475d1e1816ccec0925c0134f3192ce8d0
1 #define ASC_VERSION "3.3K" /* 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 * All Rights Reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that redistributions of source
12 * code retain the above copyright notice and this comment without
13 * modification.
15 * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys)
16 * changed its name to ConnectCom Solutions, Inc.
22 Documentation for the AdvanSys Driver
24 A. Linux Kernels Supported by this Driver
25 B. Adapters Supported by this Driver
26 C. Linux source files modified by AdvanSys Driver
27 D. Source Comments
28 E. Driver Compile Time Options and Debugging
29 F. Driver LILO Option
30 G. Tests to run before releasing new driver
31 H. Release History
32 I. Known Problems/Fix List
33 J. Credits (Chronological Order)
35 A. Linux Kernels Supported by this Driver
37 This driver has been tested in the following Linux kernels: v2.2.18
38 v2.4.0. The driver is supported on v2.2 and v2.4 kernels and on x86,
39 alpha, and PowerPC platforms.
41 B. Adapters Supported by this Driver
43 AdvanSys (Advanced System Products, Inc.) manufactures the following
44 RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow
45 (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI
46 buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit
47 transfer) SCSI Host Adapters for the PCI bus.
49 The CDB counts below indicate the number of SCSI CDB (Command
50 Descriptor Block) requests that can be stored in the RISC chip
51 cache and board LRAM. A CDB is a single SCSI command. The driver
52 detect routine will display the number of CDBs available for each
53 adapter detected. The number of CDBs used by the driver can be
54 lowered in the BIOS by changing the 'Host Queue Size' adapter setting.
56 Laptop Products:
57 ABP-480 - Bus-Master CardBus (16 CDB) (2.4 kernel and greater)
59 Connectivity Products:
60 ABP510/5150 - Bus-Master ISA (240 CDB)
61 ABP5140 - Bus-Master ISA PnP (16 CDB)
62 ABP5142 - Bus-Master ISA PnP with floppy (16 CDB)
63 ABP902/3902 - Bus-Master PCI (16 CDB)
64 ABP3905 - Bus-Master PCI (16 CDB)
65 ABP915 - Bus-Master PCI (16 CDB)
66 ABP920 - Bus-Master PCI (16 CDB)
67 ABP3922 - Bus-Master PCI (16 CDB)
68 ABP3925 - Bus-Master PCI (16 CDB)
69 ABP930 - Bus-Master PCI (16 CDB)
70 ABP930U - Bus-Master PCI Ultra (16 CDB)
71 ABP930UA - Bus-Master PCI Ultra (16 CDB)
72 ABP960 - Bus-Master PCI MAC/PC (16 CDB)
73 ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
75 Single Channel Products:
76 ABP542 - Bus-Master ISA with floppy (240 CDB)
77 ABP742 - Bus-Master EISA (240 CDB)
78 ABP842 - Bus-Master VL (240 CDB)
79 ABP940 - Bus-Master PCI (240 CDB)
80 ABP940U - Bus-Master PCI Ultra (240 CDB)
81 ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB)
82 ABP970 - Bus-Master PCI MAC/PC (240 CDB)
83 ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
84 ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB)
85 ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB)
86 ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB)
87 ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB)
89 Multi-Channel Products:
90 ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel)
91 ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel)
92 ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
93 ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel)
94 ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
95 ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
96 ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.)
97 ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB)
98 ABP3950U3W - Bus-Master PCI Dual LVD2/Ultra3-Wide (253 CDB)
100 C. Linux source files modified by AdvanSys Driver
102 This section for historical purposes documents the changes
103 originally made to the Linux kernel source to add the advansys
104 driver. As Linux has changed some of these files have also
105 been modified.
107 1. linux/arch/i386/config.in:
109 bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
111 2. linux/drivers/scsi/hosts.c:
113 #ifdef CONFIG_SCSI_ADVANSYS
114 #include "advansys.h"
115 #endif
117 and after "static struct scsi_host_template builtin_scsi_hosts[] =":
119 #ifdef CONFIG_SCSI_ADVANSYS
120 ADVANSYS,
121 #endif
123 3. linux/drivers/scsi/Makefile:
125 ifdef CONFIG_SCSI_ADVANSYS
126 SCSI_SRCS := $(SCSI_SRCS) advansys.c
127 SCSI_OBJS := $(SCSI_OBJS) advansys.o
128 else
129 SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
130 endif
132 4. linux/init/main.c:
134 extern void advansys_setup(char *str, int *ints);
136 and add the following lines to the bootsetups[] array.
138 #ifdef CONFIG_SCSI_ADVANSYS
139 { "advansys=", advansys_setup },
140 #endif
142 D. Source Comments
144 1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
146 2. This driver should be maintained in multiple files. But to make
147 it easier to include with Linux and to follow Linux conventions,
148 the whole driver is maintained in the source files advansys.h and
149 advansys.c. In this file logical sections of the driver begin with
150 a comment that contains '---'. The following are the logical sections
151 of the driver below.
153 --- Linux Version
154 --- Linux Include File
155 --- Driver Options
156 --- Debugging Header
157 --- Asc Library Constants and Macros
158 --- Adv Library Constants and Macros
159 --- Driver Constants and Macros
160 --- Driver Structures
161 --- Driver Data
162 --- Driver Function Prototypes
163 --- Linux 'struct scsi_host_template' and advansys_setup() Functions
164 --- Loadable Driver Support
165 --- Miscellaneous Driver Functions
166 --- Functions Required by the Asc Library
167 --- Functions Required by the Adv Library
168 --- Tracing and Debugging Functions
169 --- Asc Library Functions
170 --- Adv Library Functions
172 3. The string 'XXX' is used to flag code that needs to be re-written
173 or that contains a problem that needs to be addressed.
175 4. I have stripped comments from and reformatted the source for the
176 Asc Library and Adv Library to reduce the size of this file. This
177 source can be found under the following headings. The Asc Library
178 is used to support Narrow Boards. The Adv Library is used to
179 support Wide Boards.
181 --- Asc Library Constants and Macros
182 --- Adv Library Constants and Macros
183 --- Asc Library Functions
184 --- Adv Library Functions
186 E. Driver Compile Time Options and Debugging
188 In this source file the following constants can be defined. They are
189 defined in the source below. Both of these options are enabled by
190 default.
192 1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled)
194 Enabling this option adds assertion logic statements to the
195 driver. If an assertion fails a message will be displayed to
196 the console, but the system will continue to operate. Any
197 assertions encountered should be reported to the person
198 responsible for the driver. Assertion statements may proactively
199 detect problems with the driver and facilitate fixing these
200 problems. Enabling assertions will add a small overhead to the
201 execution of the driver.
203 2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled)
205 Enabling this option adds tracing functions to the driver and
206 the ability to set a driver tracing level at boot time. This
207 option will also export symbols not required outside the driver to
208 the kernel name space. This option is very useful for debugging
209 the driver, but it will add to the size of the driver execution
210 image and add overhead to the execution of the driver.
212 The amount of debugging output can be controlled with the global
213 variable 'asc_dbglvl'. The higher the number the more output. By
214 default the debug level is 0.
216 If the driver is loaded at boot time and the LILO Driver Option
217 is included in the system, the debug level can be changed by
218 specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The
219 first three hex digits of the pseudo I/O Port must be set to
220 'deb' and the fourth hex digit specifies the debug level: 0 - F.
221 The following command line will look for an adapter at 0x330
222 and set the debug level to 2.
224 linux advansys=0x330,0,0,0,0xdeb2
226 If the driver is built as a loadable module this variable can be
227 defined when the driver is loaded. The following insmod command
228 will set the debug level to one.
230 insmod advansys.o asc_dbglvl=1
232 Debugging Message Levels:
233 0: Errors Only
234 1: High-Level Tracing
235 2-N: Verbose Tracing
237 To enable debug output to console, please make sure that:
239 a. System and kernel logging is enabled (syslogd, klogd running).
240 b. Kernel messages are routed to console output. Check
241 /etc/syslog.conf for an entry similar to this:
243 kern.* /dev/console
245 c. klogd is started with the appropriate -c parameter
246 (e.g. klogd -c 8)
248 This will cause printk() messages to be be displayed on the
249 current console. Refer to the klogd(8) and syslogd(8) man pages
250 for details.
252 Alternatively you can enable printk() to console with this
253 program. However, this is not the 'official' way to do this.
254 Debug output is logged in /var/log/messages.
256 main()
258 syscall(103, 7, 0, 0);
261 Increasing LOG_BUF_LEN in kernel/printk.c to something like
262 40960 allows more debug messages to be buffered in the kernel
263 and written to the console or log file.
265 3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0)
267 Enabling this option adds statistics collection and display
268 through /proc to the driver. The information is useful for
269 monitoring driver and device performance. It will add to the
270 size of the driver execution image and add minor overhead to
271 the execution of the driver.
273 Statistics are maintained on a per adapter basis. Driver entry
274 point call counts and transfer size counts are maintained.
275 Statistics are only available for kernels greater than or equal
276 to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured.
278 AdvanSys SCSI adapter files have the following path name format:
280 /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
282 This information can be displayed with cat. For example:
284 cat /proc/scsi/advansys/0
286 When ADVANSYS_STATS is not defined the AdvanSys /proc files only
287 contain adapter and device configuration information.
289 F. Driver LILO Option
291 If init/main.c is modified as described in the 'Directions for Adding
292 the AdvanSys Driver to Linux' section (B.4.) above, the driver will
293 recognize the 'advansys' LILO command line and /etc/lilo.conf option.
294 This option can be used to either disable I/O port scanning or to limit
295 scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
296 PCI boards will still be searched for and detected. This option only
297 affects searching for ISA and VL boards.
299 Examples:
300 1. Eliminate I/O port scanning:
301 boot: linux advansys=
303 boot: linux advansys=0x0
304 2. Limit I/O port scanning to one I/O port:
305 boot: linux advansys=0x110
306 3. Limit I/O port scanning to four I/O ports:
307 boot: linux advansys=0x110,0x210,0x230,0x330
309 For a loadable module the same effect can be achieved by setting
310 the 'asc_iopflag' variable and 'asc_ioport' array when loading
311 the driver, e.g.
313 insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
315 If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1)
316 I/O Port may be added to specify the driver debug level. Refer to
317 the 'Driver Compile Time Options and Debugging' section above for
318 more information.
320 G. Tests to run before releasing new driver
322 1. In the supported kernels verify there are no warning or compile
323 errors when the kernel is built as both a driver and as a module
324 and with the following options:
326 ADVANSYS_DEBUG - enabled and disabled
327 CONFIG_SMP - enabled and disabled
328 CONFIG_PROC_FS - enabled and disabled
330 2. Run tests on an x86, alpha, and PowerPC with at least one narrow
331 card and one wide card attached to a hard disk and CD-ROM drive:
332 fdisk, mkfs, fsck, bonnie, copy/compare test from the
333 CD-ROM to the hard drive.
335 H. Release History
337 BETA-1.0 (12/23/95):
338 First Release
340 BETA-1.1 (12/28/95):
341 1. Prevent advansys_detect() from being called twice.
342 2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
344 1.2 (1/12/96):
345 1. Prevent re-entrancy in the interrupt handler which
346 resulted in the driver hanging Linux.
347 2. Fix problem that prevented ABP-940 cards from being
348 recognized on some PCI motherboards.
349 3. Add support for the ABP-5140 PnP ISA card.
350 4. Fix check condition return status.
351 5. Add conditionally compiled code for Linux v1.3.X.
353 1.3 (2/23/96):
354 1. Fix problem in advansys_biosparam() that resulted in the
355 wrong drive geometry being returned for drives > 1GB with
356 extended translation enabled.
357 2. Add additional tracing during device initialization.
358 3. Change code that only applies to ISA PnP adapter.
359 4. Eliminate 'make dep' warning.
360 5. Try to fix problem with handling resets by increasing their
361 timeout value.
363 1.4 (5/8/96):
364 1. Change definitions to eliminate conflicts with other subsystems.
365 2. Add versioning code for the shared interrupt changes.
366 3. Eliminate problem in asc_rmqueue() with iterating after removing
367 a request.
368 4. Remove reset request loop problem from the "Known Problems or
369 Issues" section. This problem was isolated and fixed in the
370 mid-level SCSI driver.
372 1.5 (8/8/96):
373 1. Add support for ABP-940U (PCI Ultra) adapter.
374 2. Add support for IRQ sharing by setting the IRQF_SHARED flag for
375 request_irq and supplying a dev_id pointer to both request_irq()
376 and free_irq().
377 3. In AscSearchIOPortAddr11() restore a call to check_region() which
378 should be used before I/O port probing.
379 4. Fix bug in asc_prt_hex() which resulted in the displaying
380 the wrong data.
381 5. Incorporate miscellaneous Asc Library bug fixes and new microcode.
382 6. Change driver versioning to be specific to each Linux sub-level.
383 7. Change statistics gathering to be per adapter instead of global
384 to the driver.
385 8. Add more information and statistics to the adapter /proc file:
386 /proc/scsi/advansys[0...].
387 9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list.
388 This problem has been addressed with the SCSI mid-level changes
389 made in v1.3.89. The advansys_select_queue_depths() function
390 was added for the v1.3.89 changes.
392 1.6 (9/10/96):
393 1. Incorporate miscellaneous Asc Library bug fixes and new microcode.
395 1.7 (9/25/96):
396 1. Enable clustering and optimize the setting of the maximum number
397 of scatter gather elements for any particular board. Clustering
398 increases CPU utilization, but results in a relatively larger
399 increase in I/O throughput.
400 2. Improve the performance of the request queuing functions by
401 adding a last pointer to the queue structure.
402 3. Correct problems with reset and abort request handling that
403 could have hung or crashed Linux.
404 4. Add more information to the adapter /proc file:
405 /proc/scsi/advansys[0...].
406 5. Remove the request timeout issue form the driver issues list.
407 6. Miscellaneous documentation additions and changes.
409 1.8 (10/4/96):
410 1. Make changes to handle the new v2.1.0 kernel memory mapping
411 in which a kernel virtual address may not be equivalent to its
412 bus or DMA memory address.
413 2. Change abort and reset request handling to make it yet even
414 more robust.
415 3. Try to mitigate request starvation by sending ordered requests
416 to heavily loaded, tag queuing enabled devices.
417 4. Maintain statistics on request response time.
418 5. Add request response time statistics and other information to
419 the adapter /proc file: /proc/scsi/advansys[0...].
421 1.9 (10/21/96):
422 1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to
423 make use of mid-level SCSI driver device queue depth flow
424 control mechanism. This will eliminate aborts caused by a
425 device being unable to keep up with requests and eliminate
426 repeat busy or QUEUE FULL status returned by a device.
427 2. Incorporate miscellaneous Asc Library bug fixes.
428 3. To allow the driver to work in kernels with broken module
429 support set 'cmd_per_lun' if the driver is compiled as a
430 module. This change affects kernels v1.3.89 to present.
431 4. Remove PCI BIOS address from the driver banner. The PCI BIOS
432 is relocated by the motherboard BIOS and its new address can
433 not be determined by the driver.
434 5. Add mid-level SCSI queue depth information to the adapter
435 /proc file: /proc/scsi/advansys[0...].
437 2.0 (11/14/96):
438 1. Change allocation of global structures used for device
439 initialization to guarantee they are in DMA-able memory.
440 Previously when the driver was loaded as a module these
441 structures might not have been in DMA-able memory, causing
442 device initialization to fail.
444 2.1 (12/30/96):
445 1. In advansys_reset(), if the request is a synchronous reset
446 request, even if the request serial number has changed, then
447 complete the request.
448 2. Add Asc Library bug fixes including new microcode.
449 3. Clear inquiry buffer before using it.
450 4. Correct ifdef typo.
452 2.2 (1/15/97):
453 1. Add Asc Library bug fixes including new microcode.
454 2. Add synchronous data transfer rate information to the
455 adapter /proc file: /proc/scsi/advansys[0...].
456 3. Change ADVANSYS_DEBUG to be disabled by default. This
457 will reduce the size of the driver image, eliminate execution
458 overhead, and remove unneeded symbols from the kernel symbol
459 space that were previously added by the driver.
460 4. Add new compile-time option ADVANSYS_ASSERT for assertion
461 code that used to be defined within ADVANSYS_DEBUG. This
462 option is enabled by default.
464 2.8 (5/26/97):
465 1. Change version number to 2.8 to synchronize the Linux driver
466 version numbering with other AdvanSys drivers.
467 2. Reformat source files without tabs to present the same view
468 of the file to everyone regardless of the editor tab setting
469 being used.
470 3. Add Asc Library bug fixes.
472 3.1A (1/8/98):
473 1. Change version number to 3.1 to indicate that support for
474 Ultra-Wide adapters (ABP-940UW) is included in this release.
475 2. Add Asc Library (Narrow Board) bug fixes.
476 3. Report an underrun condition with the host status byte set
477 to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which
478 causes the underrun condition to be ignored. When Linux defines
479 its own DID_UNDERRUN the constant defined in this file can be
480 removed.
481 4. Add patch to AscWaitTixISRDone().
482 5. Add support for up to 16 different AdvanSys host adapter SCSI
483 channels in one system. This allows four cards with four channels
484 to be used in one system.
486 3.1B (1/9/98):
487 1. Handle that PCI register base addresses are not always page
488 aligned even though ioremap() requires that the address argument
489 be page aligned.
491 3.1C (1/10/98):
492 1. Update latest BIOS version checked for from the /proc file.
493 2. Don't set microcode SDTR variable at initialization. Instead
494 wait until device capabilities have been detected from an Inquiry
495 command.
497 3.1D (1/21/98):
498 1. Improve performance when the driver is compiled as module by
499 allowing up to 64 scatter-gather elements instead of 8.
501 3.1E (5/1/98):
502 1. Set time delay in AscWaitTixISRDone() to 1000 ms.
503 2. Include SMP locking changes.
504 3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS
505 access functions.
506 4. Update board serial number printing.
507 5. Try allocating an IRQ both with and without the IRQF_DISABLED
508 flag set to allow IRQ sharing with drivers that do not set
509 the IRQF_DISABLED flag. Also display a more descriptive error
510 message if request_irq() fails.
511 6. Update to latest Asc and Adv Libraries.
513 3.2A (7/22/99):
514 1. Update Adv Library to 4.16 which includes support for
515 the ASC38C0800 (Ultra2/LVD) IC.
517 3.2B (8/23/99):
518 1. Correct PCI compile time option for v2.1.93 and greater
519 kernels, advansys_info() string, and debug compile time
520 option.
521 2. Correct DvcSleepMilliSecond() for v2.1.0 and greater
522 kernels. This caused an LVD detection/BIST problem problem
523 among other things.
524 3. Sort PCI cards by PCI Bus, Slot, Function ascending order
525 to be consistent with the BIOS.
526 4. Update to Asc Library S121 and Adv Library 5.2.
528 3.2C (8/24/99):
529 1. Correct PCI card detection bug introduced in 3.2B that
530 prevented PCI cards from being detected in kernels older
531 than v2.1.93.
533 3.2D (8/26/99):
534 1. Correct /proc device synchronous speed information display.
535 Also when re-negotiation is pending for a target device
536 note this condition with an * and footnote.
537 2. Correct initialization problem with Ultra-Wide cards that
538 have a pre-3.2 BIOS. A microcode variable changed locations
539 in 3.2 and greater BIOSes which caused WDTR to be attempted
540 erroneously with drives that don't support WDTR.
542 3.2E (8/30/99):
543 1. Fix compile error caused by v2.3.13 PCI structure change.
544 2. Remove field from ASCEEP_CONFIG that resulted in an EEPROM
545 checksum error for ISA cards.
546 3. Remove ASC_QUEUE_FLOW_CONTROL conditional code. The mid-level
547 SCSI changes that it depended on were never included in Linux.
549 3.2F (9/3/99):
550 1. Handle new initial function code added in v2.3.16 for all
551 driver versions.
553 3.2G (9/8/99):
554 1. Fix PCI board detection in v2.3.13 and greater kernels.
555 2. Fix comiple errors in v2.3.X with debugging enabled.
557 3.2H (9/13/99):
558 1. Add 64-bit address, long support for Alpha and UltraSPARC.
559 The driver has been verified to work on an Alpha system.
560 2. Add partial byte order handling support for Power PC and
561 other big-endian platforms. This support has not yet been
562 completed or verified.
563 3. For wide boards replace block zeroing of request and
564 scatter-gather structures with individual field initialization
565 to improve performance.
566 4. Correct and clarify ROM BIOS version detection.
568 3.2I (10/8/99):
569 1. Update to Adv Library 5.4.
570 2. Add v2.3.19 underrun reporting to asc_isr_callback() and
571 adv_isr_callback(). Remove DID_UNDERRUN constant and other
572 no longer needed code that previously documented the lack
573 of underrun handling.
575 3.2J (10/14/99):
576 1. Eliminate compile errors for v2.0 and earlier kernels.
578 3.2K (11/15/99):
579 1. Correct debug compile error in asc_prt_adv_scsi_req_q().
580 2. Update Adv Library to 5.5.
581 3. Add ifdef handling for /proc changes added in v2.3.28.
582 4. Increase Wide board scatter-gather list maximum length to
583 255 when the driver is compiled into the kernel.
585 3.2L (11/18/99):
586 1. Fix bug in adv_get_sglist() that caused an assertion failure
587 at line 7475. The reqp->sgblkp pointer must be initialized
588 to NULL in adv_get_sglist().
590 3.2M (11/29/99):
591 1. Really fix bug in adv_get_sglist().
592 2. Incorporate v2.3.29 changes into driver.
594 3.2N (4/1/00):
595 1. Add CONFIG_ISA ifdef code.
596 2. Include advansys_interrupts_enabled name change patch.
597 3. For >= v2.3.28 use new SCSI error handling with new function
598 advansys_eh_bus_reset(). Don't include an abort function
599 because of base library limitations.
600 4. For >= v2.3.28 use per board lock instead of io_request_lock.
601 5. For >= v2.3.28 eliminate advansys_command() and
602 advansys_command_done().
603 6. Add some changes for PowerPC (Big Endian) support, but it isn't
604 working yet.
605 7. Fix "nonexistent resource free" problem that occurred on a module
606 unload for boards with an I/O space >= 255. The 'n_io_port' field
607 is only one byte and can not be used to hold an ioport length more
608 than 255.
610 3.3A (4/4/00):
611 1. Update to Adv Library 5.8.
612 2. For wide cards add support for CDBs up to 16 bytes.
613 3. Eliminate warnings when CONFIG_PROC_FS is not defined.
615 3.3B (5/1/00):
616 1. Support for PowerPC (Big Endian) wide cards. Narrow cards
617 still need work.
618 2. Change bitfields to shift and mask access for endian
619 portability.
621 3.3C (10/13/00):
622 1. Update for latest 2.4 kernel.
623 2. Test ABP-480 CardBus support in 2.4 kernel - works!
624 3. Update to Asc Library S123.
625 4. Update to Adv Library 5.12.
627 3.3D (11/22/00):
628 1. Update for latest 2.4 kernel.
629 2. Create patches for 2.2 and 2.4 kernels.
631 3.3E (1/9/01):
632 1. Now that 2.4 is released remove ifdef code for kernel versions
633 less than 2.2. The driver is now only supported in kernels 2.2,
634 2.4, and greater.
635 2. Add code to release and acquire the io_request_lock in
636 the driver entrypoint functions: advansys_detect and
637 advansys_queuecommand. In kernel 2.4 the SCSI mid-level driver
638 still holds the io_request_lock on entry to SCSI low-level drivers.
639 This was supposed to be removed before 2.4 was released but never
640 happened. When the mid-level SCSI driver is changed all references
641 to the io_request_lock should be removed from the driver.
642 3. Simplify error handling by removing advansys_abort(),
643 AscAbortSRB(), AscResetDevice(). SCSI bus reset requests are
644 now handled by resetting the SCSI bus and fully re-initializing
645 the chip. This simple method of error recovery has proven to work
646 most reliably after attempts at different methods. Also now only
647 support the "new" error handling method and remove the obsolete
648 error handling interface.
649 4. Fix debug build errors.
651 3.3F (1/24/01):
652 1. Merge with ConnectCom version from Andy Kellner which
653 updates Adv Library to 5.14.
654 2. Make PowerPC (Big Endian) work for narrow cards and
655 fix problems writing EEPROM for wide cards.
656 3. Remove interrupts_enabled assertion function.
658 3.3G (2/16/01):
659 1. Return an error from narrow boards if passed a 16 byte
660 CDB. The wide board can already handle 16 byte CDBs.
662 3.3GJ (4/15/02):
663 1. hacks for lk 2.5 series (D. Gilbert)
665 3.3GJD (10/14/02):
666 1. change select_queue_depths to slave_configure
667 2. make cmd_per_lun be sane again
669 3.3K [2004/06/24]:
670 1. continuing cleanup for lk 2.6 series
671 2. Fix problem in lk 2.6.7-bk2 that broke PCI wide cards
672 3. Fix problem that oopsed ISA cards
674 I. Known Problems/Fix List (XXX)
676 1. Need to add memory mapping workaround. Test the memory mapping.
677 If it doesn't work revert to I/O port access. Can a test be done
678 safely?
679 2. Handle an interrupt not working. Keep an interrupt counter in
680 the interrupt handler. In the timeout function if the interrupt
681 has not occurred then print a message and run in polled mode.
682 3. Allow bus type scanning order to be changed.
683 4. Need to add support for target mode commands, cf. CAM XPT.
685 J. Credits (Chronological Order)
687 Bob Frey <bfrey@turbolinux.com.cn> wrote the AdvanSys SCSI driver
688 and maintained it up to 3.3F. He continues to answer questions
689 and help maintain the driver.
691 Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and
692 basis for the Linux v1.3.X changes which were included in the
693 1.2 release.
695 Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug
696 in advansys_biosparam() which was fixed in the 1.3 release.
698 Erik Ratcliffe <erik@caldera.com> has done testing of the
699 AdvanSys driver in the Caldera releases.
701 Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to
702 AscWaitTixISRDone() which he found necessary to make the
703 driver work with a SCSI-1 disk.
705 Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide
706 support in the 3.1A driver.
708 Doug Gilbert <dgilbert@interlog.com> has made changes and
709 suggestions to improve the driver and done a lot of testing.
711 Ken Mort <ken@mort.net> reported a DEBUG compile bug fixed
712 in 3.2K.
714 Tom Rini <trini@kernel.crashing.org> provided the CONFIG_ISA
715 patch and helped with PowerPC wide and narrow board support.
717 Philip Blundell <philb@gnu.org> provided an
718 advansys_interrupts_enabled patch.
720 Dave Jones <dave@denial.force9.co.uk> reported the compiler
721 warnings generated when CONFIG_PROC_FS was not defined in
722 the 3.2M driver.
724 Jerry Quinn <jlquinn@us.ibm.com> fixed PowerPC support (endian
725 problems) for wide cards.
727 Bryan Henderson <bryanh@giraffe-data.com> helped debug narrow
728 card error handling.
730 Manuel Veloso <veloso@pobox.com> worked hard on PowerPC narrow
731 board support and fixed a bug in AscGetEEPConfig().
733 Arnaldo Carvalho de Melo <acme@conectiva.com.br> made
734 save_flags/restore_flags changes.
736 Andy Kellner <AKellner@connectcom.net> continues the Advansys SCSI
737 driver development for ConnectCom (Version > 3.3F).
739 K. ConnectCom (AdvanSys) Contact Information
741 Mail: ConnectCom Solutions, Inc.
742 1150 Ringwood Court
743 San Jose, CA 95131
744 Operator/Sales: 1-408-383-9400
745 FAX: 1-408-383-9612
746 Tech Support: 1-408-467-2930
747 Tech Support E-Mail: linux@connectcom.net
748 FTP Site: ftp.connectcom.net (login: anonymous)
749 Web Site: http://www.connectcom.net
754 * --- Linux Include Files
757 #include <linux/module.h>
759 #if defined(CONFIG_X86) && !defined(CONFIG_ISA)
760 #define CONFIG_ISA
761 #endif /* CONFIG_X86 && !CONFIG_ISA */
763 #include <linux/string.h>
764 #include <linux/kernel.h>
765 #include <linux/types.h>
766 #include <linux/ioport.h>
767 #include <linux/interrupt.h>
768 #include <linux/delay.h>
769 #include <linux/slab.h>
770 #include <linux/mm.h>
771 #include <linux/proc_fs.h>
772 #include <linux/init.h>
773 #include <linux/blkdev.h>
774 #include <linux/stat.h>
775 #include <linux/spinlock.h>
776 #include <linux/dma-mapping.h>
778 #include <asm/io.h>
779 #include <asm/system.h>
780 #include <asm/dma.h>
782 /* FIXME: (by jejb@steeleye.com) This warning is present for two
783 * reasons:
785 * 1) This driver badly needs converting to the correct driver model
786 * probing API
788 * 2) Although all of the necessary command mapping places have the
789 * appropriate dma_map.. APIs, the driver still processes its internal
790 * queue using bus_to_virt() and virt_to_bus() which are illegal under
791 * the API. The entire queue processing structure will need to be
792 * altered to fix this.
794 #warning this driver is still not properly converted to the DMA API
796 #include <scsi/scsi_cmnd.h>
797 #include <scsi/scsi_device.h>
798 #include <scsi/scsi_tcq.h>
799 #include <scsi/scsi.h>
800 #include <scsi/scsi_host.h>
801 #include "advansys.h"
802 #ifdef CONFIG_PCI
803 #include <linux/pci.h>
804 #endif /* CONFIG_PCI */
808 * --- Driver Options
811 /* Enable driver assertions. */
812 #define ADVANSYS_ASSERT
814 /* Enable driver /proc statistics. */
815 #define ADVANSYS_STATS
817 /* Enable driver tracing. */
818 /* #define ADVANSYS_DEBUG */
822 * --- Debugging Header
825 #ifdef ADVANSYS_DEBUG
826 #define STATIC
827 #else /* ADVANSYS_DEBUG */
828 #define STATIC static
829 #endif /* ADVANSYS_DEBUG */
833 * --- Asc Library Constants and Macros
836 #define ASC_LIB_VERSION_MAJOR 1
837 #define ASC_LIB_VERSION_MINOR 24
838 #define ASC_LIB_SERIAL_NUMBER 123
841 * Portable Data Types
843 * Any instance where a 32-bit long or pointer type is assumed
844 * for precision or HW defined structures, the following define
845 * types must be used. In Linux the char, short, and int types
846 * are all consistent at 8, 16, and 32 bits respectively. Pointers
847 * and long types are 64 bits on Alpha and UltraSPARC.
849 #define ASC_PADDR __u32 /* Physical/Bus address data type. */
850 #define ASC_VADDR __u32 /* Virtual address data type. */
851 #define ASC_DCNT __u32 /* Unsigned Data count type. */
852 #define ASC_SDCNT __s32 /* Signed Data count type. */
855 * These macros are used to convert a virtual address to a
856 * 32-bit value. This currently can be used on Linux Alpha
857 * which uses 64-bit virtual address but a 32-bit bus address.
858 * This is likely to break in the future, but doing this now
859 * will give us time to change the HW and FW to handle 64-bit
860 * addresses.
862 #define ASC_VADDR_TO_U32 virt_to_bus
863 #define ASC_U32_TO_VADDR bus_to_virt
865 typedef unsigned char uchar;
867 #ifndef TRUE
868 #define TRUE (1)
869 #endif
870 #ifndef FALSE
871 #define FALSE (0)
872 #endif
874 #define EOF (-1)
875 #define ERR (-1)
876 #define UW_ERR (uint)(0xFFFF)
877 #define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0)
878 #define AscPCIConfigVendorIDRegister 0x0000
879 #define AscPCIConfigDeviceIDRegister 0x0002
880 #define AscPCIConfigCommandRegister 0x0004
881 #define AscPCIConfigStatusRegister 0x0006
882 #define AscPCIConfigRevisionIDRegister 0x0008
883 #define AscPCIConfigCacheSize 0x000C
884 #define AscPCIConfigLatencyTimer 0x000D
885 #define AscPCIIOBaseRegister 0x0010
886 #define AscPCICmdRegBits_IOMemBusMaster 0x0007
887 #define ASC_PCI_ID2BUS(id) ((id) & 0xFF)
888 #define ASC_PCI_ID2DEV(id) (((id) >> 11) & 0x1F)
889 #define ASC_PCI_ID2FUNC(id) (((id) >> 8) & 0x7)
890 #define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF))
891 #define ASC_PCI_REVISION_3150 0x02
892 #define ASC_PCI_REVISION_3050 0x03
894 #define ASC_DVCLIB_CALL_DONE (1)
895 #define ASC_DVCLIB_CALL_FAILED (0)
896 #define ASC_DVCLIB_CALL_ERROR (-1)
898 #define PCI_VENDOR_ID_ASP 0x10cd
899 #define PCI_DEVICE_ID_ASP_1200A 0x1100
900 #define PCI_DEVICE_ID_ASP_ABP940 0x1200
901 #define PCI_DEVICE_ID_ASP_ABP940U 0x1300
902 #define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
903 #define PCI_DEVICE_ID_38C0800_REV1 0x2500
904 #define PCI_DEVICE_ID_38C1600_REV1 0x2700
907 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
908 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
909 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
910 * SRB structure.
912 #define CC_VERY_LONG_SG_LIST 0
913 #define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
915 #define PortAddr unsigned short /* port address size */
916 #define inp(port) inb(port)
917 #define outp(port, byte) outb((byte), (port))
919 #define inpw(port) inw(port)
920 #define outpw(port, word) outw((word), (port))
922 #define ASC_MAX_SG_QUEUE 7
923 #define ASC_MAX_SG_LIST 255
925 #define ASC_CS_TYPE unsigned short
927 #define ASC_IS_ISA (0x0001)
928 #define ASC_IS_ISAPNP (0x0081)
929 #define ASC_IS_EISA (0x0002)
930 #define ASC_IS_PCI (0x0004)
931 #define ASC_IS_PCI_ULTRA (0x0104)
932 #define ASC_IS_PCMCIA (0x0008)
933 #define ASC_IS_MCA (0x0020)
934 #define ASC_IS_VL (0x0040)
935 #define ASC_ISA_PNP_PORT_ADDR (0x279)
936 #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
937 #define ASC_IS_WIDESCSI_16 (0x0100)
938 #define ASC_IS_WIDESCSI_32 (0x0200)
939 #define ASC_IS_BIG_ENDIAN (0x8000)
940 #define ASC_CHIP_MIN_VER_VL (0x01)
941 #define ASC_CHIP_MAX_VER_VL (0x07)
942 #define ASC_CHIP_MIN_VER_PCI (0x09)
943 #define ASC_CHIP_MAX_VER_PCI (0x0F)
944 #define ASC_CHIP_VER_PCI_BIT (0x08)
945 #define ASC_CHIP_MIN_VER_ISA (0x11)
946 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
947 #define ASC_CHIP_MAX_VER_ISA (0x27)
948 #define ASC_CHIP_VER_ISA_BIT (0x30)
949 #define ASC_CHIP_VER_ISAPNP_BIT (0x20)
950 #define ASC_CHIP_VER_ASYN_BUG (0x21)
951 #define ASC_CHIP_VER_PCI 0x08
952 #define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
953 #define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
954 #define ASC_CHIP_MIN_VER_EISA (0x41)
955 #define ASC_CHIP_MAX_VER_EISA (0x47)
956 #define ASC_CHIP_VER_EISA_BIT (0x40)
957 #define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
958 #define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER 0x21
959 #define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER 0x0A
960 #define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL)
961 #define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
962 #define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL)
963 #define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
964 #define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL)
965 #define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
966 #define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL)
967 #define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL)
969 #define ASC_SCSI_ID_BITS 3
970 #define ASC_SCSI_TIX_TYPE uchar
971 #define ASC_ALL_DEVICE_BIT_SET 0xFF
972 #define ASC_SCSI_BIT_ID_TYPE uchar
973 #define ASC_MAX_TID 7
974 #define ASC_MAX_LUN 7
975 #define ASC_SCSI_WIDTH_BIT_SET 0xFF
976 #define ASC_MAX_SENSE_LEN 32
977 #define ASC_MIN_SENSE_LEN 14
978 #define ASC_MAX_CDB_LEN 12
979 #define ASC_SCSI_RESET_HOLD_TIME_US 60
981 #define ADV_INQ_CLOCKING_ST_ONLY 0x0
982 #define ADV_INQ_CLOCKING_DT_ONLY 0x1
983 #define ADV_INQ_CLOCKING_ST_AND_DT 0x3
986 * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
987 * and CmdDt (Command Support Data) field bit definitions.
989 #define ADV_INQ_RTN_VPD_AND_CMDDT 0x3
990 #define ADV_INQ_RTN_CMDDT_FOR_OP_CODE 0x2
991 #define ADV_INQ_RTN_VPD_FOR_PG_CODE 0x1
992 #define ADV_INQ_RTN_STD_INQUIRY_DATA 0x0
994 #define ASC_SCSIDIR_NOCHK 0x00
995 #define ASC_SCSIDIR_T2H 0x08
996 #define ASC_SCSIDIR_H2T 0x10
997 #define ASC_SCSIDIR_NODATA 0x18
998 #define SCSI_ASC_NOMEDIA 0x3A
999 #define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4))
1000 #define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F))
1001 #define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13))
1002 #define PUT_CDB1(x) ((uchar)((uint)(x) >> 8))
1003 #define MS_CMD_DONE 0x00
1004 #define MS_EXTEND 0x01
1005 #define MS_SDTR_LEN 0x03
1006 #define MS_SDTR_CODE 0x01
1007 #define MS_WDTR_LEN 0x02
1008 #define MS_WDTR_CODE 0x03
1009 #define MS_MDP_LEN 0x05
1010 #define MS_MDP_CODE 0x00
1013 * Inquiry data structure and bitfield macros
1015 * Only quantities of more than 1 bit are shifted, since the others are
1016 * just tested for true or false. C bitfields aren't portable between big
1017 * and little-endian platforms so they are not used.
1020 #define ASC_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f)
1021 #define ASC_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5)
1022 #define ASC_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f)
1023 #define ASC_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80)
1024 #define ASC_INQ_ANSI_VER(inq) ((inq)->ver & 0x07)
1025 #define ASC_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3)
1026 #define ASC_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6)
1027 #define ASC_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f)
1028 #define ASC_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40)
1029 #define ASC_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80)
1030 #define ASC_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01)
1031 #define ASC_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02)
1032 #define ASC_INQ_LINK_CMD(inq) ((inq)->flags & 0x08)
1033 #define ASC_INQ_SYNC(inq) ((inq)->flags & 0x10)
1034 #define ASC_INQ_WIDE16(inq) ((inq)->flags & 0x20)
1035 #define ASC_INQ_WIDE32(inq) ((inq)->flags & 0x40)
1036 #define ASC_INQ_REL_ADDR(inq) ((inq)->flags & 0x80)
1037 #define ASC_INQ_INFO_UNIT(inq) ((inq)->info & 0x01)
1038 #define ASC_INQ_QUICK_ARB(inq) ((inq)->info & 0x02)
1039 #define ASC_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2)
1041 typedef struct {
1042 uchar periph;
1043 uchar devtype;
1044 uchar ver;
1045 uchar byte3;
1046 uchar add_len;
1047 uchar res1;
1048 uchar res2;
1049 uchar flags;
1050 uchar vendor_id[8];
1051 uchar product_id[16];
1052 uchar product_rev_level[4];
1053 } ASC_SCSI_INQUIRY;
1055 #define ASC_SG_LIST_PER_Q 7
1056 #define QS_FREE 0x00
1057 #define QS_READY 0x01
1058 #define QS_DISC1 0x02
1059 #define QS_DISC2 0x04
1060 #define QS_BUSY 0x08
1061 #define QS_ABORTED 0x40
1062 #define QS_DONE 0x80
1063 #define QC_NO_CALLBACK 0x01
1064 #define QC_SG_SWAP_QUEUE 0x02
1065 #define QC_SG_HEAD 0x04
1066 #define QC_DATA_IN 0x08
1067 #define QC_DATA_OUT 0x10
1068 #define QC_URGENT 0x20
1069 #define QC_MSG_OUT 0x40
1070 #define QC_REQ_SENSE 0x80
1071 #define QCSG_SG_XFER_LIST 0x02
1072 #define QCSG_SG_XFER_MORE 0x04
1073 #define QCSG_SG_XFER_END 0x08
1074 #define QD_IN_PROGRESS 0x00
1075 #define QD_NO_ERROR 0x01
1076 #define QD_ABORTED_BY_HOST 0x02
1077 #define QD_WITH_ERROR 0x04
1078 #define QD_INVALID_REQUEST 0x80
1079 #define QD_INVALID_HOST_NUM 0x81
1080 #define QD_INVALID_DEVICE 0x82
1081 #define QD_ERR_INTERNAL 0xFF
1082 #define QHSTA_NO_ERROR 0x00
1083 #define QHSTA_M_SEL_TIMEOUT 0x11
1084 #define QHSTA_M_DATA_OVER_RUN 0x12
1085 #define QHSTA_M_DATA_UNDER_RUN 0x12
1086 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
1087 #define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
1088 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1089 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
1090 #define QHSTA_D_HOST_ABORT_FAILED 0x23
1091 #define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
1092 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1093 #define QHSTA_D_ASPI_NO_BUF_POOL 0x26
1094 #define QHSTA_M_WTM_TIMEOUT 0x41
1095 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
1096 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
1097 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1098 #define QHSTA_M_TARGET_STATUS_BUSY 0x45
1099 #define QHSTA_M_BAD_TAG_CODE 0x46
1100 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
1101 #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1102 #define QHSTA_D_LRAM_CMP_ERROR 0x81
1103 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1104 #define ASC_FLAG_SCSIQ_REQ 0x01
1105 #define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
1106 #define ASC_FLAG_BIOS_ASYNC_IO 0x04
1107 #define ASC_FLAG_SRB_LINEAR_ADDR 0x08
1108 #define ASC_FLAG_WIN16 0x10
1109 #define ASC_FLAG_WIN32 0x20
1110 #define ASC_FLAG_ISA_OVER_16MB 0x40
1111 #define ASC_FLAG_DOS_VM_CALLBACK 0x80
1112 #define ASC_TAG_FLAG_EXTRA_BYTES 0x10
1113 #define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
1114 #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
1115 #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1116 #define ASC_SCSIQ_CPY_BEG 4
1117 #define ASC_SCSIQ_SGHD_CPY_BEG 2
1118 #define ASC_SCSIQ_B_FWD 0
1119 #define ASC_SCSIQ_B_BWD 1
1120 #define ASC_SCSIQ_B_STATUS 2
1121 #define ASC_SCSIQ_B_QNO 3
1122 #define ASC_SCSIQ_B_CNTL 4
1123 #define ASC_SCSIQ_B_SG_QUEUE_CNT 5
1124 #define ASC_SCSIQ_D_DATA_ADDR 8
1125 #define ASC_SCSIQ_D_DATA_CNT 12
1126 #define ASC_SCSIQ_B_SENSE_LEN 20
1127 #define ASC_SCSIQ_DONE_INFO_BEG 22
1128 #define ASC_SCSIQ_D_SRBPTR 22
1129 #define ASC_SCSIQ_B_TARGET_IX 26
1130 #define ASC_SCSIQ_B_CDB_LEN 28
1131 #define ASC_SCSIQ_B_TAG_CODE 29
1132 #define ASC_SCSIQ_W_VM_ID 30
1133 #define ASC_SCSIQ_DONE_STATUS 32
1134 #define ASC_SCSIQ_HOST_STATUS 33
1135 #define ASC_SCSIQ_SCSI_STATUS 34
1136 #define ASC_SCSIQ_CDB_BEG 36
1137 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1138 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
1139 #define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
1140 #define ASC_SCSIQ_B_SG_WK_QP 49
1141 #define ASC_SCSIQ_B_SG_WK_IX 50
1142 #define ASC_SCSIQ_W_ALT_DC1 52
1143 #define ASC_SCSIQ_B_LIST_CNT 6
1144 #define ASC_SCSIQ_B_CUR_LIST_CNT 7
1145 #define ASC_SGQ_B_SG_CNTL 4
1146 #define ASC_SGQ_B_SG_HEAD_QP 5
1147 #define ASC_SGQ_B_SG_LIST_CNT 6
1148 #define ASC_SGQ_B_SG_CUR_LIST_CNT 7
1149 #define ASC_SGQ_LIST_BEG 8
1150 #define ASC_DEF_SCSI1_QNG 4
1151 #define ASC_MAX_SCSI1_QNG 4
1152 #define ASC_DEF_SCSI2_QNG 16
1153 #define ASC_MAX_SCSI2_QNG 32
1154 #define ASC_TAG_CODE_MASK 0x23
1155 #define ASC_STOP_REQ_RISC_STOP 0x01
1156 #define ASC_STOP_ACK_RISC_STOP 0x03
1157 #define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
1158 #define ASC_STOP_CLEAN_UP_DISC_Q 0x20
1159 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1160 #define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1161 #define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1162 #define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
1163 #define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
1164 #define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
1165 #define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1166 #define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
1168 typedef struct asc_scsiq_1 {
1169 uchar status;
1170 uchar q_no;
1171 uchar cntl;
1172 uchar sg_queue_cnt;
1173 uchar target_id;
1174 uchar target_lun;
1175 ASC_PADDR data_addr;
1176 ASC_DCNT data_cnt;
1177 ASC_PADDR sense_addr;
1178 uchar sense_len;
1179 uchar extra_bytes;
1180 } ASC_SCSIQ_1;
1182 typedef struct asc_scsiq_2 {
1183 ASC_VADDR srb_ptr;
1184 uchar target_ix;
1185 uchar flag;
1186 uchar cdb_len;
1187 uchar tag_code;
1188 ushort vm_id;
1189 } ASC_SCSIQ_2;
1191 typedef struct asc_scsiq_3 {
1192 uchar done_stat;
1193 uchar host_stat;
1194 uchar scsi_stat;
1195 uchar scsi_msg;
1196 } ASC_SCSIQ_3;
1198 typedef struct asc_scsiq_4 {
1199 uchar cdb[ASC_MAX_CDB_LEN];
1200 uchar y_first_sg_list_qp;
1201 uchar y_working_sg_qp;
1202 uchar y_working_sg_ix;
1203 uchar y_res;
1204 ushort x_req_count;
1205 ushort x_reconnect_rtn;
1206 ASC_PADDR x_saved_data_addr;
1207 ASC_DCNT x_saved_data_cnt;
1208 } ASC_SCSIQ_4;
1210 typedef struct asc_q_done_info {
1211 ASC_SCSIQ_2 d2;
1212 ASC_SCSIQ_3 d3;
1213 uchar q_status;
1214 uchar q_no;
1215 uchar cntl;
1216 uchar sense_len;
1217 uchar extra_bytes;
1218 uchar res;
1219 ASC_DCNT remain_bytes;
1220 } ASC_QDONE_INFO;
1222 typedef struct asc_sg_list {
1223 ASC_PADDR addr;
1224 ASC_DCNT bytes;
1225 } ASC_SG_LIST;
1227 typedef struct asc_sg_head {
1228 ushort entry_cnt;
1229 ushort queue_cnt;
1230 ushort entry_to_copy;
1231 ushort res;
1232 ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1233 } ASC_SG_HEAD;
1235 #define ASC_MIN_SG_LIST 2
1237 typedef struct asc_min_sg_head {
1238 ushort entry_cnt;
1239 ushort queue_cnt;
1240 ushort entry_to_copy;
1241 ushort res;
1242 ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
1243 } ASC_MIN_SG_HEAD;
1245 #define QCX_SORT (0x0001)
1246 #define QCX_COALEASE (0x0002)
1248 typedef struct asc_scsi_q {
1249 ASC_SCSIQ_1 q1;
1250 ASC_SCSIQ_2 q2;
1251 uchar *cdbptr;
1252 ASC_SG_HEAD *sg_head;
1253 ushort remain_sg_entry_cnt;
1254 ushort next_sg_index;
1255 } ASC_SCSI_Q;
1257 typedef struct asc_scsi_req_q {
1258 ASC_SCSIQ_1 r1;
1259 ASC_SCSIQ_2 r2;
1260 uchar *cdbptr;
1261 ASC_SG_HEAD *sg_head;
1262 uchar *sense_ptr;
1263 ASC_SCSIQ_3 r3;
1264 uchar cdb[ASC_MAX_CDB_LEN];
1265 uchar sense[ASC_MIN_SENSE_LEN];
1266 } ASC_SCSI_REQ_Q;
1268 typedef struct asc_scsi_bios_req_q {
1269 ASC_SCSIQ_1 r1;
1270 ASC_SCSIQ_2 r2;
1271 uchar *cdbptr;
1272 ASC_SG_HEAD *sg_head;
1273 uchar *sense_ptr;
1274 ASC_SCSIQ_3 r3;
1275 uchar cdb[ASC_MAX_CDB_LEN];
1276 uchar sense[ASC_MIN_SENSE_LEN];
1277 } ASC_SCSI_BIOS_REQ_Q;
1279 typedef struct asc_risc_q {
1280 uchar fwd;
1281 uchar bwd;
1282 ASC_SCSIQ_1 i1;
1283 ASC_SCSIQ_2 i2;
1284 ASC_SCSIQ_3 i3;
1285 ASC_SCSIQ_4 i4;
1286 } ASC_RISC_Q;
1288 typedef struct asc_sg_list_q {
1289 uchar seq_no;
1290 uchar q_no;
1291 uchar cntl;
1292 uchar sg_head_qp;
1293 uchar sg_list_cnt;
1294 uchar sg_cur_list_cnt;
1295 } ASC_SG_LIST_Q;
1297 typedef struct asc_risc_sg_list_q {
1298 uchar fwd;
1299 uchar bwd;
1300 ASC_SG_LIST_Q sg;
1301 ASC_SG_LIST sg_list[7];
1302 } ASC_RISC_SG_LIST_Q;
1304 #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL
1305 #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024
1306 #define ASCQ_ERR_NO_ERROR 0
1307 #define ASCQ_ERR_IO_NOT_FOUND 1
1308 #define ASCQ_ERR_LOCAL_MEM 2
1309 #define ASCQ_ERR_CHKSUM 3
1310 #define ASCQ_ERR_START_CHIP 4
1311 #define ASCQ_ERR_INT_TARGET_ID 5
1312 #define ASCQ_ERR_INT_LOCAL_MEM 6
1313 #define ASCQ_ERR_HALT_RISC 7
1314 #define ASCQ_ERR_GET_ASPI_ENTRY 8
1315 #define ASCQ_ERR_CLOSE_ASPI 9
1316 #define ASCQ_ERR_HOST_INQUIRY 0x0A
1317 #define ASCQ_ERR_SAVED_SRB_BAD 0x0B
1318 #define ASCQ_ERR_QCNTL_SG_LIST 0x0C
1319 #define ASCQ_ERR_Q_STATUS 0x0D
1320 #define ASCQ_ERR_WR_SCSIQ 0x0E
1321 #define ASCQ_ERR_PC_ADDR 0x0F
1322 #define ASCQ_ERR_SYN_OFFSET 0x10
1323 #define ASCQ_ERR_SYN_XFER_TIME 0x11
1324 #define ASCQ_ERR_LOCK_DMA 0x12
1325 #define ASCQ_ERR_UNLOCK_DMA 0x13
1326 #define ASCQ_ERR_VDS_CHK_INSTALL 0x14
1327 #define ASCQ_ERR_MICRO_CODE_HALT 0x15
1328 #define ASCQ_ERR_SET_LRAM_ADDR 0x16
1329 #define ASCQ_ERR_CUR_QNG 0x17
1330 #define ASCQ_ERR_SG_Q_LINKS 0x18
1331 #define ASCQ_ERR_SCSIQ_PTR 0x19
1332 #define ASCQ_ERR_ISR_RE_ENTRY 0x1A
1333 #define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
1334 #define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
1335 #define ASCQ_ERR_SG_LIST_ODD_ADDRESS 0x1D
1336 #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1337 #define ASCQ_ERR_SCSIQ_NULL_PTR 0x1F
1338 #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR 0x20
1339 #define ASCQ_ERR_GET_NUM_OF_FREE_Q 0x21
1340 #define ASCQ_ERR_SEND_SCSI_Q 0x22
1341 #define ASCQ_ERR_HOST_REQ_RISC_HALT 0x23
1342 #define ASCQ_ERR_RESET_SDTR 0x24
1345 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
1347 #define ASC_WARN_NO_ERROR 0x0000
1348 #define ASC_WARN_IO_PORT_ROTATE 0x0001
1349 #define ASC_WARN_EEPROM_CHKSUM 0x0002
1350 #define ASC_WARN_IRQ_MODIFIED 0x0004
1351 #define ASC_WARN_AUTO_CONFIG 0x0008
1352 #define ASC_WARN_CMD_QNG_CONFLICT 0x0010
1353 #define ASC_WARN_EEPROM_RECOVER 0x0020
1354 #define ASC_WARN_CFG_MSW_RECOVER 0x0040
1355 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1358 * Error code values are set in ASC_DVC_VAR 'err_code'.
1360 #define ASC_IERR_WRITE_EEPROM 0x0001
1361 #define ASC_IERR_MCODE_CHKSUM 0x0002
1362 #define ASC_IERR_SET_PC_ADDR 0x0004
1363 #define ASC_IERR_START_STOP_CHIP 0x0008
1364 #define ASC_IERR_IRQ_NO 0x0010
1365 #define ASC_IERR_SET_IRQ_NO 0x0020
1366 #define ASC_IERR_CHIP_VERSION 0x0040
1367 #define ASC_IERR_SET_SCSI_ID 0x0080
1368 #define ASC_IERR_GET_PHY_ADDR 0x0100
1369 #define ASC_IERR_BAD_SIGNATURE 0x0200
1370 #define ASC_IERR_NO_BUS_TYPE 0x0400
1371 #define ASC_IERR_SCAM 0x0800
1372 #define ASC_IERR_SET_SDTR 0x1000
1373 #define ASC_IERR_RW_LRAM 0x8000
1375 #define ASC_DEF_IRQ_NO 10
1376 #define ASC_MAX_IRQ_NO 15
1377 #define ASC_MIN_IRQ_NO 10
1378 #define ASC_MIN_REMAIN_Q (0x02)
1379 #define ASC_DEF_MAX_TOTAL_QNG (0xF0)
1380 #define ASC_MIN_TAG_Q_PER_DVC (0x04)
1381 #define ASC_DEF_TAG_Q_PER_DVC (0x04)
1382 #define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q
1383 #define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1384 #define ASC_MAX_TOTAL_QNG 240
1385 #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1386 #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
1387 #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
1388 #define ASC_MAX_INRAM_TAG_QNG 16
1389 #define ASC_IOADR_TABLE_MAX_IX 11
1390 #define ASC_IOADR_GAP 0x10
1391 #define ASC_SEARCH_IOP_GAP 0x10
1392 #define ASC_MIN_IOP_ADDR (PortAddr)0x0100
1393 #define ASC_MAX_IOP_ADDR (PortAddr)0x3F0
1394 #define ASC_IOADR_1 (PortAddr)0x0110
1395 #define ASC_IOADR_2 (PortAddr)0x0130
1396 #define ASC_IOADR_3 (PortAddr)0x0150
1397 #define ASC_IOADR_4 (PortAddr)0x0190
1398 #define ASC_IOADR_5 (PortAddr)0x0210
1399 #define ASC_IOADR_6 (PortAddr)0x0230
1400 #define ASC_IOADR_7 (PortAddr)0x0250
1401 #define ASC_IOADR_8 (PortAddr)0x0330
1402 #define ASC_IOADR_DEF ASC_IOADR_8
1403 #define ASC_LIB_SCSIQ_WK_SP 256
1404 #define ASC_MAX_SYN_XFER_NO 16
1405 #define ASC_SYN_MAX_OFFSET 0x0F
1406 #define ASC_DEF_SDTR_OFFSET 0x0F
1407 #define ASC_DEF_SDTR_INDEX 0x00
1408 #define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
1409 #define SYN_XFER_NS_0 25
1410 #define SYN_XFER_NS_1 30
1411 #define SYN_XFER_NS_2 35
1412 #define SYN_XFER_NS_3 40
1413 #define SYN_XFER_NS_4 50
1414 #define SYN_XFER_NS_5 60
1415 #define SYN_XFER_NS_6 70
1416 #define SYN_XFER_NS_7 85
1417 #define SYN_ULTRA_XFER_NS_0 12
1418 #define SYN_ULTRA_XFER_NS_1 19
1419 #define SYN_ULTRA_XFER_NS_2 25
1420 #define SYN_ULTRA_XFER_NS_3 32
1421 #define SYN_ULTRA_XFER_NS_4 38
1422 #define SYN_ULTRA_XFER_NS_5 44
1423 #define SYN_ULTRA_XFER_NS_6 50
1424 #define SYN_ULTRA_XFER_NS_7 57
1425 #define SYN_ULTRA_XFER_NS_8 63
1426 #define SYN_ULTRA_XFER_NS_9 69
1427 #define SYN_ULTRA_XFER_NS_10 75
1428 #define SYN_ULTRA_XFER_NS_11 82
1429 #define SYN_ULTRA_XFER_NS_12 88
1430 #define SYN_ULTRA_XFER_NS_13 94
1431 #define SYN_ULTRA_XFER_NS_14 100
1432 #define SYN_ULTRA_XFER_NS_15 107
1434 typedef struct ext_msg {
1435 uchar msg_type;
1436 uchar msg_len;
1437 uchar msg_req;
1438 union {
1439 struct {
1440 uchar sdtr_xfer_period;
1441 uchar sdtr_req_ack_offset;
1442 } sdtr;
1443 struct {
1444 uchar wdtr_width;
1445 } wdtr;
1446 struct {
1447 uchar mdp_b3;
1448 uchar mdp_b2;
1449 uchar mdp_b1;
1450 uchar mdp_b0;
1451 } mdp;
1452 } u_ext_msg;
1453 uchar res;
1454 } EXT_MSG;
1456 #define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
1457 #define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
1458 #define wdtr_width u_ext_msg.wdtr.wdtr_width
1459 #define mdp_b3 u_ext_msg.mdp_b3
1460 #define mdp_b2 u_ext_msg.mdp_b2
1461 #define mdp_b1 u_ext_msg.mdp_b1
1462 #define mdp_b0 u_ext_msg.mdp_b0
1464 typedef struct asc_dvc_cfg {
1465 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1466 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1467 ASC_SCSI_BIT_ID_TYPE disc_enable;
1468 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1469 uchar chip_scsi_id;
1470 uchar isa_dma_speed;
1471 uchar isa_dma_channel;
1472 uchar chip_version;
1473 ushort lib_serial_no;
1474 ushort lib_version;
1475 ushort mcode_date;
1476 ushort mcode_version;
1477 uchar max_tag_qng[ASC_MAX_TID + 1];
1478 uchar *overrun_buf;
1479 uchar sdtr_period_offset[ASC_MAX_TID + 1];
1480 ushort pci_slot_info;
1481 uchar adapter_info[6];
1482 struct device *dev;
1483 } ASC_DVC_CFG;
1485 #define ASC_DEF_DVC_CNTL 0xFFFF
1486 #define ASC_DEF_CHIP_SCSI_ID 7
1487 #define ASC_DEF_ISA_DMA_SPEED 4
1488 #define ASC_INIT_STATE_NULL 0x0000
1489 #define ASC_INIT_STATE_BEG_GET_CFG 0x0001
1490 #define ASC_INIT_STATE_END_GET_CFG 0x0002
1491 #define ASC_INIT_STATE_BEG_SET_CFG 0x0004
1492 #define ASC_INIT_STATE_END_SET_CFG 0x0008
1493 #define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
1494 #define ASC_INIT_STATE_END_LOAD_MC 0x0020
1495 #define ASC_INIT_STATE_BEG_INQUIRY 0x0040
1496 #define ASC_INIT_STATE_END_INQUIRY 0x0080
1497 #define ASC_INIT_RESET_SCSI_DONE 0x0100
1498 #define ASC_INIT_STATE_WITHOUT_EEP 0x8000
1499 #define ASC_BUG_FIX_IF_NOT_DWB 0x0001
1500 #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
1501 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1502 #define ASC_MIN_TAGGED_CMD 7
1503 #define ASC_MAX_SCSI_RESET_WAIT 30
1505 struct asc_dvc_var; /* Forward Declaration. */
1507 typedef void (* ASC_ISR_CALLBACK)(struct asc_dvc_var *, ASC_QDONE_INFO *);
1508 typedef int (* ASC_EXE_CALLBACK)(struct asc_dvc_var *, ASC_SCSI_Q *);
1510 typedef struct asc_dvc_var {
1511 PortAddr iop_base;
1512 ushort err_code;
1513 ushort dvc_cntl;
1514 ushort bug_fix_cntl;
1515 ushort bus_type;
1516 ASC_ISR_CALLBACK isr_callback;
1517 ASC_EXE_CALLBACK exe_callback;
1518 ASC_SCSI_BIT_ID_TYPE init_sdtr;
1519 ASC_SCSI_BIT_ID_TYPE sdtr_done;
1520 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1521 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1522 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1523 ASC_SCSI_BIT_ID_TYPE start_motor;
1524 uchar scsi_reset_wait;
1525 uchar chip_no;
1526 char is_in_int;
1527 uchar max_total_qng;
1528 uchar cur_total_qng;
1529 uchar in_critical_cnt;
1530 uchar irq_no;
1531 uchar last_q_shortage;
1532 ushort init_state;
1533 uchar cur_dvc_qng[ASC_MAX_TID + 1];
1534 uchar max_dvc_qng[ASC_MAX_TID + 1];
1535 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
1536 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
1537 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1538 ASC_DVC_CFG *cfg;
1539 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1540 char redo_scam;
1541 ushort res2;
1542 uchar dos_int13_table[ASC_MAX_TID + 1];
1543 ASC_DCNT max_dma_count;
1544 ASC_SCSI_BIT_ID_TYPE no_scam;
1545 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1546 uchar max_sdtr_index;
1547 uchar host_init_sdtr_index;
1548 struct asc_board *drv_ptr;
1549 ASC_DCNT uc_break;
1550 } ASC_DVC_VAR;
1552 typedef struct asc_dvc_inq_info {
1553 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1554 } ASC_DVC_INQ_INFO;
1556 typedef struct asc_cap_info {
1557 ASC_DCNT lba;
1558 ASC_DCNT blk_size;
1559 } ASC_CAP_INFO;
1561 typedef struct asc_cap_info_array {
1562 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1563 } ASC_CAP_INFO_ARRAY;
1565 #define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
1566 #define ASC_MCNTL_NULL_TARGET (ushort)0x0002
1567 #define ASC_CNTL_INITIATOR (ushort)0x0001
1568 #define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
1569 #define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
1570 #define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
1571 #define ASC_CNTL_NO_SCAM (ushort)0x0010
1572 #define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
1573 #define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
1574 #define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
1575 #define ASC_CNTL_RESET_SCSI (ushort)0x0200
1576 #define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
1577 #define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
1578 #define ASC_CNTL_SCSI_PARITY (ushort)0x1000
1579 #define ASC_CNTL_BURST_MODE (ushort)0x2000
1580 #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1581 #define ASC_EEP_DVC_CFG_BEG_VL 2
1582 #define ASC_EEP_MAX_DVC_ADDR_VL 15
1583 #define ASC_EEP_DVC_CFG_BEG 32
1584 #define ASC_EEP_MAX_DVC_ADDR 45
1585 #define ASC_EEP_DEFINED_WORDS 10
1586 #define ASC_EEP_MAX_ADDR 63
1587 #define ASC_EEP_RES_WORDS 0
1588 #define ASC_EEP_MAX_RETRY 20
1589 #define ASC_MAX_INIT_BUSY_RETRY 8
1590 #define ASC_EEP_ISA_PNP_WSIZE 16
1593 * These macros keep the chip SCSI id and ISA DMA speed
1594 * bitfields in board order. C bitfields aren't portable
1595 * between big and little-endian platforms so they are
1596 * not used.
1599 #define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
1600 #define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
1601 #define ASC_EEP_SET_CHIP_ID(cfg, sid) \
1602 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
1603 #define ASC_EEP_SET_DMA_SPD(cfg, spd) \
1604 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
1606 typedef struct asceep_config {
1607 ushort cfg_lsw;
1608 ushort cfg_msw;
1609 uchar init_sdtr;
1610 uchar disc_enable;
1611 uchar use_cmd_qng;
1612 uchar start_motor;
1613 uchar max_total_qng;
1614 uchar max_tag_qng;
1615 uchar bios_scan;
1616 uchar power_up_wait;
1617 uchar no_scam;
1618 uchar id_speed; /* low order 4 bits is chip scsi id */
1619 /* high order 4 bits is isa dma speed */
1620 uchar dos_int13_table[ASC_MAX_TID + 1];
1621 uchar adapter_info[6];
1622 ushort cntl;
1623 ushort chksum;
1624 } ASCEEP_CONFIG;
1626 #define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800
1627 #define ASC_PCI_CFG_LSW_BURST_MODE 0x0080
1628 #define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020
1630 #define ASC_EEP_CMD_READ 0x80
1631 #define ASC_EEP_CMD_WRITE 0x40
1632 #define ASC_EEP_CMD_WRITE_ABLE 0x30
1633 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
1634 #define ASC_OVERRUN_BSIZE 0x00000048UL
1635 #define ASC_CTRL_BREAK_ONCE 0x0001
1636 #define ASC_CTRL_BREAK_STAY_IDLE 0x0002
1637 #define ASCV_MSGOUT_BEG 0x0000
1638 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1639 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1640 #define ASCV_BREAK_SAVED_CODE (ushort)0x0006
1641 #define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
1642 #define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
1643 #define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
1644 #define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
1645 #define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
1646 #define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
1647 #define ASCV_BREAK_ADDR (ushort)0x0028
1648 #define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
1649 #define ASCV_BREAK_CONTROL (ushort)0x002C
1650 #define ASCV_BREAK_HIT_COUNT (ushort)0x002E
1652 #define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
1653 #define ASCV_MCODE_CHKSUM_W (ushort)0x0032
1654 #define ASCV_MCODE_SIZE_W (ushort)0x0034
1655 #define ASCV_STOP_CODE_B (ushort)0x0036
1656 #define ASCV_DVC_ERR_CODE_B (ushort)0x0037
1657 #define ASCV_OVERRUN_PADDR_D (ushort)0x0038
1658 #define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
1659 #define ASCV_HALTCODE_W (ushort)0x0040
1660 #define ASCV_CHKSUM_W (ushort)0x0042
1661 #define ASCV_MC_DATE_W (ushort)0x0044
1662 #define ASCV_MC_VER_W (ushort)0x0046
1663 #define ASCV_NEXTRDY_B (ushort)0x0048
1664 #define ASCV_DONENEXT_B (ushort)0x0049
1665 #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1666 #define ASCV_SCSIBUSY_B (ushort)0x004B
1667 #define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
1668 #define ASCV_CURCDB_B (ushort)0x004D
1669 #define ASCV_RCLUN_B (ushort)0x004E
1670 #define ASCV_BUSY_QHEAD_B (ushort)0x004F
1671 #define ASCV_DISC1_QHEAD_B (ushort)0x0050
1672 #define ASCV_DISC_ENABLE_B (ushort)0x0052
1673 #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1674 #define ASCV_HOSTSCSI_ID_B (ushort)0x0055
1675 #define ASCV_MCODE_CNTL_B (ushort)0x0056
1676 #define ASCV_NULL_TARGET_B (ushort)0x0057
1677 #define ASCV_FREE_Q_HEAD_W (ushort)0x0058
1678 #define ASCV_DONE_Q_TAIL_W (ushort)0x005A
1679 #define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
1680 #define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
1681 #define ASCV_HOST_FLAG_B (ushort)0x005D
1682 #define ASCV_TOTAL_READY_Q_B (ushort)0x0064
1683 #define ASCV_VER_SERIAL_B (ushort)0x0065
1684 #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1685 #define ASCV_WTM_FLAG_B (ushort)0x0068
1686 #define ASCV_RISC_FLAG_B (ushort)0x006A
1687 #define ASCV_REQ_SG_LIST_QP (ushort)0x006B
1688 #define ASC_HOST_FLAG_IN_ISR 0x01
1689 #define ASC_HOST_FLAG_ACK_INT 0x02
1690 #define ASC_RISC_FLAG_GEN_INT 0x01
1691 #define ASC_RISC_FLAG_REQ_SG_LIST 0x02
1692 #define IOP_CTRL (0x0F)
1693 #define IOP_STATUS (0x0E)
1694 #define IOP_INT_ACK IOP_STATUS
1695 #define IOP_REG_IFC (0x0D)
1696 #define IOP_SYN_OFFSET (0x0B)
1697 #define IOP_EXTRA_CONTROL (0x0D)
1698 #define IOP_REG_PC (0x0C)
1699 #define IOP_RAM_ADDR (0x0A)
1700 #define IOP_RAM_DATA (0x08)
1701 #define IOP_EEP_DATA (0x06)
1702 #define IOP_EEP_CMD (0x07)
1703 #define IOP_VERSION (0x03)
1704 #define IOP_CONFIG_HIGH (0x04)
1705 #define IOP_CONFIG_LOW (0x02)
1706 #define IOP_SIG_BYTE (0x01)
1707 #define IOP_SIG_WORD (0x00)
1708 #define IOP_REG_DC1 (0x0E)
1709 #define IOP_REG_DC0 (0x0C)
1710 #define IOP_REG_SB (0x0B)
1711 #define IOP_REG_DA1 (0x0A)
1712 #define IOP_REG_DA0 (0x08)
1713 #define IOP_REG_SC (0x09)
1714 #define IOP_DMA_SPEED (0x07)
1715 #define IOP_REG_FLAG (0x07)
1716 #define IOP_FIFO_H (0x06)
1717 #define IOP_FIFO_L (0x04)
1718 #define IOP_REG_ID (0x05)
1719 #define IOP_REG_QP (0x03)
1720 #define IOP_REG_IH (0x02)
1721 #define IOP_REG_IX (0x01)
1722 #define IOP_REG_AX (0x00)
1723 #define IFC_REG_LOCK (0x00)
1724 #define IFC_REG_UNLOCK (0x09)
1725 #define IFC_WR_EN_FILTER (0x10)
1726 #define IFC_RD_NO_EEPROM (0x10)
1727 #define IFC_SLEW_RATE (0x20)
1728 #define IFC_ACT_NEG (0x40)
1729 #define IFC_INP_FILTER (0x80)
1730 #define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
1731 #define SC_SEL (uchar)(0x80)
1732 #define SC_BSY (uchar)(0x40)
1733 #define SC_ACK (uchar)(0x20)
1734 #define SC_REQ (uchar)(0x10)
1735 #define SC_ATN (uchar)(0x08)
1736 #define SC_IO (uchar)(0x04)
1737 #define SC_CD (uchar)(0x02)
1738 #define SC_MSG (uchar)(0x01)
1739 #define SEC_SCSI_CTL (uchar)(0x80)
1740 #define SEC_ACTIVE_NEGATE (uchar)(0x40)
1741 #define SEC_SLEW_RATE (uchar)(0x20)
1742 #define SEC_ENABLE_FILTER (uchar)(0x10)
1743 #define ASC_HALT_EXTMSG_IN (ushort)0x8000
1744 #define ASC_HALT_CHK_CONDITION (ushort)0x8100
1745 #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1746 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
1747 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
1748 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1749 #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1750 #define ASC_MAX_QNO 0xF8
1751 #define ASC_DATA_SEC_BEG (ushort)0x0080
1752 #define ASC_DATA_SEC_END (ushort)0x0080
1753 #define ASC_CODE_SEC_BEG (ushort)0x0080
1754 #define ASC_CODE_SEC_END (ushort)0x0080
1755 #define ASC_QADR_BEG (0x4000)
1756 #define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
1757 #define ASC_QADR_END (ushort)0x7FFF
1758 #define ASC_QLAST_ADR (ushort)0x7FC0
1759 #define ASC_QBLK_SIZE 0x40
1760 #define ASC_BIOS_DATA_QBEG 0xF8
1761 #define ASC_MIN_ACTIVE_QNO 0x01
1762 #define ASC_QLINK_END 0xFF
1763 #define ASC_EEPROM_WORDS 0x10
1764 #define ASC_MAX_MGS_LEN 0x10
1765 #define ASC_BIOS_ADDR_DEF 0xDC00
1766 #define ASC_BIOS_SIZE 0x3800
1767 #define ASC_BIOS_RAM_OFF 0x3800
1768 #define ASC_BIOS_RAM_SIZE 0x800
1769 #define ASC_BIOS_MIN_ADDR 0xC000
1770 #define ASC_BIOS_MAX_ADDR 0xEC00
1771 #define ASC_BIOS_BANK_SIZE 0x0400
1772 #define ASC_MCODE_START_ADDR 0x0080
1773 #define ASC_CFG0_HOST_INT_ON 0x0020
1774 #define ASC_CFG0_BIOS_ON 0x0040
1775 #define ASC_CFG0_VERA_BURST_ON 0x0080
1776 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
1777 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
1778 #define ASC_CFG1_LRAM_8BITS_ON 0x0800
1779 #define ASC_CFG_MSW_CLR_MASK 0x3080
1780 #define CSW_TEST1 (ASC_CS_TYPE)0x8000
1781 #define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
1782 #define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
1783 #define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
1784 #define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
1785 #define CSW_TEST2 (ASC_CS_TYPE)0x0400
1786 #define CSW_TEST3 (ASC_CS_TYPE)0x0200
1787 #define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
1788 #define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
1789 #define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
1790 #define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
1791 #define CSW_HALTED (ASC_CS_TYPE)0x0010
1792 #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1793 #define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
1794 #define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
1795 #define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
1796 #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1797 #define CIW_INT_ACK (ASC_CS_TYPE)0x0100
1798 #define CIW_TEST1 (ASC_CS_TYPE)0x0200
1799 #define CIW_TEST2 (ASC_CS_TYPE)0x0400
1800 #define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
1801 #define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
1802 #define CC_CHIP_RESET (uchar)0x80
1803 #define CC_SCSI_RESET (uchar)0x40
1804 #define CC_HALT (uchar)0x20
1805 #define CC_SINGLE_STEP (uchar)0x10
1806 #define CC_DMA_ABLE (uchar)0x08
1807 #define CC_TEST (uchar)0x04
1808 #define CC_BANK_ONE (uchar)0x02
1809 #define CC_DIAG (uchar)0x01
1810 #define ASC_1000_ID0W 0x04C1
1811 #define ASC_1000_ID0W_FIX 0x00C1
1812 #define ASC_1000_ID1B 0x25
1813 #define ASC_EISA_BIG_IOP_GAP (0x1C30-0x0C50)
1814 #define ASC_EISA_SMALL_IOP_GAP (0x0020)
1815 #define ASC_EISA_MIN_IOP_ADDR (0x0C30)
1816 #define ASC_EISA_MAX_IOP_ADDR (0xFC50)
1817 #define ASC_EISA_REV_IOP_MASK (0x0C83)
1818 #define ASC_EISA_PID_IOP_MASK (0x0C80)
1819 #define ASC_EISA_CFG_IOP_MASK (0x0C86)
1820 #define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
1821 #define ASC_EISA_ID_740 0x01745004UL
1822 #define ASC_EISA_ID_750 0x01755004UL
1823 #define INS_HALTINT (ushort)0x6281
1824 #define INS_HALT (ushort)0x6280
1825 #define INS_SINT (ushort)0x6200
1826 #define INS_RFLAG_WTM (ushort)0x7380
1827 #define ASC_MC_SAVE_CODE_WSIZE 0x500
1828 #define ASC_MC_SAVE_DATA_WSIZE 0x40
1830 typedef struct asc_mc_saved {
1831 ushort data[ASC_MC_SAVE_DATA_WSIZE];
1832 ushort code[ASC_MC_SAVE_CODE_WSIZE];
1833 } ASC_MC_SAVED;
1835 #define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1836 #define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1837 #define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1838 #define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1839 #define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1840 #define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1841 #define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
1842 #define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
1843 #define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1844 #define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1845 #define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1846 #define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1847 #define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1848 #define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1849 #define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1850 #define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
1851 #define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
1852 #define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
1853 #define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
1854 #define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
1855 #define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
1856 #define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
1857 #define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
1858 #define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
1859 #define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
1860 #define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
1861 #define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1862 #define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1863 #define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
1864 #define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
1865 #define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
1866 #define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
1867 #define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1868 #define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
1869 #define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
1870 #define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
1871 #define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
1872 #define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
1873 #define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
1874 #define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
1875 #define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1876 #define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1877 #define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
1878 #define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
1879 #define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
1880 #define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
1881 #define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
1882 #define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
1883 #define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
1884 #define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
1885 #define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
1886 #define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
1887 #define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
1888 #define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
1889 #define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
1890 #define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
1891 #define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
1892 #define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
1893 #define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
1894 #define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
1895 #define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
1896 #define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
1897 #define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
1898 #define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
1899 #define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
1900 #define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
1901 #define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
1902 #define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
1904 STATIC int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1905 STATIC int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1906 STATIC void AscWaitEEPRead(void);
1907 STATIC void AscWaitEEPWrite(void);
1908 STATIC ushort AscReadEEPWord(PortAddr, uchar);
1909 STATIC ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1910 STATIC ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1911 STATIC int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1912 STATIC int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1913 STATIC int AscStartChip(PortAddr);
1914 STATIC int AscStopChip(PortAddr);
1915 STATIC void AscSetChipIH(PortAddr, ushort);
1916 STATIC int AscIsChipHalted(PortAddr);
1917 STATIC void AscAckInterrupt(PortAddr);
1918 STATIC void AscDisableInterrupt(PortAddr);
1919 STATIC void AscEnableInterrupt(PortAddr);
1920 STATIC void AscSetBank(PortAddr, uchar);
1921 STATIC int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1922 #ifdef CONFIG_ISA
1923 STATIC ushort AscGetIsaDmaChannel(PortAddr);
1924 STATIC ushort AscSetIsaDmaChannel(PortAddr, ushort);
1925 STATIC uchar AscSetIsaDmaSpeed(PortAddr, uchar);
1926 STATIC uchar AscGetIsaDmaSpeed(PortAddr);
1927 #endif /* CONFIG_ISA */
1928 STATIC uchar AscReadLramByte(PortAddr, ushort);
1929 STATIC ushort AscReadLramWord(PortAddr, ushort);
1930 #if CC_VERY_LONG_SG_LIST
1931 STATIC ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1932 #endif /* CC_VERY_LONG_SG_LIST */
1933 STATIC void AscWriteLramWord(PortAddr, ushort, ushort);
1934 STATIC void AscWriteLramByte(PortAddr, ushort, uchar);
1935 STATIC ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
1936 STATIC void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1937 STATIC void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1938 STATIC void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1939 STATIC void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
1940 STATIC ushort AscInitAscDvcVar(ASC_DVC_VAR *);
1941 STATIC ushort AscInitFromEEP(ASC_DVC_VAR *);
1942 STATIC ushort AscInitFromAscDvcVar(ASC_DVC_VAR *);
1943 STATIC ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1944 STATIC int AscTestExternalLram(ASC_DVC_VAR *);
1945 STATIC uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1946 STATIC uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1947 STATIC void AscSetChipSDTR(PortAddr, uchar, uchar);
1948 STATIC uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1949 STATIC uchar AscAllocFreeQueue(PortAddr, uchar);
1950 STATIC uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1951 STATIC int AscHostReqRiscHalt(PortAddr);
1952 STATIC int AscStopQueueExe(PortAddr);
1953 STATIC int AscSendScsiQueue(ASC_DVC_VAR *,
1954 ASC_SCSI_Q * scsiq,
1955 uchar n_q_required);
1956 STATIC int AscPutReadyQueue(ASC_DVC_VAR *,
1957 ASC_SCSI_Q *, uchar);
1958 STATIC int AscPutReadySgListQueue(ASC_DVC_VAR *,
1959 ASC_SCSI_Q *, uchar);
1960 STATIC int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1961 STATIC int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1962 STATIC ushort AscInitLram(ASC_DVC_VAR *);
1963 STATIC ushort AscInitQLinkVar(ASC_DVC_VAR *);
1964 STATIC int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1965 STATIC int AscIsrChipHalted(ASC_DVC_VAR *);
1966 STATIC uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1967 ASC_QDONE_INFO *, ASC_DCNT);
1968 STATIC int AscIsrQDone(ASC_DVC_VAR *);
1969 STATIC int AscCompareString(uchar *, uchar *, int);
1970 #ifdef CONFIG_ISA
1971 STATIC ushort AscGetEisaChipCfg(PortAddr);
1972 STATIC ASC_DCNT AscGetEisaProductID(PortAddr);
1973 STATIC PortAddr AscSearchIOPortAddrEISA(PortAddr);
1974 STATIC PortAddr AscSearchIOPortAddr11(PortAddr);
1975 STATIC PortAddr AscSearchIOPortAddr(PortAddr, ushort);
1976 STATIC void AscSetISAPNPWaitForKey(void);
1977 #endif /* CONFIG_ISA */
1978 STATIC uchar AscGetChipScsiCtrl(PortAddr);
1979 STATIC uchar AscSetChipScsiID(PortAddr, uchar);
1980 STATIC uchar AscGetChipVersion(PortAddr, ushort);
1981 STATIC ushort AscGetChipBusType(PortAddr);
1982 STATIC ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
1983 STATIC int AscFindSignature(PortAddr);
1984 STATIC void AscToggleIRQAct(PortAddr);
1985 STATIC uchar AscGetChipIRQ(PortAddr, ushort);
1986 STATIC uchar AscSetChipIRQ(PortAddr, uchar, ushort);
1987 STATIC ushort AscGetChipBiosAddress(PortAddr, ushort);
1988 STATIC inline ulong DvcEnterCritical(void);
1989 STATIC inline void DvcLeaveCritical(ulong);
1990 #ifdef CONFIG_PCI
1991 STATIC uchar DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort);
1992 STATIC void DvcWritePCIConfigByte(ASC_DVC_VAR *,
1993 ushort, uchar);
1994 #endif /* CONFIG_PCI */
1995 STATIC ushort AscGetChipBiosAddress(PortAddr, ushort);
1996 STATIC void DvcSleepMilliSecond(ASC_DCNT);
1997 STATIC void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
1998 STATIC void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1999 STATIC void DvcGetQinfo(PortAddr, ushort, uchar *, int);
2000 STATIC ushort AscInitGetConfig(ASC_DVC_VAR *);
2001 STATIC ushort AscInitSetConfig(ASC_DVC_VAR *);
2002 STATIC ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
2003 STATIC void AscAsyncFix(ASC_DVC_VAR *, uchar,
2004 ASC_SCSI_INQUIRY *);
2005 STATIC int AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
2006 STATIC void AscInquiryHandling(ASC_DVC_VAR *,
2007 uchar, ASC_SCSI_INQUIRY *);
2008 STATIC int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
2009 STATIC int AscISR(ASC_DVC_VAR *);
2010 STATIC uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar,
2011 uchar);
2012 STATIC int AscSgListToQueue(int);
2013 #ifdef CONFIG_ISA
2014 STATIC void AscEnableIsaDma(uchar);
2015 #endif /* CONFIG_ISA */
2016 STATIC ASC_DCNT AscGetMaxDmaCount(ushort);
2020 * --- Adv Library Constants and Macros
2023 #define ADV_LIB_VERSION_MAJOR 5
2024 #define ADV_LIB_VERSION_MINOR 14
2027 * Define Adv Library required special types.
2031 * Portable Data Types
2033 * Any instance where a 32-bit long or pointer type is assumed
2034 * for precision or HW defined structures, the following define
2035 * types must be used. In Linux the char, short, and int types
2036 * are all consistent at 8, 16, and 32 bits respectively. Pointers
2037 * and long types are 64 bits on Alpha and UltraSPARC.
2039 #define ADV_PADDR __u32 /* Physical address data type. */
2040 #define ADV_VADDR __u32 /* Virtual address data type. */
2041 #define ADV_DCNT __u32 /* Unsigned Data count type. */
2042 #define ADV_SDCNT __s32 /* Signed Data count type. */
2045 * These macros are used to convert a virtual address to a
2046 * 32-bit value. This currently can be used on Linux Alpha
2047 * which uses 64-bit virtual address but a 32-bit bus address.
2048 * This is likely to break in the future, but doing this now
2049 * will give us time to change the HW and FW to handle 64-bit
2050 * addresses.
2052 #define ADV_VADDR_TO_U32 virt_to_bus
2053 #define ADV_U32_TO_VADDR bus_to_virt
2055 #define AdvPortAddr void __iomem * /* Virtual memory address size */
2058 * Define Adv Library required memory access macros.
2060 #define ADV_MEM_READB(addr) readb(addr)
2061 #define ADV_MEM_READW(addr) readw(addr)
2062 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
2063 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
2064 #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
2066 #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
2069 * For wide boards a CDB length maximum of 16 bytes
2070 * is supported.
2072 #define ADV_MAX_CDB_LEN 16
2075 * Define total number of simultaneous maximum element scatter-gather
2076 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
2077 * maximum number of outstanding commands per wide host adapter. Each
2078 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
2079 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
2080 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
2081 * structures or 255 scatter-gather elements.
2084 #define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
2087 * Define Adv Library required maximum number of scatter-gather
2088 * elements per request.
2090 #define ADV_MAX_SG_LIST 255
2092 /* Number of SG blocks needed. */
2093 #define ADV_NUM_SG_BLOCK \
2094 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
2096 /* Total contiguous memory needed for SG blocks. */
2097 #define ADV_SG_TOTAL_MEM_SIZE \
2098 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
2100 #define ADV_PAGE_SIZE PAGE_SIZE
2102 #define ADV_NUM_PAGE_CROSSING \
2103 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2105 #define ADV_EEP_DVC_CFG_BEGIN (0x00)
2106 #define ADV_EEP_DVC_CFG_END (0x15)
2107 #define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
2108 #define ADV_EEP_MAX_WORD_ADDR (0x1E)
2110 #define ADV_EEP_DELAY_MS 100
2112 #define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
2113 #define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
2115 * For the ASC3550 Bit 13 is Termination Polarity control bit.
2116 * For later ICs Bit 13 controls whether the CIS (Card Information
2117 * Service Section) is loaded from EEPROM.
2119 #define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
2120 #define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
2122 * ASC38C1600 Bit 11
2124 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
2125 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
2126 * Function 0 will specify INT B.
2128 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
2129 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
2130 * Function 1 will specify INT A.
2132 #define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
2134 typedef struct adveep_3550_config
2136 /* Word Offset, Description */
2138 ushort cfg_lsw; /* 00 power up initialization */
2139 /* bit 13 set - Term Polarity Control */
2140 /* bit 14 set - BIOS Enable */
2141 /* bit 15 set - Big Endian Mode */
2142 ushort cfg_msw; /* 01 unused */
2143 ushort disc_enable; /* 02 disconnect enable */
2144 ushort wdtr_able; /* 03 Wide DTR able */
2145 ushort sdtr_able; /* 04 Synchronous DTR able */
2146 ushort start_motor; /* 05 send start up motor */
2147 ushort tagqng_able; /* 06 tag queuing able */
2148 ushort bios_scan; /* 07 BIOS device control */
2149 ushort scam_tolerant; /* 08 no scam */
2151 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2152 uchar bios_boot_delay; /* power up wait */
2154 uchar scsi_reset_delay; /* 10 reset delay */
2155 uchar bios_id_lun; /* first boot device scsi id & lun */
2156 /* high nibble is lun */
2157 /* low nibble is scsi id */
2159 uchar termination; /* 11 0 - automatic */
2160 /* 1 - low off / high off */
2161 /* 2 - low off / high on */
2162 /* 3 - low on / high on */
2163 /* There is no low on / high off */
2165 uchar reserved1; /* reserved byte (not used) */
2167 ushort bios_ctrl; /* 12 BIOS control bits */
2168 /* bit 0 BIOS don't act as initiator. */
2169 /* bit 1 BIOS > 1 GB support */
2170 /* bit 2 BIOS > 2 Disk Support */
2171 /* bit 3 BIOS don't support removables */
2172 /* bit 4 BIOS support bootable CD */
2173 /* bit 5 BIOS scan enabled */
2174 /* bit 6 BIOS support multiple LUNs */
2175 /* bit 7 BIOS display of message */
2176 /* bit 8 SCAM disabled */
2177 /* bit 9 Reset SCSI bus during init. */
2178 /* bit 10 */
2179 /* bit 11 No verbose initialization. */
2180 /* bit 12 SCSI parity enabled */
2181 /* bit 13 */
2182 /* bit 14 */
2183 /* bit 15 */
2184 ushort ultra_able; /* 13 ULTRA speed able */
2185 ushort reserved2; /* 14 reserved */
2186 uchar max_host_qng; /* 15 maximum host queuing */
2187 uchar max_dvc_qng; /* maximum per device queuing */
2188 ushort dvc_cntl; /* 16 control bit for driver */
2189 ushort bug_fix; /* 17 control bit for bug fix */
2190 ushort serial_number_word1; /* 18 Board serial number word 1 */
2191 ushort serial_number_word2; /* 19 Board serial number word 2 */
2192 ushort serial_number_word3; /* 20 Board serial number word 3 */
2193 ushort check_sum; /* 21 EEP check sum */
2194 uchar oem_name[16]; /* 22 OEM name */
2195 ushort dvc_err_code; /* 30 last device driver error code */
2196 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2197 ushort adv_err_addr; /* 32 last uc error address */
2198 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2199 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2200 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2201 ushort num_of_err; /* 36 number of error */
2202 } ADVEEP_3550_CONFIG;
2204 typedef struct adveep_38C0800_config
2206 /* Word Offset, Description */
2208 ushort cfg_lsw; /* 00 power up initialization */
2209 /* bit 13 set - Load CIS */
2210 /* bit 14 set - BIOS Enable */
2211 /* bit 15 set - Big Endian Mode */
2212 ushort cfg_msw; /* 01 unused */
2213 ushort disc_enable; /* 02 disconnect enable */
2214 ushort wdtr_able; /* 03 Wide DTR able */
2215 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2216 ushort start_motor; /* 05 send start up motor */
2217 ushort tagqng_able; /* 06 tag queuing able */
2218 ushort bios_scan; /* 07 BIOS device control */
2219 ushort scam_tolerant; /* 08 no scam */
2221 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2222 uchar bios_boot_delay; /* power up wait */
2224 uchar scsi_reset_delay; /* 10 reset delay */
2225 uchar bios_id_lun; /* first boot device scsi id & lun */
2226 /* high nibble is lun */
2227 /* low nibble is scsi id */
2229 uchar termination_se; /* 11 0 - automatic */
2230 /* 1 - low off / high off */
2231 /* 2 - low off / high on */
2232 /* 3 - low on / high on */
2233 /* There is no low on / high off */
2235 uchar termination_lvd; /* 11 0 - automatic */
2236 /* 1 - low off / high off */
2237 /* 2 - low off / high on */
2238 /* 3 - low on / high on */
2239 /* There is no low on / high off */
2241 ushort bios_ctrl; /* 12 BIOS control bits */
2242 /* bit 0 BIOS don't act as initiator. */
2243 /* bit 1 BIOS > 1 GB support */
2244 /* bit 2 BIOS > 2 Disk Support */
2245 /* bit 3 BIOS don't support removables */
2246 /* bit 4 BIOS support bootable CD */
2247 /* bit 5 BIOS scan enabled */
2248 /* bit 6 BIOS support multiple LUNs */
2249 /* bit 7 BIOS display of message */
2250 /* bit 8 SCAM disabled */
2251 /* bit 9 Reset SCSI bus during init. */
2252 /* bit 10 */
2253 /* bit 11 No verbose initialization. */
2254 /* bit 12 SCSI parity enabled */
2255 /* bit 13 */
2256 /* bit 14 */
2257 /* bit 15 */
2258 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2259 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2260 uchar max_host_qng; /* 15 maximum host queueing */
2261 uchar max_dvc_qng; /* maximum per device queuing */
2262 ushort dvc_cntl; /* 16 control bit for driver */
2263 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2264 ushort serial_number_word1; /* 18 Board serial number word 1 */
2265 ushort serial_number_word2; /* 19 Board serial number word 2 */
2266 ushort serial_number_word3; /* 20 Board serial number word 3 */
2267 ushort check_sum; /* 21 EEP check sum */
2268 uchar oem_name[16]; /* 22 OEM name */
2269 ushort dvc_err_code; /* 30 last device driver error code */
2270 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2271 ushort adv_err_addr; /* 32 last uc error address */
2272 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2273 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2274 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2275 ushort reserved36; /* 36 reserved */
2276 ushort reserved37; /* 37 reserved */
2277 ushort reserved38; /* 38 reserved */
2278 ushort reserved39; /* 39 reserved */
2279 ushort reserved40; /* 40 reserved */
2280 ushort reserved41; /* 41 reserved */
2281 ushort reserved42; /* 42 reserved */
2282 ushort reserved43; /* 43 reserved */
2283 ushort reserved44; /* 44 reserved */
2284 ushort reserved45; /* 45 reserved */
2285 ushort reserved46; /* 46 reserved */
2286 ushort reserved47; /* 47 reserved */
2287 ushort reserved48; /* 48 reserved */
2288 ushort reserved49; /* 49 reserved */
2289 ushort reserved50; /* 50 reserved */
2290 ushort reserved51; /* 51 reserved */
2291 ushort reserved52; /* 52 reserved */
2292 ushort reserved53; /* 53 reserved */
2293 ushort reserved54; /* 54 reserved */
2294 ushort reserved55; /* 55 reserved */
2295 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2296 ushort cisprt_msw; /* 57 CIS PTR MSW */
2297 ushort subsysvid; /* 58 SubSystem Vendor ID */
2298 ushort subsysid; /* 59 SubSystem ID */
2299 ushort reserved60; /* 60 reserved */
2300 ushort reserved61; /* 61 reserved */
2301 ushort reserved62; /* 62 reserved */
2302 ushort reserved63; /* 63 reserved */
2303 } ADVEEP_38C0800_CONFIG;
2305 typedef struct adveep_38C1600_config
2307 /* Word Offset, Description */
2309 ushort cfg_lsw; /* 00 power up initialization */
2310 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
2311 /* clear - Func. 0 INTA, Func. 1 INTB */
2312 /* bit 13 set - Load CIS */
2313 /* bit 14 set - BIOS Enable */
2314 /* bit 15 set - Big Endian Mode */
2315 ushort cfg_msw; /* 01 unused */
2316 ushort disc_enable; /* 02 disconnect enable */
2317 ushort wdtr_able; /* 03 Wide DTR able */
2318 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2319 ushort start_motor; /* 05 send start up motor */
2320 ushort tagqng_able; /* 06 tag queuing able */
2321 ushort bios_scan; /* 07 BIOS device control */
2322 ushort scam_tolerant; /* 08 no scam */
2324 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2325 uchar bios_boot_delay; /* power up wait */
2327 uchar scsi_reset_delay; /* 10 reset delay */
2328 uchar bios_id_lun; /* first boot device scsi id & lun */
2329 /* high nibble is lun */
2330 /* low nibble is scsi id */
2332 uchar termination_se; /* 11 0 - automatic */
2333 /* 1 - low off / high off */
2334 /* 2 - low off / high on */
2335 /* 3 - low on / high on */
2336 /* There is no low on / high off */
2338 uchar termination_lvd; /* 11 0 - automatic */
2339 /* 1 - low off / high off */
2340 /* 2 - low off / high on */
2341 /* 3 - low on / high on */
2342 /* There is no low on / high off */
2344 ushort bios_ctrl; /* 12 BIOS control bits */
2345 /* bit 0 BIOS don't act as initiator. */
2346 /* bit 1 BIOS > 1 GB support */
2347 /* bit 2 BIOS > 2 Disk Support */
2348 /* bit 3 BIOS don't support removables */
2349 /* bit 4 BIOS support bootable CD */
2350 /* bit 5 BIOS scan enabled */
2351 /* bit 6 BIOS support multiple LUNs */
2352 /* bit 7 BIOS display of message */
2353 /* bit 8 SCAM disabled */
2354 /* bit 9 Reset SCSI bus during init. */
2355 /* bit 10 Basic Integrity Checking disabled */
2356 /* bit 11 No verbose initialization. */
2357 /* bit 12 SCSI parity enabled */
2358 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
2359 /* bit 14 */
2360 /* bit 15 */
2361 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2362 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2363 uchar max_host_qng; /* 15 maximum host queueing */
2364 uchar max_dvc_qng; /* maximum per device queuing */
2365 ushort dvc_cntl; /* 16 control bit for driver */
2366 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2367 ushort serial_number_word1; /* 18 Board serial number word 1 */
2368 ushort serial_number_word2; /* 19 Board serial number word 2 */
2369 ushort serial_number_word3; /* 20 Board serial number word 3 */
2370 ushort check_sum; /* 21 EEP check sum */
2371 uchar oem_name[16]; /* 22 OEM name */
2372 ushort dvc_err_code; /* 30 last device driver error code */
2373 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2374 ushort adv_err_addr; /* 32 last uc error address */
2375 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2376 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2377 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2378 ushort reserved36; /* 36 reserved */
2379 ushort reserved37; /* 37 reserved */
2380 ushort reserved38; /* 38 reserved */
2381 ushort reserved39; /* 39 reserved */
2382 ushort reserved40; /* 40 reserved */
2383 ushort reserved41; /* 41 reserved */
2384 ushort reserved42; /* 42 reserved */
2385 ushort reserved43; /* 43 reserved */
2386 ushort reserved44; /* 44 reserved */
2387 ushort reserved45; /* 45 reserved */
2388 ushort reserved46; /* 46 reserved */
2389 ushort reserved47; /* 47 reserved */
2390 ushort reserved48; /* 48 reserved */
2391 ushort reserved49; /* 49 reserved */
2392 ushort reserved50; /* 50 reserved */
2393 ushort reserved51; /* 51 reserved */
2394 ushort reserved52; /* 52 reserved */
2395 ushort reserved53; /* 53 reserved */
2396 ushort reserved54; /* 54 reserved */
2397 ushort reserved55; /* 55 reserved */
2398 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2399 ushort cisprt_msw; /* 57 CIS PTR MSW */
2400 ushort subsysvid; /* 58 SubSystem Vendor ID */
2401 ushort subsysid; /* 59 SubSystem ID */
2402 ushort reserved60; /* 60 reserved */
2403 ushort reserved61; /* 61 reserved */
2404 ushort reserved62; /* 62 reserved */
2405 ushort reserved63; /* 63 reserved */
2406 } ADVEEP_38C1600_CONFIG;
2409 * EEPROM Commands
2411 #define ASC_EEP_CMD_DONE 0x0200
2412 #define ASC_EEP_CMD_DONE_ERR 0x0001
2414 /* cfg_word */
2415 #define EEP_CFG_WORD_BIG_ENDIAN 0x8000
2417 /* bios_ctrl */
2418 #define BIOS_CTRL_BIOS 0x0001
2419 #define BIOS_CTRL_EXTENDED_XLAT 0x0002
2420 #define BIOS_CTRL_GT_2_DISK 0x0004
2421 #define BIOS_CTRL_BIOS_REMOVABLE 0x0008
2422 #define BIOS_CTRL_BOOTABLE_CD 0x0010
2423 #define BIOS_CTRL_MULTIPLE_LUN 0x0040
2424 #define BIOS_CTRL_DISPLAY_MSG 0x0080
2425 #define BIOS_CTRL_NO_SCAM 0x0100
2426 #define BIOS_CTRL_RESET_SCSI_BUS 0x0200
2427 #define BIOS_CTRL_INIT_VERBOSE 0x0800
2428 #define BIOS_CTRL_SCSI_PARITY 0x1000
2429 #define BIOS_CTRL_AIPP_DIS 0x2000
2431 #define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
2432 #define ADV_3550_IOLEN 0x40 /* I/O Port Range in bytes */
2434 #define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2435 #define ADV_38C0800_IOLEN 0x100 /* I/O Port Range in bytes */
2438 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
2439 * a special 16K Adv Library and Microcode version. After the issue is
2440 * resolved, should restore 32K support.
2442 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
2444 #define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2445 #define ADV_38C1600_IOLEN 0x100 /* I/O Port Range 256 bytes */
2446 #define ADV_38C1600_MEMLEN 0x1000 /* Memory Range 4KB bytes */
2449 * Byte I/O register address from base of 'iop_base'.
2451 #define IOPB_INTR_STATUS_REG 0x00
2452 #define IOPB_CHIP_ID_1 0x01
2453 #define IOPB_INTR_ENABLES 0x02
2454 #define IOPB_CHIP_TYPE_REV 0x03
2455 #define IOPB_RES_ADDR_4 0x04
2456 #define IOPB_RES_ADDR_5 0x05
2457 #define IOPB_RAM_DATA 0x06
2458 #define IOPB_RES_ADDR_7 0x07
2459 #define IOPB_FLAG_REG 0x08
2460 #define IOPB_RES_ADDR_9 0x09
2461 #define IOPB_RISC_CSR 0x0A
2462 #define IOPB_RES_ADDR_B 0x0B
2463 #define IOPB_RES_ADDR_C 0x0C
2464 #define IOPB_RES_ADDR_D 0x0D
2465 #define IOPB_SOFT_OVER_WR 0x0E
2466 #define IOPB_RES_ADDR_F 0x0F
2467 #define IOPB_MEM_CFG 0x10
2468 #define IOPB_RES_ADDR_11 0x11
2469 #define IOPB_GPIO_DATA 0x12
2470 #define IOPB_RES_ADDR_13 0x13
2471 #define IOPB_FLASH_PAGE 0x14
2472 #define IOPB_RES_ADDR_15 0x15
2473 #define IOPB_GPIO_CNTL 0x16
2474 #define IOPB_RES_ADDR_17 0x17
2475 #define IOPB_FLASH_DATA 0x18
2476 #define IOPB_RES_ADDR_19 0x19
2477 #define IOPB_RES_ADDR_1A 0x1A
2478 #define IOPB_RES_ADDR_1B 0x1B
2479 #define IOPB_RES_ADDR_1C 0x1C
2480 #define IOPB_RES_ADDR_1D 0x1D
2481 #define IOPB_RES_ADDR_1E 0x1E
2482 #define IOPB_RES_ADDR_1F 0x1F
2483 #define IOPB_DMA_CFG0 0x20
2484 #define IOPB_DMA_CFG1 0x21
2485 #define IOPB_TICKLE 0x22
2486 #define IOPB_DMA_REG_WR 0x23
2487 #define IOPB_SDMA_STATUS 0x24
2488 #define IOPB_SCSI_BYTE_CNT 0x25
2489 #define IOPB_HOST_BYTE_CNT 0x26
2490 #define IOPB_BYTE_LEFT_TO_XFER 0x27
2491 #define IOPB_BYTE_TO_XFER_0 0x28
2492 #define IOPB_BYTE_TO_XFER_1 0x29
2493 #define IOPB_BYTE_TO_XFER_2 0x2A
2494 #define IOPB_BYTE_TO_XFER_3 0x2B
2495 #define IOPB_ACC_GRP 0x2C
2496 #define IOPB_RES_ADDR_2D 0x2D
2497 #define IOPB_DEV_ID 0x2E
2498 #define IOPB_RES_ADDR_2F 0x2F
2499 #define IOPB_SCSI_DATA 0x30
2500 #define IOPB_RES_ADDR_31 0x31
2501 #define IOPB_RES_ADDR_32 0x32
2502 #define IOPB_SCSI_DATA_HSHK 0x33
2503 #define IOPB_SCSI_CTRL 0x34
2504 #define IOPB_RES_ADDR_35 0x35
2505 #define IOPB_RES_ADDR_36 0x36
2506 #define IOPB_RES_ADDR_37 0x37
2507 #define IOPB_RAM_BIST 0x38
2508 #define IOPB_PLL_TEST 0x39
2509 #define IOPB_PCI_INT_CFG 0x3A
2510 #define IOPB_RES_ADDR_3B 0x3B
2511 #define IOPB_RFIFO_CNT 0x3C
2512 #define IOPB_RES_ADDR_3D 0x3D
2513 #define IOPB_RES_ADDR_3E 0x3E
2514 #define IOPB_RES_ADDR_3F 0x3F
2517 * Word I/O register address from base of 'iop_base'.
2519 #define IOPW_CHIP_ID_0 0x00 /* CID0 */
2520 #define IOPW_CTRL_REG 0x02 /* CC */
2521 #define IOPW_RAM_ADDR 0x04 /* LA */
2522 #define IOPW_RAM_DATA 0x06 /* LD */
2523 #define IOPW_RES_ADDR_08 0x08
2524 #define IOPW_RISC_CSR 0x0A /* CSR */
2525 #define IOPW_SCSI_CFG0 0x0C /* CFG0 */
2526 #define IOPW_SCSI_CFG1 0x0E /* CFG1 */
2527 #define IOPW_RES_ADDR_10 0x10
2528 #define IOPW_SEL_MASK 0x12 /* SM */
2529 #define IOPW_RES_ADDR_14 0x14
2530 #define IOPW_FLASH_ADDR 0x16 /* FA */
2531 #define IOPW_RES_ADDR_18 0x18
2532 #define IOPW_EE_CMD 0x1A /* EC */
2533 #define IOPW_EE_DATA 0x1C /* ED */
2534 #define IOPW_SFIFO_CNT 0x1E /* SFC */
2535 #define IOPW_RES_ADDR_20 0x20
2536 #define IOPW_Q_BASE 0x22 /* QB */
2537 #define IOPW_QP 0x24 /* QP */
2538 #define IOPW_IX 0x26 /* IX */
2539 #define IOPW_SP 0x28 /* SP */
2540 #define IOPW_PC 0x2A /* PC */
2541 #define IOPW_RES_ADDR_2C 0x2C
2542 #define IOPW_RES_ADDR_2E 0x2E
2543 #define IOPW_SCSI_DATA 0x30 /* SD */
2544 #define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
2545 #define IOPW_SCSI_CTRL 0x34 /* SC */
2546 #define IOPW_HSHK_CFG 0x36 /* HCFG */
2547 #define IOPW_SXFR_STATUS 0x36 /* SXS */
2548 #define IOPW_SXFR_CNTL 0x38 /* SXL */
2549 #define IOPW_SXFR_CNTH 0x3A /* SXH */
2550 #define IOPW_RES_ADDR_3C 0x3C
2551 #define IOPW_RFIFO_DATA 0x3E /* RFD */
2554 * Doubleword I/O register address from base of 'iop_base'.
2556 #define IOPDW_RES_ADDR_0 0x00
2557 #define IOPDW_RAM_DATA 0x04
2558 #define IOPDW_RES_ADDR_8 0x08
2559 #define IOPDW_RES_ADDR_C 0x0C
2560 #define IOPDW_RES_ADDR_10 0x10
2561 #define IOPDW_COMMA 0x14
2562 #define IOPDW_COMMB 0x18
2563 #define IOPDW_RES_ADDR_1C 0x1C
2564 #define IOPDW_SDMA_ADDR0 0x20
2565 #define IOPDW_SDMA_ADDR1 0x24
2566 #define IOPDW_SDMA_COUNT 0x28
2567 #define IOPDW_SDMA_ERROR 0x2C
2568 #define IOPDW_RDMA_ADDR0 0x30
2569 #define IOPDW_RDMA_ADDR1 0x34
2570 #define IOPDW_RDMA_COUNT 0x38
2571 #define IOPDW_RDMA_ERROR 0x3C
2573 #define ADV_CHIP_ID_BYTE 0x25
2574 #define ADV_CHIP_ID_WORD 0x04C1
2576 #define ADV_SC_SCSI_BUS_RESET 0x2000
2578 #define ADV_INTR_ENABLE_HOST_INTR 0x01
2579 #define ADV_INTR_ENABLE_SEL_INTR 0x02
2580 #define ADV_INTR_ENABLE_DPR_INTR 0x04
2581 #define ADV_INTR_ENABLE_RTA_INTR 0x08
2582 #define ADV_INTR_ENABLE_RMA_INTR 0x10
2583 #define ADV_INTR_ENABLE_RST_INTR 0x20
2584 #define ADV_INTR_ENABLE_DPE_INTR 0x40
2585 #define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
2587 #define ADV_INTR_STATUS_INTRA 0x01
2588 #define ADV_INTR_STATUS_INTRB 0x02
2589 #define ADV_INTR_STATUS_INTRC 0x04
2591 #define ADV_RISC_CSR_STOP (0x0000)
2592 #define ADV_RISC_TEST_COND (0x2000)
2593 #define ADV_RISC_CSR_RUN (0x4000)
2594 #define ADV_RISC_CSR_SINGLE_STEP (0x8000)
2596 #define ADV_CTRL_REG_HOST_INTR 0x0100
2597 #define ADV_CTRL_REG_SEL_INTR 0x0200
2598 #define ADV_CTRL_REG_DPR_INTR 0x0400
2599 #define ADV_CTRL_REG_RTA_INTR 0x0800
2600 #define ADV_CTRL_REG_RMA_INTR 0x1000
2601 #define ADV_CTRL_REG_RES_BIT14 0x2000
2602 #define ADV_CTRL_REG_DPE_INTR 0x4000
2603 #define ADV_CTRL_REG_POWER_DONE 0x8000
2604 #define ADV_CTRL_REG_ANY_INTR 0xFF00
2606 #define ADV_CTRL_REG_CMD_RESET 0x00C6
2607 #define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
2608 #define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
2609 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
2610 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
2612 #define ADV_TICKLE_NOP 0x00
2613 #define ADV_TICKLE_A 0x01
2614 #define ADV_TICKLE_B 0x02
2615 #define ADV_TICKLE_C 0x03
2617 #define ADV_SCSI_CTRL_RSTOUT 0x2000
2619 #define AdvIsIntPending(port) \
2620 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2623 * SCSI_CFG0 Register bit definitions
2625 #define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
2626 #define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
2627 #define EVEN_PARITY 0x1000 /* Select Even Parity */
2628 #define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2629 #define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
2630 #define PRIM_MODE 0x0100 /* Primitive SCSI mode */
2631 #define SCAM_EN 0x0080 /* Enable SCAM selection */
2632 #define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2633 #define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2634 #define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
2635 #define OUR_ID 0x000F /* SCSI ID */
2638 * SCSI_CFG1 Register bit definitions
2640 #define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
2641 #define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2642 #define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
2643 #define FILTER_SEL 0x0C00 /* Filter Period Selection */
2644 #define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
2645 #define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
2646 #define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
2647 #define ACTIVE_DBL 0x0200 /* Disable Active Negation */
2648 #define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
2649 #define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
2650 #define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
2651 #define TERM_CTL 0x0030 /* External SCSI Termination Bits */
2652 #define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
2653 #define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
2654 #define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
2657 * Addendum for ASC-38C0800 Chip
2659 * The ASC-38C1600 Chip uses the same definitions except that the
2660 * bus mode override bits [12:10] have been moved to byte register
2661 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
2662 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
2663 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
2664 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
2665 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
2667 #define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
2668 #define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
2669 #define HVD 0x1000 /* HVD Device Detect */
2670 #define LVD 0x0800 /* LVD Device Detect */
2671 #define SE 0x0400 /* SE Device Detect */
2672 #define TERM_LVD 0x00C0 /* LVD Termination Bits */
2673 #define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
2674 #define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
2675 #define TERM_SE 0x0030 /* SE Termination Bits */
2676 #define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
2677 #define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
2678 #define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
2679 #define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
2680 #define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
2681 #define C_DET_SE 0x0003 /* SE Cable Detect Bits */
2682 #define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
2683 #define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
2686 #define CABLE_ILLEGAL_A 0x7
2687 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
2689 #define CABLE_ILLEGAL_B 0xB
2690 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
2693 * MEM_CFG Register bit definitions
2695 #define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
2696 #define FAST_EE_CLK 0x20 /* Diagnostic Bit */
2697 #define RAM_SZ 0x1C /* Specify size of RAM to RISC */
2698 #define RAM_SZ_2KB 0x00 /* 2 KB */
2699 #define RAM_SZ_4KB 0x04 /* 4 KB */
2700 #define RAM_SZ_8KB 0x08 /* 8 KB */
2701 #define RAM_SZ_16KB 0x0C /* 16 KB */
2702 #define RAM_SZ_32KB 0x10 /* 32 KB */
2703 #define RAM_SZ_64KB 0x14 /* 64 KB */
2706 * DMA_CFG0 Register bit definitions
2708 * This register is only accessible to the host.
2710 #define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
2711 #define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
2712 #define FIFO_THRESH_16B 0x00 /* 16 bytes */
2713 #define FIFO_THRESH_32B 0x20 /* 32 bytes */
2714 #define FIFO_THRESH_48B 0x30 /* 48 bytes */
2715 #define FIFO_THRESH_64B 0x40 /* 64 bytes */
2716 #define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
2717 #define FIFO_THRESH_96B 0x60 /* 96 bytes */
2718 #define FIFO_THRESH_112B 0x70 /* 112 bytes */
2719 #define START_CTL 0x0C /* DMA start conditions */
2720 #define START_CTL_TH 0x00 /* Wait threshold level (default) */
2721 #define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
2722 #define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
2723 #define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
2724 #define READ_CMD 0x03 /* Memory Read Method */
2725 #define READ_CMD_MR 0x00 /* Memory Read */
2726 #define READ_CMD_MRL 0x02 /* Memory Read Long */
2727 #define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
2730 * ASC-38C0800 RAM BIST Register bit definitions
2732 #define RAM_TEST_MODE 0x80
2733 #define PRE_TEST_MODE 0x40
2734 #define NORMAL_MODE 0x00
2735 #define RAM_TEST_DONE 0x10
2736 #define RAM_TEST_STATUS 0x0F
2737 #define RAM_TEST_HOST_ERROR 0x08
2738 #define RAM_TEST_INTRAM_ERROR 0x04
2739 #define RAM_TEST_RISC_ERROR 0x02
2740 #define RAM_TEST_SCSI_ERROR 0x01
2741 #define RAM_TEST_SUCCESS 0x00
2742 #define PRE_TEST_VALUE 0x05
2743 #define NORMAL_VALUE 0x00
2746 * ASC38C1600 Definitions
2748 * IOPB_PCI_INT_CFG Bit Field Definitions
2751 #define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
2754 * Bit 1 can be set to change the interrupt for the Function to operate in
2755 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
2756 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
2757 * mode, otherwise the operating mode is undefined.
2759 #define TOTEMPOLE 0x02
2762 * Bit 0 can be used to change the Int Pin for the Function. The value is
2763 * 0 by default for both Functions with Function 0 using INT A and Function
2764 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
2765 * INT A is used.
2767 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
2768 * value specified in the PCI Configuration Space.
2770 #define INTAB 0x01
2772 /* a_advlib.h */
2775 * Adv Library Status Definitions
2777 #define ADV_TRUE 1
2778 #define ADV_FALSE 0
2779 #define ADV_NOERROR 1
2780 #define ADV_SUCCESS 1
2781 #define ADV_BUSY 0
2782 #define ADV_ERROR (-1)
2786 * ADV_DVC_VAR 'warn_code' values
2788 #define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
2789 #define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
2790 #define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
2791 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */
2792 #define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
2794 #define ADV_MAX_TID 15 /* max. target identifier */
2795 #define ADV_MAX_LUN 7 /* max. logical unit number */
2798 * Error code values are set in ADV_DVC_VAR 'err_code'.
2800 #define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */
2801 #define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
2802 #define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */
2803 #define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
2804 #define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */
2805 #define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
2806 #define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */
2807 #define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
2808 #define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
2809 #define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */
2810 #define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */
2811 #define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */
2812 #define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */
2813 #define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */
2816 * Fixed locations of microcode operating variables.
2818 #define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
2819 #define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
2820 #define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
2821 #define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
2822 #define ASC_MC_VERSION_NUM 0x003A /* microcode number */
2823 #define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
2824 #define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
2825 #define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
2826 #define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
2827 #define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
2828 #define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
2829 #define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
2830 #define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
2831 #define ASC_MC_CHIP_TYPE 0x009A
2832 #define ASC_MC_INTRB_CODE 0x009B
2833 #define ASC_MC_WDTR_ABLE 0x009C
2834 #define ASC_MC_SDTR_ABLE 0x009E
2835 #define ASC_MC_TAGQNG_ABLE 0x00A0
2836 #define ASC_MC_DISC_ENABLE 0x00A2
2837 #define ASC_MC_IDLE_CMD_STATUS 0x00A4
2838 #define ASC_MC_IDLE_CMD 0x00A6
2839 #define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
2840 #define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
2841 #define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
2842 #define ASC_MC_DEFAULT_MEM_CFG 0x00B0
2843 #define ASC_MC_DEFAULT_SEL_MASK 0x00B2
2844 #define ASC_MC_SDTR_DONE 0x00B6
2845 #define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
2846 #define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
2847 #define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
2848 #define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
2849 #define ASC_MC_WDTR_DONE 0x0124
2850 #define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
2851 #define ASC_MC_ICQ 0x0160
2852 #define ASC_MC_IRQ 0x0164
2853 #define ASC_MC_PPR_ABLE 0x017A
2856 * BIOS LRAM variable absolute offsets.
2858 #define BIOS_CODESEG 0x54
2859 #define BIOS_CODELEN 0x56
2860 #define BIOS_SIGNATURE 0x58
2861 #define BIOS_VERSION 0x5A
2864 * Microcode Control Flags
2866 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2867 * and handled by the microcode.
2869 #define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
2870 #define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
2873 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2875 #define HSHK_CFG_WIDE_XFR 0x8000
2876 #define HSHK_CFG_RATE 0x0F00
2877 #define HSHK_CFG_OFFSET 0x001F
2879 #define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
2880 #define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
2881 #define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
2882 #define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
2884 #define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2885 #define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
2886 #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2887 #define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
2888 #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2890 #define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
2891 #define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
2892 #define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
2893 #define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
2894 #define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
2896 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
2897 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
2899 #define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
2900 #define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
2903 * All fields here are accessed by the board microcode and need to be
2904 * little-endian.
2906 typedef struct adv_carr_t
2908 ADV_VADDR carr_va; /* Carrier Virtual Address */
2909 ADV_PADDR carr_pa; /* Carrier Physical Address */
2910 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
2912 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
2914 * next_vpa [3:1] Reserved Bits
2915 * next_vpa [0] Done Flag set in Response Queue.
2917 ADV_VADDR next_vpa;
2918 } ADV_CARR_T;
2921 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2923 #define ASC_NEXT_VPA_MASK 0xFFFFFFF0
2925 #define ASC_RQ_DONE 0x00000001
2926 #define ASC_RQ_GOOD 0x00000002
2927 #define ASC_CQ_STOPPER 0x00000000
2929 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2931 #define ADV_CARRIER_NUM_PAGE_CROSSING \
2932 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2933 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2935 #define ADV_CARRIER_BUFSIZE \
2936 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2939 * ASC_SCSI_REQ_Q 'a_flag' definitions
2941 * The Adv Library should limit use to the lower nibble (4 bits) of
2942 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2944 #define ADV_POLL_REQUEST 0x01 /* poll for request completion */
2945 #define ADV_SCSIQ_DONE 0x02 /* request done */
2946 #define ADV_DONT_RETRY 0x08 /* don't do retry */
2948 #define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
2949 #define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
2950 #define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
2953 * Adapter temporary configuration structure
2955 * This structure can be discarded after initialization. Don't add
2956 * fields here needed after initialization.
2958 * Field naming convention:
2960 * *_enable indicates the field enables or disables a feature. The
2961 * value of the field is never reset.
2963 typedef struct adv_dvc_cfg {
2964 ushort disc_enable; /* enable disconnection */
2965 uchar chip_version; /* chip version */
2966 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2967 ushort lib_version; /* Adv Library version number */
2968 ushort control_flag; /* Microcode Control Flag */
2969 ushort mcode_date; /* Microcode date */
2970 ushort mcode_version; /* Microcode version */
2971 ushort pci_slot_info; /* high byte device/function number */
2972 /* bits 7-3 device num., bits 2-0 function num. */
2973 /* low byte bus num. */
2974 ushort serial1; /* EEPROM serial number word 1 */
2975 ushort serial2; /* EEPROM serial number word 2 */
2976 ushort serial3; /* EEPROM serial number word 3 */
2977 struct device *dev; /* pointer to the pci dev structure for this board */
2978 } ADV_DVC_CFG;
2980 struct adv_dvc_var;
2981 struct adv_scsi_req_q;
2983 typedef void (* ADV_ISR_CALLBACK)
2984 (struct adv_dvc_var *, struct adv_scsi_req_q *);
2986 typedef void (* ADV_ASYNC_CALLBACK)
2987 (struct adv_dvc_var *, uchar);
2990 * Adapter operation variable structure.
2992 * One structure is required per host adapter.
2994 * Field naming convention:
2996 * *_able indicates both whether a feature should be enabled or disabled
2997 * and whether a device isi capable of the feature. At initialization
2998 * this field may be set, but later if a device is found to be incapable
2999 * of the feature, the field is cleared.
3001 typedef struct adv_dvc_var {
3002 AdvPortAddr iop_base; /* I/O port address */
3003 ushort err_code; /* fatal error code */
3004 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
3005 ADV_ISR_CALLBACK isr_callback;
3006 ADV_ASYNC_CALLBACK async_callback;
3007 ushort wdtr_able; /* try WDTR for a device */
3008 ushort sdtr_able; /* try SDTR for a device */
3009 ushort ultra_able; /* try SDTR Ultra speed for a device */
3010 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
3011 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
3012 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
3013 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
3014 ushort tagqng_able; /* try tagged queuing with a device */
3015 ushort ppr_able; /* PPR message capable per TID bitmask. */
3016 uchar max_dvc_qng; /* maximum number of tagged commands per device */
3017 ushort start_motor; /* start motor command allowed */
3018 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
3019 uchar chip_no; /* should be assigned by caller */
3020 uchar max_host_qng; /* maximum number of Q'ed command allowed */
3021 uchar irq_no; /* IRQ number */
3022 ushort no_scam; /* scam_tolerant of EEPROM */
3023 struct asc_board *drv_ptr; /* driver pointer to private structure */
3024 uchar chip_scsi_id; /* chip SCSI target ID */
3025 uchar chip_type;
3026 uchar bist_err_code;
3027 ADV_CARR_T *carrier_buf;
3028 ADV_CARR_T *carr_freelist; /* Carrier free list. */
3029 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
3030 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
3031 ushort carr_pending_cnt; /* Count of pending carriers. */
3033 * Note: The following fields will not be used after initialization. The
3034 * driver may discard the buffer after initialization is done.
3036 ADV_DVC_CFG *cfg; /* temporary configuration structure */
3037 } ADV_DVC_VAR;
3039 #define NO_OF_SG_PER_BLOCK 15
3041 typedef struct asc_sg_block {
3042 uchar reserved1;
3043 uchar reserved2;
3044 uchar reserved3;
3045 uchar sg_cnt; /* Valid entries in block. */
3046 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
3047 struct {
3048 ADV_PADDR sg_addr; /* SG element address. */
3049 ADV_DCNT sg_count; /* SG element count. */
3050 } sg_list[NO_OF_SG_PER_BLOCK];
3051 } ADV_SG_BLOCK;
3054 * ADV_SCSI_REQ_Q - microcode request structure
3056 * All fields in this structure up to byte 60 are used by the microcode.
3057 * The microcode makes assumptions about the size and ordering of fields
3058 * in this structure. Do not change the structure definition here without
3059 * coordinating the change with the microcode.
3061 * All fields accessed by microcode must be maintained in little_endian
3062 * order.
3064 typedef struct adv_scsi_req_q {
3065 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
3066 uchar target_cmd;
3067 uchar target_id; /* Device target identifier. */
3068 uchar target_lun; /* Device target logical unit number. */
3069 ADV_PADDR data_addr; /* Data buffer physical address. */
3070 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
3071 ADV_PADDR sense_addr;
3072 ADV_PADDR carr_pa;
3073 uchar mflag;
3074 uchar sense_len;
3075 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
3076 uchar scsi_cntl;
3077 uchar done_status; /* Completion status. */
3078 uchar scsi_status; /* SCSI status byte. */
3079 uchar host_status; /* Ucode host status. */
3080 uchar sg_working_ix;
3081 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
3082 ADV_PADDR sg_real_addr; /* SG list physical address. */
3083 ADV_PADDR scsiq_rptr;
3084 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
3085 ADV_VADDR scsiq_ptr;
3086 ADV_VADDR carr_va;
3088 * End of microcode structure - 60 bytes. The rest of the structure
3089 * is used by the Adv Library and ignored by the microcode.
3091 ADV_VADDR srb_ptr;
3092 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
3093 char *vdata_addr; /* Data buffer virtual address. */
3094 uchar a_flag;
3095 uchar pad[2]; /* Pad out to a word boundary. */
3096 } ADV_SCSI_REQ_Q;
3099 * Microcode idle loop commands
3101 #define IDLE_CMD_COMPLETED 0
3102 #define IDLE_CMD_STOP_CHIP 0x0001
3103 #define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
3104 #define IDLE_CMD_SEND_INT 0x0004
3105 #define IDLE_CMD_ABORT 0x0008
3106 #define IDLE_CMD_DEVICE_RESET 0x0010
3107 #define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
3108 #define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
3109 #define IDLE_CMD_SCSIREQ 0x0080
3111 #define IDLE_CMD_STATUS_SUCCESS 0x0001
3112 #define IDLE_CMD_STATUS_FAILURE 0x0002
3115 * AdvSendIdleCmd() flag definitions.
3117 #define ADV_NOWAIT 0x01
3120 * Wait loop time out values.
3122 #define SCSI_WAIT_10_SEC 10UL /* 10 seconds */
3123 #define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
3124 #define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
3125 #define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */
3126 #define SCSI_MAX_RETRY 10 /* retry count */
3128 #define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
3129 #define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
3130 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
3131 #define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
3134 #define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
3137 * Device drivers must define the following functions.
3139 STATIC inline ulong DvcEnterCritical(void);
3140 STATIC inline void DvcLeaveCritical(ulong);
3141 STATIC void DvcSleepMilliSecond(ADV_DCNT);
3142 STATIC uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
3143 STATIC void DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
3144 STATIC ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
3145 uchar *, ASC_SDCNT *, int);
3146 STATIC void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
3149 * Adv Library functions available to drivers.
3151 STATIC int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3152 STATIC int AdvISR(ADV_DVC_VAR *);
3153 STATIC int AdvInitGetConfig(ADV_DVC_VAR *);
3154 STATIC int AdvInitAsc3550Driver(ADV_DVC_VAR *);
3155 STATIC int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
3156 STATIC int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
3157 STATIC int AdvResetChipAndSB(ADV_DVC_VAR *);
3158 STATIC int AdvResetSB(ADV_DVC_VAR *asc_dvc);
3161 * Internal Adv Library functions.
3163 STATIC int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
3164 STATIC void AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3165 STATIC int AdvInitFrom3550EEP(ADV_DVC_VAR *);
3166 STATIC int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
3167 STATIC int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
3168 STATIC ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3169 STATIC void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3170 STATIC ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3171 STATIC void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3172 STATIC ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3173 STATIC void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3174 STATIC void AdvWaitEEPCmd(AdvPortAddr);
3175 STATIC ushort AdvReadEEPWord(AdvPortAddr, int);
3178 * PCI Bus Definitions
3180 #define AscPCICmdRegBits_BusMastering 0x0007
3181 #define AscPCICmdRegBits_ParErrRespCtrl 0x0040
3183 /* Read byte from a register. */
3184 #define AdvReadByteRegister(iop_base, reg_off) \
3185 (ADV_MEM_READB((iop_base) + (reg_off)))
3187 /* Write byte to a register. */
3188 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
3189 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3191 /* Read word (2 bytes) from a register. */
3192 #define AdvReadWordRegister(iop_base, reg_off) \
3193 (ADV_MEM_READW((iop_base) + (reg_off)))
3195 /* Write word (2 bytes) to a register. */
3196 #define AdvWriteWordRegister(iop_base, reg_off, word) \
3197 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
3199 /* Write dword (4 bytes) to a register. */
3200 #define AdvWriteDWordRegister(iop_base, reg_off, dword) \
3201 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
3203 /* Read byte from LRAM. */
3204 #define AdvReadByteLram(iop_base, addr, byte) \
3205 do { \
3206 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3207 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3208 } while (0)
3210 /* Write byte to LRAM. */
3211 #define AdvWriteByteLram(iop_base, addr, byte) \
3212 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3213 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3215 /* Read word (2 bytes) from LRAM. */
3216 #define AdvReadWordLram(iop_base, addr, word) \
3217 do { \
3218 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3219 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3220 } while (0)
3222 /* Write word (2 bytes) to LRAM. */
3223 #define AdvWriteWordLram(iop_base, addr, word) \
3224 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3225 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3227 /* Write little-endian double word (4 bytes) to LRAM */
3228 /* Because of unspecified C language ordering don't use auto-increment. */
3229 #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
3230 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3231 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3232 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3233 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3234 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3235 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3237 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
3238 #define AdvReadWordAutoIncLram(iop_base) \
3239 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3241 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
3242 #define AdvWriteWordAutoIncLram(iop_base, word) \
3243 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3247 * Define macro to check for Condor signature.
3249 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3250 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3252 #define AdvFindSignature(iop_base) \
3253 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3254 ADV_CHIP_ID_BYTE) && \
3255 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3256 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
3259 * Define macro to Return the version number of the chip at 'iop_base'.
3261 * The second parameter 'bus_type' is currently unused.
3263 #define AdvGetChipVersion(iop_base, bus_type) \
3264 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3267 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3268 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3270 * If the request has not yet been sent to the device it will simply be
3271 * aborted from RISC memory. If the request is disconnected it will be
3272 * aborted on reselection by sending an Abort Message to the target ID.
3274 * Return value:
3275 * ADV_TRUE(1) - Queue was successfully aborted.
3276 * ADV_FALSE(0) - Queue was not found on the active queue list.
3278 #define AdvAbortQueue(asc_dvc, scsiq) \
3279 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3280 (ADV_DCNT) (scsiq))
3283 * Send a Bus Device Reset Message to the specified target ID.
3285 * All outstanding commands will be purged if sending the
3286 * Bus Device Reset Message is successful.
3288 * Return Value:
3289 * ADV_TRUE(1) - All requests on the target are purged.
3290 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3291 * are not purged.
3293 #define AdvResetDevice(asc_dvc, target_id) \
3294 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3295 (ADV_DCNT) (target_id))
3298 * SCSI Wide Type definition.
3300 #define ADV_SCSI_BIT_ID_TYPE ushort
3303 * AdvInitScsiTarget() 'cntl_flag' options.
3305 #define ADV_SCAN_LUN 0x01
3306 #define ADV_CAPINFO_NOLUN 0x02
3309 * Convert target id to target id bit mask.
3311 #define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
3314 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3317 #define QD_NO_STATUS 0x00 /* Request not completed yet. */
3318 #define QD_NO_ERROR 0x01
3319 #define QD_ABORTED_BY_HOST 0x02
3320 #define QD_WITH_ERROR 0x04
3322 #define QHSTA_NO_ERROR 0x00
3323 #define QHSTA_M_SEL_TIMEOUT 0x11
3324 #define QHSTA_M_DATA_OVER_RUN 0x12
3325 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3326 #define QHSTA_M_QUEUE_ABORTED 0x15
3327 #define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
3328 #define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
3329 #define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
3330 #define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
3331 #define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
3332 #define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
3333 #define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
3334 /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
3335 #define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
3336 #define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
3337 #define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
3338 #define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
3339 #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
3340 #define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
3341 #define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
3342 #define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
3343 #define QHSTA_M_WTM_TIMEOUT 0x41
3344 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
3345 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
3346 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
3347 #define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
3348 #define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
3349 #define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
3353 * Default EEPROM Configuration structure defined in a_init.c.
3355 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
3356 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
3357 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
3360 * DvcGetPhyAddr() flag arguments
3362 #define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
3363 #define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
3364 #define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
3365 #define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
3366 #define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
3367 #define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
3369 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
3370 #define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
3371 #define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
3372 #define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
3375 * Total contiguous memory needed for driver SG blocks.
3377 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3378 * number of scatter-gather elements the driver supports in a
3379 * single request.
3382 #define ADV_SG_LIST_MAX_BYTE_SIZE \
3383 (sizeof(ADV_SG_BLOCK) * \
3384 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3387 * Inquiry data structure and bitfield macros
3389 * Using bitfields to access the subchar data isn't portable across
3390 * endianness, so instead mask and shift. Only quantities of more
3391 * than 1 bit are shifted, since the others are just tested for true
3392 * or false.
3395 #define ADV_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f)
3396 #define ADV_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5)
3397 #define ADV_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f)
3398 #define ADV_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80)
3399 #define ADV_INQ_ANSI_VER(inq) ((inq)->ver & 0x07)
3400 #define ADV_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3)
3401 #define ADV_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6)
3402 #define ADV_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f)
3403 #define ADV_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40)
3404 #define ADV_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80)
3405 #define ADV_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01)
3406 #define ADV_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02)
3407 #define ADV_INQ_LINK_CMD(inq) ((inq)->flags & 0x08)
3408 #define ADV_INQ_SYNC(inq) ((inq)->flags & 0x10)
3409 #define ADV_INQ_WIDE16(inq) ((inq)->flags & 0x20)
3410 #define ADV_INQ_WIDE32(inq) ((inq)->flags & 0x40)
3411 #define ADV_INQ_REL_ADDR(inq) ((inq)->flags & 0x80)
3412 #define ADV_INQ_INFO_UNIT(inq) ((inq)->info & 0x01)
3413 #define ADV_INQ_QUICK_ARB(inq) ((inq)->info & 0x02)
3414 #define ADV_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2)
3416 typedef struct {
3417 uchar periph; /* peripheral device type [0:4] */
3418 /* peripheral qualifier [5:7] */
3419 uchar devtype; /* device type modifier (for SCSI I) [0:6] */
3420 /* RMB - removable medium bit [7] */
3421 uchar ver; /* ANSI approved version [0:2] */
3422 /* ECMA version [3:5] */
3423 /* ISO version [6:7] */
3424 uchar byte3; /* response data format [0:3] */
3425 /* 0 SCSI 1 */
3426 /* 1 CCS */
3427 /* 2 SCSI-2 */
3428 /* 3-F reserved */
3429 /* reserved [4:5] */
3430 /* terminate I/O process bit (see 5.6.22) [6] */
3431 /* asynch. event notification (processor) [7] */
3432 uchar add_len; /* additional length */
3433 uchar res1; /* reserved */
3434 uchar res2; /* reserved */
3435 uchar flags; /* soft reset implemented [0] */
3436 /* command queuing [1] */
3437 /* reserved [2] */
3438 /* linked command for this logical unit [3] */
3439 /* synchronous data transfer [4] */
3440 /* wide bus 16 bit data transfer [5] */
3441 /* wide bus 32 bit data transfer [6] */
3442 /* relative addressing mode [7] */
3443 uchar vendor_id[8]; /* vendor identification */
3444 uchar product_id[16]; /* product identification */
3445 uchar product_rev_level[4]; /* product revision level */
3446 uchar vendor_specific[20]; /* vendor specific */
3447 uchar info; /* information unit supported [0] */
3448 /* quick arbitrate supported [1] */
3449 /* clocking field [2:3] */
3450 /* reserved [4:7] */
3451 uchar res3; /* reserved */
3452 } ADV_SCSI_INQUIRY; /* 58 bytes */
3456 * --- Driver Constants and Macros
3459 #define ASC_NUM_BOARD_SUPPORTED 16
3460 #define ASC_NUM_IOPORT_PROBE 4
3461 #define ASC_NUM_BUS 4
3463 /* Reference Scsi_Host hostdata */
3464 #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3466 /* asc_board_t flags */
3467 #define ASC_HOST_IN_RESET 0x01
3468 #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
3469 #define ASC_SELECT_QUEUE_DEPTHS 0x08
3471 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3472 #define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD)
3474 #define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
3476 #define ASC_INFO_SIZE 128 /* advansys_info() line size */
3478 #ifdef CONFIG_PROC_FS
3479 /* /proc/scsi/advansys/[0...] related definitions */
3480 #define ASC_PRTBUF_SIZE 2048
3481 #define ASC_PRTLINE_SIZE 160
3483 #define ASC_PRT_NEXT() \
3484 if (cp) { \
3485 totlen += len; \
3486 leftlen -= len; \
3487 if (leftlen == 0) { \
3488 return totlen; \
3490 cp += len; \
3492 #endif /* CONFIG_PROC_FS */
3494 /* Asc Library return codes */
3495 #define ASC_TRUE 1
3496 #define ASC_FALSE 0
3497 #define ASC_NOERROR 1
3498 #define ASC_BUSY 0
3499 #define ASC_ERROR (-1)
3501 /* struct scsi_cmnd function return codes */
3502 #define STATUS_BYTE(byte) (byte)
3503 #define MSG_BYTE(byte) ((byte) << 8)
3504 #define HOST_BYTE(byte) ((byte) << 16)
3505 #define DRIVER_BYTE(byte) ((byte) << 24)
3508 * The following definitions and macros are OS independent interfaces to
3509 * the queue functions:
3510 * REQ - SCSI request structure
3511 * REQP - pointer to SCSI request structure
3512 * REQPTID(reqp) - reqp's target id
3513 * REQPNEXT(reqp) - reqp's next pointer
3514 * REQPNEXTP(reqp) - pointer to reqp's next pointer
3515 * REQPTIME(reqp) - reqp's time stamp value
3516 * REQTIMESTAMP() - system time stamp value
3518 typedef struct scsi_cmnd REQ, *REQP;
3519 #define REQPNEXT(reqp) ((REQP) ((reqp)->host_scribble))
3520 #define REQPNEXTP(reqp) ((REQP *) &((reqp)->host_scribble))
3521 #define REQPTID(reqp) ((reqp)->device->id)
3522 #define REQPTIME(reqp) ((reqp)->SCp.this_residual)
3523 #define REQTIMESTAMP() (jiffies)
3525 #define REQTIMESTAT(function, ascq, reqp, tid) \
3528 * If the request time stamp is less than the system time stamp, then \
3529 * maybe the system time stamp wrapped. Set the request time to zero.\
3530 */ \
3531 if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3532 REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3533 } else { \
3534 /* Indicate an error occurred with the assertion. */ \
3535 ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3536 REQPTIME(reqp) = 0; \
3538 /* Handle first minimum time case without external initialization. */ \
3539 if (((ascq)->q_tot_cnt[tid] == 1) || \
3540 (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3541 (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3542 ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3543 (function), (tid), (ascq)->q_min_tim[tid]); \
3545 if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3546 (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3547 ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3548 (function), tid, (ascq)->q_max_tim[tid]); \
3550 (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3551 /* Reset the time stamp field. */ \
3552 REQPTIME(reqp) = 0; \
3555 /* asc_enqueue() flags */
3556 #define ASC_FRONT 1
3557 #define ASC_BACK 2
3559 /* asc_dequeue_list() argument */
3560 #define ASC_TID_ALL (-1)
3562 /* Return non-zero, if the queue is empty. */
3563 #define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0)
3565 #define PCI_MAX_SLOT 0x1F
3566 #define PCI_MAX_BUS 0xFF
3567 #define PCI_IOADDRESS_MASK 0xFFFE
3568 #define ASC_PCI_DEVICE_ID_CNT 6 /* PCI Device ID count. */
3570 #ifndef ADVANSYS_STATS
3571 #define ASC_STATS(shp, counter)
3572 #define ASC_STATS_ADD(shp, counter, count)
3573 #else /* ADVANSYS_STATS */
3574 #define ASC_STATS(shp, counter) \
3575 (ASC_BOARDP(shp)->asc_stats.counter++)
3577 #define ASC_STATS_ADD(shp, counter, count) \
3578 (ASC_BOARDP(shp)->asc_stats.counter += (count))
3579 #endif /* ADVANSYS_STATS */
3581 #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3583 /* If the result wraps when calculating tenths, return 0. */
3584 #define ASC_TENTHS(num, den) \
3585 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3586 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3589 * Display a message to the console.
3591 #define ASC_PRINT(s) \
3593 printk("advansys: "); \
3594 printk(s); \
3597 #define ASC_PRINT1(s, a1) \
3599 printk("advansys: "); \
3600 printk((s), (a1)); \
3603 #define ASC_PRINT2(s, a1, a2) \
3605 printk("advansys: "); \
3606 printk((s), (a1), (a2)); \
3609 #define ASC_PRINT3(s, a1, a2, a3) \
3611 printk("advansys: "); \
3612 printk((s), (a1), (a2), (a3)); \
3615 #define ASC_PRINT4(s, a1, a2, a3, a4) \
3617 printk("advansys: "); \
3618 printk((s), (a1), (a2), (a3), (a4)); \
3622 #ifndef ADVANSYS_DEBUG
3624 #define ASC_DBG(lvl, s)
3625 #define ASC_DBG1(lvl, s, a1)
3626 #define ASC_DBG2(lvl, s, a1, a2)
3627 #define ASC_DBG3(lvl, s, a1, a2, a3)
3628 #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3629 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3630 #define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3631 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3632 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3633 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3634 #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3635 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
3636 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
3637 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
3638 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3640 #else /* ADVANSYS_DEBUG */
3643 * Debugging Message Levels:
3644 * 0: Errors Only
3645 * 1: High-Level Tracing
3646 * 2-N: Verbose Tracing
3649 #define ASC_DBG(lvl, s) \
3651 if (asc_dbglvl >= (lvl)) { \
3652 printk(s); \
3656 #define ASC_DBG1(lvl, s, a1) \
3658 if (asc_dbglvl >= (lvl)) { \
3659 printk((s), (a1)); \
3663 #define ASC_DBG2(lvl, s, a1, a2) \
3665 if (asc_dbglvl >= (lvl)) { \
3666 printk((s), (a1), (a2)); \
3670 #define ASC_DBG3(lvl, s, a1, a2, a3) \
3672 if (asc_dbglvl >= (lvl)) { \
3673 printk((s), (a1), (a2), (a3)); \
3677 #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3679 if (asc_dbglvl >= (lvl)) { \
3680 printk((s), (a1), (a2), (a3), (a4)); \
3684 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3686 if (asc_dbglvl >= (lvl)) { \
3687 asc_prt_scsi_host(s); \
3691 #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3693 if (asc_dbglvl >= (lvl)) { \
3694 asc_prt_scsi_cmnd(s); \
3698 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3700 if (asc_dbglvl >= (lvl)) { \
3701 asc_prt_asc_scsi_q(scsiqp); \
3705 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3707 if (asc_dbglvl >= (lvl)) { \
3708 asc_prt_asc_qdone_info(qdone); \
3712 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3714 if (asc_dbglvl >= (lvl)) { \
3715 asc_prt_adv_scsi_req_q(scsiqp); \
3719 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3721 if (asc_dbglvl >= (lvl)) { \
3722 asc_prt_hex((name), (start), (length)); \
3726 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3727 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3729 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3730 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3732 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3733 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3734 #endif /* ADVANSYS_DEBUG */
3736 #ifndef ADVANSYS_ASSERT
3737 #define ASC_ASSERT(a)
3738 #else /* ADVANSYS_ASSERT */
3740 #define ASC_ASSERT(a) \
3742 if (!(a)) { \
3743 printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3744 __FILE__, __LINE__); \
3748 #endif /* ADVANSYS_ASSERT */
3752 * --- Driver Structures
3755 #ifdef ADVANSYS_STATS
3757 /* Per board statistics structure */
3758 struct asc_stats {
3759 /* Driver Entrypoint Statistics */
3760 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
3761 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
3762 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
3763 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
3764 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
3765 ADV_DCNT done; /* # calls to request's scsi_done function */
3766 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
3767 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
3768 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
3769 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3770 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
3771 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
3772 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
3773 ADV_DCNT exe_unknown; /* # unknown returns. */
3774 /* Data Transfer Statistics */
3775 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
3776 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
3777 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
3778 ADV_DCNT sg_elem; /* # scatter-gather elements */
3779 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
3781 #endif /* ADVANSYS_STATS */
3784 * Request queuing structure
3786 typedef struct asc_queue {
3787 ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */
3788 REQP q_first[ADV_MAX_TID+1]; /* first queued request */
3789 REQP q_last[ADV_MAX_TID+1]; /* last queued request */
3790 #ifdef ADVANSYS_STATS
3791 short q_cur_cnt[ADV_MAX_TID+1]; /* current queue count */
3792 short q_max_cnt[ADV_MAX_TID+1]; /* maximum queue count */
3793 ADV_DCNT q_tot_cnt[ADV_MAX_TID+1]; /* total enqueue count */
3794 ADV_DCNT q_tot_tim[ADV_MAX_TID+1]; /* total time queued */
3795 ushort q_max_tim[ADV_MAX_TID+1]; /* maximum time queued */
3796 ushort q_min_tim[ADV_MAX_TID+1]; /* minimum time queued */
3797 #endif /* ADVANSYS_STATS */
3798 } asc_queue_t;
3801 * Adv Library Request Structures
3803 * The following two structures are used to process Wide Board requests.
3805 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
3806 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
3807 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
3808 * Mid-Level SCSI request structure.
3810 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
3811 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
3812 * up to 255 scatter-gather elements may be used per request or
3813 * ADV_SCSI_REQ_Q.
3815 * Both structures must be 32 byte aligned.
3817 typedef struct adv_sgblk {
3818 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
3819 uchar align[32]; /* Sgblock structure padding. */
3820 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
3821 } adv_sgblk_t;
3823 typedef struct adv_req {
3824 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
3825 uchar align[32]; /* Request structure padding. */
3826 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
3827 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
3828 struct adv_req *next_reqp; /* Next Request Structure. */
3829 } adv_req_t;
3832 * Structure allocated for each board.
3834 * This structure is allocated by scsi_register() at the end
3835 * of the 'Scsi_Host' structure starting at the 'hostdata'
3836 * field. It is guaranteed to be allocated from DMA-able memory.
3838 typedef struct asc_board {
3839 int id; /* Board Id */
3840 uint flags; /* Board flags */
3841 union {
3842 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
3843 ADV_DVC_VAR adv_dvc_var; /* Wide board */
3844 } dvc_var;
3845 union {
3846 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
3847 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
3848 } dvc_cfg;
3849 ushort asc_n_io_port; /* Number I/O ports. */
3850 asc_queue_t active; /* Active command queue */
3851 asc_queue_t waiting; /* Waiting command queue */
3852 asc_queue_t done; /* Done command queue */
3853 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
3854 struct scsi_device *device[ADV_MAX_TID+1]; /* Mid-Level Scsi Device */
3855 ushort reqcnt[ADV_MAX_TID+1]; /* Starvation request count */
3856 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
3857 ushort queue_full_cnt[ADV_MAX_TID+1]; /* Queue full count */
3858 union {
3859 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
3860 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
3861 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
3862 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
3863 } eep_config;
3864 ulong last_reset; /* Saved last reset time */
3865 spinlock_t lock; /* Board spinlock */
3866 #ifdef CONFIG_PROC_FS
3867 /* /proc/scsi/advansys/[0...] */
3868 char *prtbuf; /* /proc print buffer */
3869 #endif /* CONFIG_PROC_FS */
3870 #ifdef ADVANSYS_STATS
3871 struct asc_stats asc_stats; /* Board statistics */
3872 #endif /* ADVANSYS_STATS */
3874 * The following fields are used only for Narrow Boards.
3876 /* The following three structures must be in DMA-able memory. */
3877 ASC_SCSI_REQ_Q scsireqq;
3878 ASC_CAP_INFO cap_info;
3879 ASC_SCSI_INQUIRY inquiry;
3880 uchar sdtr_data[ASC_MAX_TID+1]; /* SDTR information */
3882 * The following fields are used only for Wide Boards.
3884 void __iomem *ioremap_addr; /* I/O Memory remap address. */
3885 ushort ioport; /* I/O Port address. */
3886 ADV_CARR_T *orig_carrp; /* ADV_CARR_T memory block. */
3887 adv_req_t *orig_reqp; /* adv_req_t memory block. */
3888 adv_req_t *adv_reqp; /* Request structures. */
3889 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
3890 ushort bios_signature; /* BIOS Signature. */
3891 ushort bios_version; /* BIOS Version. */
3892 ushort bios_codeseg; /* BIOS Code Segment. */
3893 ushort bios_codelen; /* BIOS Code Segment Length. */
3894 } asc_board_t;
3897 * PCI configuration structures
3899 typedef struct _PCI_DATA_
3901 uchar type;
3902 uchar bus;
3903 uchar slot;
3904 uchar func;
3905 uchar offset;
3906 } PCI_DATA;
3908 typedef struct _PCI_DEVICE_
3910 ushort vendorID;
3911 ushort deviceID;
3912 ushort slotNumber;
3913 ushort slotFound;
3914 uchar busNumber;
3915 uchar maxBusNumber;
3916 uchar devFunc;
3917 ushort startSlot;
3918 ushort endSlot;
3919 uchar bridge;
3920 uchar type;
3921 } PCI_DEVICE;
3923 typedef struct _PCI_CONFIG_SPACE_
3925 ushort vendorID;
3926 ushort deviceID;
3927 ushort command;
3928 ushort status;
3929 uchar revision;
3930 uchar classCode[3];
3931 uchar cacheSize;
3932 uchar latencyTimer;
3933 uchar headerType;
3934 uchar bist;
3935 ADV_PADDR baseAddress[6];
3936 ushort reserved[4];
3937 ADV_PADDR optionRomAddr;
3938 ushort reserved2[4];
3939 uchar irqLine;
3940 uchar irqPin;
3941 uchar minGnt;
3942 uchar maxLatency;
3943 } PCI_CONFIG_SPACE;
3947 * --- Driver Data
3950 /* Note: All driver global data should be initialized. */
3952 /* Number of boards detected in system. */
3953 STATIC int asc_board_count = 0;
3954 STATIC struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { NULL };
3956 /* Overrun buffer used by all narrow boards. */
3957 STATIC uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
3960 * Global structures required to issue a command.
3962 STATIC ASC_SCSI_Q asc_scsi_q = { { 0 } };
3963 STATIC ASC_SG_HEAD asc_sg_head = { 0 };
3965 /* List of supported bus types. */
3966 STATIC ushort asc_bus[ASC_NUM_BUS] __initdata = {
3967 ASC_IS_ISA,
3968 ASC_IS_VL,
3969 ASC_IS_EISA,
3970 ASC_IS_PCI,
3974 * Used with the LILO 'advansys' option to eliminate or
3975 * limit I/O port probing at boot time, cf. advansys_setup().
3977 STATIC int asc_iopflag = ASC_FALSE;
3978 STATIC int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
3980 #ifdef ADVANSYS_DEBUG
3981 STATIC char *
3982 asc_bus_name[ASC_NUM_BUS] = {
3983 "ASC_IS_ISA",
3984 "ASC_IS_VL",
3985 "ASC_IS_EISA",
3986 "ASC_IS_PCI",
3989 STATIC int asc_dbglvl = 3;
3990 #endif /* ADVANSYS_DEBUG */
3992 /* Declaration for Asc Library internal data referenced by driver. */
3993 STATIC PortAddr _asc_def_iop_base[];
3997 * --- Driver Function Prototypes
3999 * advansys.h contains function prototypes for functions global to Linux.
4002 STATIC irqreturn_t advansys_interrupt(int, void *);
4003 STATIC int advansys_slave_configure(struct scsi_device *);
4004 STATIC void asc_scsi_done_list(struct scsi_cmnd *);
4005 STATIC int asc_execute_scsi_cmnd(struct scsi_cmnd *);
4006 STATIC int asc_build_req(asc_board_t *, struct scsi_cmnd *);
4007 STATIC int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
4008 STATIC int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
4009 STATIC void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
4010 STATIC void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
4011 STATIC void adv_async_callback(ADV_DVC_VAR *, uchar);
4012 STATIC void asc_enqueue(asc_queue_t *, REQP, int);
4013 STATIC REQP asc_dequeue(asc_queue_t *, int);
4014 STATIC REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
4015 STATIC int asc_rmqueue(asc_queue_t *, REQP);
4016 STATIC void asc_execute_queue(asc_queue_t *);
4017 #ifdef CONFIG_PROC_FS
4018 STATIC int asc_proc_copy(off_t, off_t, char *, int , char *, int);
4019 STATIC int asc_prt_board_devices(struct Scsi_Host *, char *, int);
4020 STATIC int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
4021 STATIC int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
4022 STATIC int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
4023 STATIC int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
4024 STATIC int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
4025 STATIC int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
4026 STATIC int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
4027 STATIC int asc_prt_line(char *, int, char *fmt, ...);
4028 #endif /* CONFIG_PROC_FS */
4030 /* Declaration for Asc Library internal functions referenced by driver. */
4031 STATIC int AscFindSignature(PortAddr);
4032 STATIC ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
4034 /* Statistics function prototypes. */
4035 #ifdef ADVANSYS_STATS
4036 #ifdef CONFIG_PROC_FS
4037 STATIC int asc_prt_board_stats(struct Scsi_Host *, char *, int);
4038 STATIC int asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
4039 #endif /* CONFIG_PROC_FS */
4040 #endif /* ADVANSYS_STATS */
4042 /* Debug function prototypes. */
4043 #ifdef ADVANSYS_DEBUG
4044 STATIC void asc_prt_scsi_host(struct Scsi_Host *);
4045 STATIC void asc_prt_scsi_cmnd(struct scsi_cmnd *);
4046 STATIC void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
4047 STATIC void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
4048 STATIC void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
4049 STATIC void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
4050 STATIC void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
4051 STATIC void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
4052 STATIC void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
4053 STATIC void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
4054 STATIC void asc_prt_hex(char *f, uchar *, int);
4055 #endif /* ADVANSYS_DEBUG */
4059 * --- Linux 'struct scsi_host_template' and advansys_setup() Functions
4062 #ifdef CONFIG_PROC_FS
4064 * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
4066 * *buffer: I/O buffer
4067 * **start: if inout == FALSE pointer into buffer where user read should start
4068 * offset: current offset into a /proc/scsi/advansys/[0...] file
4069 * length: length of buffer
4070 * hostno: Scsi_Host host_no
4071 * inout: TRUE - user is writing; FALSE - user is reading
4073 * Return the number of bytes read from or written to a
4074 * /proc/scsi/advansys/[0...] file.
4076 * Note: This function uses the per board buffer 'prtbuf' which is
4077 * allocated when the board is initialized in advansys_detect(). The
4078 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
4079 * used to write to the buffer. The way asc_proc_copy() is written
4080 * if 'prtbuf' is too small it will not be overwritten. Instead the
4081 * user just won't get all the available statistics.
4084 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
4085 off_t offset, int length, int inout)
4087 struct Scsi_Host *shp;
4088 asc_board_t *boardp;
4089 int i;
4090 char *cp;
4091 int cplen;
4092 int cnt;
4093 int totcnt;
4094 int leftlen;
4095 char *curbuf;
4096 off_t advoffset;
4097 #ifdef ADVANSYS_STATS
4098 int tgt_id;
4099 #endif /* ADVANSYS_STATS */
4101 ASC_DBG(1, "advansys_proc_info: begin\n");
4104 * User write not supported.
4106 if (inout == TRUE) {
4107 return(-ENOSYS);
4111 * User read of /proc/scsi/advansys/[0...] file.
4114 /* Find the specified board. */
4115 for (i = 0; i < asc_board_count; i++) {
4116 if (asc_host[i]->host_no == shost->host_no) {
4117 break;
4120 if (i == asc_board_count) {
4121 return(-ENOENT);
4124 shp = asc_host[i];
4125 boardp = ASC_BOARDP(shp);
4127 /* Copy read data starting at the beginning of the buffer. */
4128 *start = buffer;
4129 curbuf = buffer;
4130 advoffset = 0;
4131 totcnt = 0;
4132 leftlen = length;
4135 * Get board configuration information.
4137 * advansys_info() returns the board string from its own static buffer.
4139 cp = (char *) advansys_info(shp);
4140 strcat(cp, "\n");
4141 cplen = strlen(cp);
4142 /* Copy board information. */
4143 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4144 totcnt += cnt;
4145 leftlen -= cnt;
4146 if (leftlen == 0) {
4147 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4148 return totcnt;
4150 advoffset += cplen;
4151 curbuf += cnt;
4154 * Display Wide Board BIOS Information.
4156 if (ASC_WIDE_BOARD(boardp)) {
4157 cp = boardp->prtbuf;
4158 cplen = asc_prt_adv_bios(shp, cp, ASC_PRTBUF_SIZE);
4159 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4160 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4161 totcnt += cnt;
4162 leftlen -= cnt;
4163 if (leftlen == 0) {
4164 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4165 return totcnt;
4167 advoffset += cplen;
4168 curbuf += cnt;
4172 * Display driver information for each device attached to the board.
4174 cp = boardp->prtbuf;
4175 cplen = asc_prt_board_devices(shp, cp, ASC_PRTBUF_SIZE);
4176 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4177 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4178 totcnt += cnt;
4179 leftlen -= cnt;
4180 if (leftlen == 0) {
4181 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4182 return totcnt;
4184 advoffset += cplen;
4185 curbuf += cnt;
4188 * Display EEPROM configuration for the board.
4190 cp = boardp->prtbuf;
4191 if (ASC_NARROW_BOARD(boardp)) {
4192 cplen = asc_prt_asc_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4193 } else {
4194 cplen = asc_prt_adv_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4196 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4197 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4198 totcnt += cnt;
4199 leftlen -= cnt;
4200 if (leftlen == 0) {
4201 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4202 return totcnt;
4204 advoffset += cplen;
4205 curbuf += cnt;
4208 * Display driver configuration and information for the board.
4210 cp = boardp->prtbuf;
4211 cplen = asc_prt_driver_conf(shp, cp, ASC_PRTBUF_SIZE);
4212 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4213 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4214 totcnt += cnt;
4215 leftlen -= cnt;
4216 if (leftlen == 0) {
4217 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4218 return totcnt;
4220 advoffset += cplen;
4221 curbuf += cnt;
4223 #ifdef ADVANSYS_STATS
4225 * Display driver statistics for the board.
4227 cp = boardp->prtbuf;
4228 cplen = asc_prt_board_stats(shp, cp, ASC_PRTBUF_SIZE);
4229 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4230 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4231 totcnt += cnt;
4232 leftlen -= cnt;
4233 if (leftlen == 0) {
4234 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4235 return totcnt;
4237 advoffset += cplen;
4238 curbuf += cnt;
4241 * Display driver statistics for each target.
4243 for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
4244 cp = boardp->prtbuf;
4245 cplen = asc_prt_target_stats(shp, tgt_id, cp, ASC_PRTBUF_SIZE);
4246 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4247 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4248 totcnt += cnt;
4249 leftlen -= cnt;
4250 if (leftlen == 0) {
4251 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4252 return totcnt;
4254 advoffset += cplen;
4255 curbuf += cnt;
4257 #endif /* ADVANSYS_STATS */
4260 * Display Asc Library dynamic configuration information
4261 * for the board.
4263 cp = boardp->prtbuf;
4264 if (ASC_NARROW_BOARD(boardp)) {
4265 cplen = asc_prt_asc_board_info(shp, cp, ASC_PRTBUF_SIZE);
4266 } else {
4267 cplen = asc_prt_adv_board_info(shp, cp, ASC_PRTBUF_SIZE);
4269 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4270 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4271 totcnt += cnt;
4272 leftlen -= cnt;
4273 if (leftlen == 0) {
4274 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4275 return totcnt;
4277 advoffset += cplen;
4278 curbuf += cnt;
4280 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4282 return totcnt;
4284 #endif /* CONFIG_PROC_FS */
4287 * advansys_detect()
4289 * Detect function for AdvanSys adapters.
4291 * Argument is a pointer to the host driver's scsi_hosts entry.
4293 * Return number of adapters found.
4295 * Note: Because this function is called during system initialization
4296 * it must not call SCSI mid-level functions including scsi_malloc()
4297 * and scsi_free().
4299 int __init
4300 advansys_detect(struct scsi_host_template *tpnt)
4302 static int detect_called = ASC_FALSE;
4303 int iop;
4304 int bus;
4305 struct Scsi_Host *shp = NULL;
4306 asc_board_t *boardp = NULL;
4307 ASC_DVC_VAR *asc_dvc_varp = NULL;
4308 ADV_DVC_VAR *adv_dvc_varp = NULL;
4309 adv_sgblk_t *sgp = NULL;
4310 int ioport = 0;
4311 int share_irq = FALSE;
4312 int iolen = 0;
4313 struct device *dev = NULL;
4314 #ifdef CONFIG_PCI
4315 int pci_init_search = 0;
4316 struct pci_dev *pci_devicep[ASC_NUM_BOARD_SUPPORTED];
4317 int pci_card_cnt_max = 0;
4318 int pci_card_cnt = 0;
4319 struct pci_dev *pci_devp = NULL;
4320 int pci_device_id_cnt = 0;
4321 unsigned int pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
4322 PCI_DEVICE_ID_ASP_1200A,
4323 PCI_DEVICE_ID_ASP_ABP940,
4324 PCI_DEVICE_ID_ASP_ABP940U,
4325 PCI_DEVICE_ID_ASP_ABP940UW,
4326 PCI_DEVICE_ID_38C0800_REV1,
4327 PCI_DEVICE_ID_38C1600_REV1
4329 ADV_PADDR pci_memory_address;
4330 #endif /* CONFIG_PCI */
4331 int warn_code, err_code;
4332 int ret;
4334 if (detect_called == ASC_FALSE) {
4335 detect_called = ASC_TRUE;
4336 } else {
4337 printk("AdvanSys SCSI: advansys_detect() multiple calls ignored\n");
4338 return 0;
4341 ASC_DBG(1, "advansys_detect: begin\n");
4343 asc_board_count = 0;
4346 * If I/O port probing has been modified, then verify and
4347 * clean-up the 'asc_ioport' list.
4349 if (asc_iopflag == ASC_TRUE) {
4350 for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
4351 ASC_DBG2(1, "advansys_detect: asc_ioport[%d] 0x%x\n",
4352 ioport, asc_ioport[ioport]);
4353 if (asc_ioport[ioport] != 0) {
4354 for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX; iop++) {
4355 if (_asc_def_iop_base[iop] == asc_ioport[ioport]) {
4356 break;
4359 if (iop == ASC_IOADR_TABLE_MAX_IX) {
4360 printk(
4361 "AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
4362 asc_ioport[ioport]);
4363 asc_ioport[ioport] = 0;
4367 ioport = 0;
4370 for (bus = 0; bus < ASC_NUM_BUS; bus++) {
4372 ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
4373 bus, asc_bus_name[bus]);
4374 iop = 0;
4376 while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) {
4378 ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
4379 asc_board_count);
4381 switch (asc_bus[bus]) {
4382 case ASC_IS_ISA:
4383 case ASC_IS_VL:
4384 #ifdef CONFIG_ISA
4385 if (asc_iopflag == ASC_FALSE) {
4386 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4387 } else {
4389 * ISA and VL I/O port scanning has either been
4390 * eliminated or limited to selected ports on
4391 * the LILO command line, /etc/lilo.conf, or
4392 * by setting variables when the module was loaded.
4394 ASC_DBG(1, "advansys_detect: I/O port scanning modified\n");
4395 ioport_try_again:
4396 iop = 0;
4397 for (; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
4398 if ((iop = asc_ioport[ioport]) != 0) {
4399 break;
4402 if (iop) {
4403 ASC_DBG1(1,
4404 "advansys_detect: probing I/O port 0x%x...\n",
4405 iop);
4406 if (!request_region(iop, ASC_IOADR_GAP, "advansys")){
4407 printk(
4408 "AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop);
4409 /* Don't try this I/O port twice. */
4410 asc_ioport[ioport] = 0;
4411 goto ioport_try_again;
4412 } else if (AscFindSignature(iop) == ASC_FALSE) {
4413 printk(
4414 "AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop);
4415 /* Don't try this I/O port twice. */
4416 release_region(iop, ASC_IOADR_GAP);
4417 asc_ioport[ioport] = 0;
4418 goto ioport_try_again;
4419 } else {
4421 * If this isn't an ISA board, then it must be
4422 * a VL board. If currently looking an ISA
4423 * board is being looked for then try for
4424 * another ISA board in 'asc_ioport'.
4426 if (asc_bus[bus] == ASC_IS_ISA &&
4427 (AscGetChipVersion(iop, ASC_IS_ISA) &
4428 ASC_CHIP_VER_ISA_BIT) == 0) {
4430 * Don't clear 'asc_ioport[ioport]'. Try
4431 * this board again for VL. Increment
4432 * 'ioport' past this board.
4434 ioport++;
4435 release_region(iop, ASC_IOADR_GAP);
4436 goto ioport_try_again;
4440 * This board appears good, don't try the I/O port
4441 * again by clearing its value. Increment 'ioport'
4442 * for the next iteration.
4444 asc_ioport[ioport++] = 0;
4447 #endif /* CONFIG_ISA */
4448 break;
4450 case ASC_IS_EISA:
4451 #ifdef CONFIG_ISA
4452 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4453 #endif /* CONFIG_ISA */
4454 break;
4456 case ASC_IS_PCI:
4457 #ifdef CONFIG_PCI
4458 if (pci_init_search == 0) {
4459 int i, j;
4461 pci_init_search = 1;
4463 /* Find all PCI cards. */
4464 while (pci_device_id_cnt < ASC_PCI_DEVICE_ID_CNT) {
4465 if ((pci_devp = pci_find_device(PCI_VENDOR_ID_ASP,
4466 pci_device_id[pci_device_id_cnt], pci_devp)) ==
4467 NULL) {
4468 pci_device_id_cnt++;
4469 } else {
4470 if (pci_enable_device(pci_devp) == 0) {
4471 pci_devicep[pci_card_cnt_max++] = pci_devp;
4477 * Sort PCI cards in ascending order by PCI Bus, Slot,
4478 * and Device Number.
4480 for (i = 0; i < pci_card_cnt_max - 1; i++)
4482 for (j = i + 1; j < pci_card_cnt_max; j++) {
4483 if ((pci_devicep[j]->bus->number <
4484 pci_devicep[i]->bus->number) ||
4485 ((pci_devicep[j]->bus->number ==
4486 pci_devicep[i]->bus->number) &&
4487 (pci_devicep[j]->devfn <
4488 pci_devicep[i]->devfn))) {
4489 pci_devp = pci_devicep[i];
4490 pci_devicep[i] = pci_devicep[j];
4491 pci_devicep[j] = pci_devp;
4496 pci_card_cnt = 0;
4497 } else {
4498 pci_card_cnt++;
4501 if (pci_card_cnt == pci_card_cnt_max) {
4502 iop = 0;
4503 } else {
4504 pci_devp = pci_devicep[pci_card_cnt];
4506 ASC_DBG2(2,
4507 "advansys_detect: devfn %d, bus number %d\n",
4508 pci_devp->devfn, pci_devp->bus->number);
4509 iop = pci_resource_start(pci_devp, 0);
4510 ASC_DBG2(1,
4511 "advansys_detect: vendorID %X, deviceID %X\n",
4512 pci_devp->vendor, pci_devp->device);
4513 ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
4514 iop, pci_devp->irq);
4516 if(pci_devp)
4517 dev = &pci_devp->dev;
4519 #endif /* CONFIG_PCI */
4520 break;
4522 default:
4523 ASC_PRINT1("advansys_detect: unknown bus type: %d\n",
4524 asc_bus[bus]);
4525 break;
4527 ASC_DBG1(1, "advansys_detect: iop 0x%x\n", iop);
4530 * Adapter not found, try next bus type.
4532 if (iop == 0) {
4533 break;
4537 * Adapter found.
4539 * Register the adapter, get its configuration, and
4540 * initialize it.
4542 ASC_DBG(2, "advansys_detect: scsi_register()\n");
4543 shp = scsi_register(tpnt, sizeof(asc_board_t));
4545 if (shp == NULL) {
4546 continue;
4549 /* Save a pointer to the Scsi_Host of each board found. */
4550 asc_host[asc_board_count++] = shp;
4552 /* Initialize private per board data */
4553 boardp = ASC_BOARDP(shp);
4554 memset(boardp, 0, sizeof(asc_board_t));
4555 boardp->id = asc_board_count - 1;
4557 /* Initialize spinlock. */
4558 spin_lock_init(&boardp->lock);
4561 * Handle both narrow and wide boards.
4563 * If a Wide board was detected, set the board structure
4564 * wide board flag. Set-up the board structure based on
4565 * the board type.
4567 #ifdef CONFIG_PCI
4568 if (asc_bus[bus] == ASC_IS_PCI &&
4569 (pci_devp->device == PCI_DEVICE_ID_ASP_ABP940UW ||
4570 pci_devp->device == PCI_DEVICE_ID_38C0800_REV1 ||
4571 pci_devp->device == PCI_DEVICE_ID_38C1600_REV1))
4573 boardp->flags |= ASC_IS_WIDE_BOARD;
4575 #endif /* CONFIG_PCI */
4577 if (ASC_NARROW_BOARD(boardp)) {
4578 ASC_DBG(1, "advansys_detect: narrow board\n");
4579 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4580 asc_dvc_varp->bus_type = asc_bus[bus];
4581 asc_dvc_varp->drv_ptr = boardp;
4582 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
4583 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
4584 asc_dvc_varp->iop_base = iop;
4585 asc_dvc_varp->isr_callback = asc_isr_callback;
4586 } else {
4587 ASC_DBG(1, "advansys_detect: wide board\n");
4588 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4589 adv_dvc_varp->drv_ptr = boardp;
4590 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
4591 adv_dvc_varp->isr_callback = adv_isr_callback;
4592 adv_dvc_varp->async_callback = adv_async_callback;
4593 #ifdef CONFIG_PCI
4594 if (pci_devp->device == PCI_DEVICE_ID_ASP_ABP940UW)
4596 ASC_DBG(1, "advansys_detect: ASC-3550\n");
4597 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
4598 } else if (pci_devp->device == PCI_DEVICE_ID_38C0800_REV1)
4600 ASC_DBG(1, "advansys_detect: ASC-38C0800\n");
4601 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
4602 } else
4604 ASC_DBG(1, "advansys_detect: ASC-38C1600\n");
4605 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
4607 #endif /* CONFIG_PCI */
4610 * Map the board's registers into virtual memory for
4611 * PCI slave access. Only memory accesses are used to
4612 * access the board's registers.
4614 * Note: The PCI register base address is not always
4615 * page aligned, but the address passed to ioremap()
4616 * must be page aligned. It is guaranteed that the
4617 * PCI register base address will not cross a page
4618 * boundary.
4620 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
4622 iolen = ADV_3550_IOLEN;
4623 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
4625 iolen = ADV_38C0800_IOLEN;
4626 } else
4628 iolen = ADV_38C1600_IOLEN;
4630 #ifdef CONFIG_PCI
4631 pci_memory_address = pci_resource_start(pci_devp, 1);
4632 ASC_DBG1(1, "advansys_detect: pci_memory_address: 0x%lx\n",
4633 (ulong) pci_memory_address);
4634 if ((boardp->ioremap_addr =
4635 ioremap(pci_memory_address & PAGE_MASK,
4636 PAGE_SIZE)) == 0) {
4637 ASC_PRINT3(
4638 "advansys_detect: board %d: ioremap(%x, %d) returned NULL\n",
4639 boardp->id, pci_memory_address, iolen);
4640 scsi_unregister(shp);
4641 asc_board_count--;
4642 continue;
4644 ASC_DBG1(1, "advansys_detect: ioremap_addr: 0x%lx\n",
4645 (ulong) boardp->ioremap_addr);
4646 adv_dvc_varp->iop_base = (AdvPortAddr)
4647 (boardp->ioremap_addr +
4648 (pci_memory_address - (pci_memory_address & PAGE_MASK)));
4649 ASC_DBG1(1, "advansys_detect: iop_base: 0x%lx\n",
4650 adv_dvc_varp->iop_base);
4651 #endif /* CONFIG_PCI */
4654 * Even though it isn't used to access wide boards, other
4655 * than for the debug line below, save I/O Port address so
4656 * that it can be reported.
4658 boardp->ioport = iop;
4660 ASC_DBG2(1,
4661 "advansys_detect: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
4662 (ushort) inp(iop + 1), (ushort) inpw(iop));
4665 #ifdef CONFIG_PROC_FS
4667 * Allocate buffer for printing information from
4668 * /proc/scsi/advansys/[0...].
4670 if ((boardp->prtbuf =
4671 kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) {
4672 ASC_PRINT3(
4673 "advansys_detect: board %d: kmalloc(%d, %d) returned NULL\n",
4674 boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC);
4675 scsi_unregister(shp);
4676 asc_board_count--;
4677 continue;
4679 #endif /* CONFIG_PROC_FS */
4681 if (ASC_NARROW_BOARD(boardp)) {
4682 asc_dvc_varp->cfg->dev = dev;
4684 * Set the board bus type and PCI IRQ before
4685 * calling AscInitGetConfig().
4687 switch (asc_dvc_varp->bus_type) {
4688 #ifdef CONFIG_ISA
4689 case ASC_IS_ISA:
4690 shp->unchecked_isa_dma = TRUE;
4691 share_irq = FALSE;
4692 break;
4693 case ASC_IS_VL:
4694 shp->unchecked_isa_dma = FALSE;
4695 share_irq = FALSE;
4696 break;
4697 case ASC_IS_EISA:
4698 shp->unchecked_isa_dma = FALSE;
4699 share_irq = TRUE;
4700 break;
4701 #endif /* CONFIG_ISA */
4702 #ifdef CONFIG_PCI
4703 case ASC_IS_PCI:
4704 shp->irq = asc_dvc_varp->irq_no = pci_devp->irq;
4705 asc_dvc_varp->cfg->pci_slot_info =
4706 ASC_PCI_MKID(pci_devp->bus->number,
4707 PCI_SLOT(pci_devp->devfn),
4708 PCI_FUNC(pci_devp->devfn));
4709 shp->unchecked_isa_dma = FALSE;
4710 share_irq = TRUE;
4711 break;
4712 #endif /* CONFIG_PCI */
4713 default:
4714 ASC_PRINT2(
4715 "advansys_detect: board %d: unknown adapter type: %d\n",
4716 boardp->id, asc_dvc_varp->bus_type);
4717 shp->unchecked_isa_dma = TRUE;
4718 share_irq = FALSE;
4719 break;
4721 } else {
4722 adv_dvc_varp->cfg->dev = dev;
4724 * For Wide boards set PCI information before calling
4725 * AdvInitGetConfig().
4727 #ifdef CONFIG_PCI
4728 shp->irq = adv_dvc_varp->irq_no = pci_devp->irq;
4729 adv_dvc_varp->cfg->pci_slot_info =
4730 ASC_PCI_MKID(pci_devp->bus->number,
4731 PCI_SLOT(pci_devp->devfn),
4732 PCI_FUNC(pci_devp->devfn));
4733 shp->unchecked_isa_dma = FALSE;
4734 share_irq = TRUE;
4735 #endif /* CONFIG_PCI */
4739 * Read the board configuration.
4741 if (ASC_NARROW_BOARD(boardp)) {
4743 * NOTE: AscInitGetConfig() may change the board's
4744 * bus_type value. The asc_bus[bus] value should no
4745 * longer be used. If the bus_type field must be
4746 * referenced only use the bit-wise AND operator "&".
4748 ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
4749 switch(ret = AscInitGetConfig(asc_dvc_varp)) {
4750 case 0: /* No error */
4751 break;
4752 case ASC_WARN_IO_PORT_ROTATE:
4753 ASC_PRINT1(
4754 "AscInitGetConfig: board %d: I/O port address modified\n",
4755 boardp->id);
4756 break;
4757 case ASC_WARN_AUTO_CONFIG:
4758 ASC_PRINT1(
4759 "AscInitGetConfig: board %d: I/O port increment switch enabled\n",
4760 boardp->id);
4761 break;
4762 case ASC_WARN_EEPROM_CHKSUM:
4763 ASC_PRINT1(
4764 "AscInitGetConfig: board %d: EEPROM checksum error\n",
4765 boardp->id);
4766 break;
4767 case ASC_WARN_IRQ_MODIFIED:
4768 ASC_PRINT1(
4769 "AscInitGetConfig: board %d: IRQ modified\n",
4770 boardp->id);
4771 break;
4772 case ASC_WARN_CMD_QNG_CONFLICT:
4773 ASC_PRINT1(
4774 "AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
4775 boardp->id);
4776 break;
4777 default:
4778 ASC_PRINT2(
4779 "AscInitGetConfig: board %d: unknown warning: 0x%x\n",
4780 boardp->id, ret);
4781 break;
4783 if ((err_code = asc_dvc_varp->err_code) != 0) {
4784 ASC_PRINT3(
4785 "AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
4786 boardp->id, asc_dvc_varp->init_state,
4787 asc_dvc_varp->err_code);
4789 } else {
4790 ASC_DBG(2, "advansys_detect: AdvInitGetConfig()\n");
4791 if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
4792 ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n",
4793 boardp->id, ret);
4795 if ((err_code = adv_dvc_varp->err_code) != 0) {
4796 ASC_PRINT2(
4797 "AdvInitGetConfig: board %d error: err_code 0x%x\n",
4798 boardp->id, adv_dvc_varp->err_code);
4802 if (err_code != 0) {
4803 #ifdef CONFIG_PROC_FS
4804 kfree(boardp->prtbuf);
4805 #endif /* CONFIG_PROC_FS */
4806 scsi_unregister(shp);
4807 asc_board_count--;
4808 continue;
4812 * Save the EEPROM configuration so that it can be displayed
4813 * from /proc/scsi/advansys/[0...].
4815 if (ASC_NARROW_BOARD(boardp)) {
4817 ASCEEP_CONFIG *ep;
4820 * Set the adapter's target id bit in the 'init_tidmask' field.
4822 boardp->init_tidmask |=
4823 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
4826 * Save EEPROM settings for the board.
4828 ep = &boardp->eep_config.asc_eep;
4830 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
4831 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
4832 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
4833 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
4834 ep->start_motor = asc_dvc_varp->start_motor;
4835 ep->cntl = asc_dvc_varp->dvc_cntl;
4836 ep->no_scam = asc_dvc_varp->no_scam;
4837 ep->max_total_qng = asc_dvc_varp->max_total_qng;
4838 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
4839 /* 'max_tag_qng' is set to the same value for every device. */
4840 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
4841 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
4842 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
4843 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
4844 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
4845 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
4846 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
4849 * Modify board configuration.
4851 ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n");
4852 switch (ret = AscInitSetConfig(asc_dvc_varp)) {
4853 case 0: /* No error. */
4854 break;
4855 case ASC_WARN_IO_PORT_ROTATE:
4856 ASC_PRINT1(
4857 "AscInitSetConfig: board %d: I/O port address modified\n",
4858 boardp->id);
4859 break;
4860 case ASC_WARN_AUTO_CONFIG:
4861 ASC_PRINT1(
4862 "AscInitSetConfig: board %d: I/O port increment switch enabled\n",
4863 boardp->id);
4864 break;
4865 case ASC_WARN_EEPROM_CHKSUM:
4866 ASC_PRINT1(
4867 "AscInitSetConfig: board %d: EEPROM checksum error\n",
4868 boardp->id);
4869 break;
4870 case ASC_WARN_IRQ_MODIFIED:
4871 ASC_PRINT1(
4872 "AscInitSetConfig: board %d: IRQ modified\n",
4873 boardp->id);
4874 break;
4875 case ASC_WARN_CMD_QNG_CONFLICT:
4876 ASC_PRINT1(
4877 "AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
4878 boardp->id);
4879 break;
4880 default:
4881 ASC_PRINT2(
4882 "AscInitSetConfig: board %d: unknown warning: 0x%x\n",
4883 boardp->id, ret);
4884 break;
4886 if (asc_dvc_varp->err_code != 0) {
4887 ASC_PRINT3(
4888 "AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
4889 boardp->id, asc_dvc_varp->init_state,
4890 asc_dvc_varp->err_code);
4891 #ifdef CONFIG_PROC_FS
4892 kfree(boardp->prtbuf);
4893 #endif /* CONFIG_PROC_FS */
4894 scsi_unregister(shp);
4895 asc_board_count--;
4896 continue;
4900 * Finish initializing the 'Scsi_Host' structure.
4902 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
4903 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
4904 shp->irq = asc_dvc_varp->irq_no;
4906 } else {
4907 ADVEEP_3550_CONFIG *ep_3550;
4908 ADVEEP_38C0800_CONFIG *ep_38C0800;
4909 ADVEEP_38C1600_CONFIG *ep_38C1600;
4912 * Save Wide EEP Configuration Information.
4914 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
4916 ep_3550 = &boardp->eep_config.adv_3550_eep;
4918 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
4919 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
4920 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
4921 ep_3550->termination = adv_dvc_varp->cfg->termination;
4922 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
4923 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
4924 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
4925 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
4926 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
4927 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
4928 ep_3550->start_motor = adv_dvc_varp->start_motor;
4929 ep_3550->scsi_reset_delay = adv_dvc_varp->scsi_reset_wait;
4930 ep_3550->serial_number_word1 =
4931 adv_dvc_varp->cfg->serial1;
4932 ep_3550->serial_number_word2 =
4933 adv_dvc_varp->cfg->serial2;
4934 ep_3550->serial_number_word3 =
4935 adv_dvc_varp->cfg->serial3;
4936 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
4938 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
4940 ep_38C0800->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
4941 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
4942 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
4943 ep_38C0800->termination_lvd =
4944 adv_dvc_varp->cfg->termination;
4945 ep_38C0800->disc_enable = adv_dvc_varp->cfg->disc_enable;
4946 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
4947 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
4948 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
4949 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
4950 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
4951 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
4952 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
4953 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
4954 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
4955 ep_38C0800->scsi_reset_delay =
4956 adv_dvc_varp->scsi_reset_wait;
4957 ep_38C0800->serial_number_word1 =
4958 adv_dvc_varp->cfg->serial1;
4959 ep_38C0800->serial_number_word2 =
4960 adv_dvc_varp->cfg->serial2;
4961 ep_38C0800->serial_number_word3 =
4962 adv_dvc_varp->cfg->serial3;
4963 } else
4965 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
4967 ep_38C1600->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
4968 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
4969 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
4970 ep_38C1600->termination_lvd =
4971 adv_dvc_varp->cfg->termination;
4972 ep_38C1600->disc_enable = adv_dvc_varp->cfg->disc_enable;
4973 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
4974 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
4975 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
4976 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
4977 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
4978 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
4979 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
4980 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
4981 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
4982 ep_38C1600->scsi_reset_delay =
4983 adv_dvc_varp->scsi_reset_wait;
4984 ep_38C1600->serial_number_word1 =
4985 adv_dvc_varp->cfg->serial1;
4986 ep_38C1600->serial_number_word2 =
4987 adv_dvc_varp->cfg->serial2;
4988 ep_38C1600->serial_number_word3 =
4989 adv_dvc_varp->cfg->serial3;
4993 * Set the adapter's target id bit in the 'init_tidmask' field.
4995 boardp->init_tidmask |=
4996 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
4999 * Finish initializing the 'Scsi_Host' structure.
5001 shp->irq = adv_dvc_varp->irq_no;
5005 * Channels are numbered beginning with 0. For AdvanSys one host
5006 * structure supports one channel. Multi-channel boards have a
5007 * separate host structure for each channel.
5009 shp->max_channel = 0;
5010 if (ASC_NARROW_BOARD(boardp)) {
5011 shp->max_id = ASC_MAX_TID + 1;
5012 shp->max_lun = ASC_MAX_LUN + 1;
5014 shp->io_port = asc_dvc_varp->iop_base;
5015 boardp->asc_n_io_port = ASC_IOADR_GAP;
5016 shp->this_id = asc_dvc_varp->cfg->chip_scsi_id;
5018 /* Set maximum number of queues the adapter can handle. */
5019 shp->can_queue = asc_dvc_varp->max_total_qng;
5020 } else {
5021 shp->max_id = ADV_MAX_TID + 1;
5022 shp->max_lun = ADV_MAX_LUN + 1;
5025 * Save the I/O Port address and length even though
5026 * I/O ports are not used to access Wide boards.
5027 * Instead the Wide boards are accessed with
5028 * PCI Memory Mapped I/O.
5030 shp->io_port = iop;
5031 boardp->asc_n_io_port = iolen;
5033 shp->this_id = adv_dvc_varp->chip_scsi_id;
5035 /* Set maximum number of queues the adapter can handle. */
5036 shp->can_queue = adv_dvc_varp->max_host_qng;
5040 * 'n_io_port' currently is one byte.
5042 * Set a value to 'n_io_port', but never referenced it because
5043 * it may be truncated.
5045 shp->n_io_port = boardp->asc_n_io_port <= 255 ?
5046 boardp->asc_n_io_port : 255;
5049 * Following v1.3.89, 'cmd_per_lun' is no longer needed
5050 * and should be set to zero.
5052 * But because of a bug introduced in v1.3.89 if the driver is
5053 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
5054 * SCSI function 'allocate_device' will panic. To allow the driver
5055 * to work as a module in these kernels set 'cmd_per_lun' to 1.
5057 * Note: This is wrong. cmd_per_lun should be set to the depth
5058 * you want on untagged devices always.
5059 #ifdef MODULE
5061 shp->cmd_per_lun = 1;
5062 /* #else
5063 shp->cmd_per_lun = 0;
5064 #endif */
5067 * Set the maximum number of scatter-gather elements the
5068 * adapter can handle.
5070 if (ASC_NARROW_BOARD(boardp)) {
5072 * Allow two commands with 'sg_tablesize' scatter-gather
5073 * elements to be executed simultaneously. This value is
5074 * the theoretical hardware limit. It may be decreased
5075 * below.
5077 shp->sg_tablesize =
5078 (((asc_dvc_varp->max_total_qng - 2) / 2) *
5079 ASC_SG_LIST_PER_Q) + 1;
5080 } else {
5081 shp->sg_tablesize = ADV_MAX_SG_LIST;
5085 * The value of 'sg_tablesize' can not exceed the SCSI
5086 * mid-level driver definition of SG_ALL. SG_ALL also
5087 * must not be exceeded, because it is used to define the
5088 * size of the scatter-gather table in 'struct asc_sg_head'.
5090 if (shp->sg_tablesize > SG_ALL) {
5091 shp->sg_tablesize = SG_ALL;
5094 ASC_DBG1(1, "advansys_detect: sg_tablesize: %d\n",
5095 shp->sg_tablesize);
5097 /* BIOS start address. */
5098 if (ASC_NARROW_BOARD(boardp)) {
5099 shp->base =
5100 ((ulong) AscGetChipBiosAddress(
5101 asc_dvc_varp->iop_base,
5102 asc_dvc_varp->bus_type));
5103 } else {
5105 * Fill-in BIOS board variables. The Wide BIOS saves
5106 * information in LRAM that is used by the driver.
5108 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_SIGNATURE,
5109 boardp->bios_signature);
5110 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_VERSION,
5111 boardp->bios_version);
5112 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODESEG,
5113 boardp->bios_codeseg);
5114 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODELEN,
5115 boardp->bios_codelen);
5117 ASC_DBG2(1,
5118 "advansys_detect: bios_signature 0x%x, bios_version 0x%x\n",
5119 boardp->bios_signature, boardp->bios_version);
5121 ASC_DBG2(1,
5122 "advansys_detect: bios_codeseg 0x%x, bios_codelen 0x%x\n",
5123 boardp->bios_codeseg, boardp->bios_codelen);
5126 * If the BIOS saved a valid signature, then fill in
5127 * the BIOS code segment base address.
5129 if (boardp->bios_signature == 0x55AA) {
5131 * Convert x86 realmode code segment to a linear
5132 * address by shifting left 4.
5134 shp->base = ((ulong) boardp->bios_codeseg << 4);
5135 } else {
5136 shp->base = 0;
5141 * Register Board Resources - I/O Port, DMA, IRQ
5145 * Register I/O port range.
5147 * For Wide boards the I/O ports are not used to access
5148 * the board, but request the region anyway.
5150 * 'shp->n_io_port' is not referenced, because it may be truncated.
5152 ASC_DBG2(2,
5153 "advansys_detect: request_region port 0x%lx, len 0x%x\n",
5154 (ulong) shp->io_port, boardp->asc_n_io_port);
5155 if (request_region(shp->io_port, boardp->asc_n_io_port,
5156 "advansys") == NULL) {
5157 ASC_PRINT3(
5158 "advansys_detect: board %d: request_region() failed, port 0x%lx, len 0x%x\n",
5159 boardp->id, (ulong) shp->io_port, boardp->asc_n_io_port);
5160 #ifdef CONFIG_PROC_FS
5161 kfree(boardp->prtbuf);
5162 #endif /* CONFIG_PROC_FS */
5163 scsi_unregister(shp);
5164 asc_board_count--;
5165 continue;
5168 /* Register DMA Channel for Narrow boards. */
5169 shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
5170 #ifdef CONFIG_ISA
5171 if (ASC_NARROW_BOARD(boardp)) {
5172 /* Register DMA channel for ISA bus. */
5173 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5174 shp->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
5175 if ((ret =
5176 request_dma(shp->dma_channel, "advansys")) != 0) {
5177 ASC_PRINT3(
5178 "advansys_detect: board %d: request_dma() %d failed %d\n",
5179 boardp->id, shp->dma_channel, ret);
5180 release_region(shp->io_port, boardp->asc_n_io_port);
5181 #ifdef CONFIG_PROC_FS
5182 kfree(boardp->prtbuf);
5183 #endif /* CONFIG_PROC_FS */
5184 scsi_unregister(shp);
5185 asc_board_count--;
5186 continue;
5188 AscEnableIsaDma(shp->dma_channel);
5191 #endif /* CONFIG_ISA */
5193 /* Register IRQ Number. */
5194 ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
5196 * If request_irq() fails with the IRQF_DISABLED flag set,
5197 * then try again without the IRQF_DISABLED flag set. This
5198 * allows IRQ sharing to work even with other drivers that
5199 * do not set the IRQF_DISABLED flag.
5201 * If IRQF_DISABLED is not set, then interrupts are enabled
5202 * before the driver interrupt function is called.
5204 if (((ret = request_irq(shp->irq, advansys_interrupt,
5205 IRQF_DISABLED | (share_irq == TRUE ? IRQF_SHARED : 0),
5206 "advansys", boardp)) != 0) &&
5207 ((ret = request_irq(shp->irq, advansys_interrupt,
5208 (share_irq == TRUE ? IRQF_SHARED : 0),
5209 "advansys", boardp)) != 0))
5211 if (ret == -EBUSY) {
5212 ASC_PRINT2(
5213 "advansys_detect: board %d: request_irq(): IRQ 0x%x already in use.\n",
5214 boardp->id, shp->irq);
5215 } else if (ret == -EINVAL) {
5216 ASC_PRINT2(
5217 "advansys_detect: board %d: request_irq(): IRQ 0x%x not valid.\n",
5218 boardp->id, shp->irq);
5219 } else {
5220 ASC_PRINT3(
5221 "advansys_detect: board %d: request_irq(): IRQ 0x%x failed with %d\n",
5222 boardp->id, shp->irq, ret);
5224 release_region(shp->io_port, boardp->asc_n_io_port);
5225 iounmap(boardp->ioremap_addr);
5226 if (shp->dma_channel != NO_ISA_DMA) {
5227 free_dma(shp->dma_channel);
5229 #ifdef CONFIG_PROC_FS
5230 kfree(boardp->prtbuf);
5231 #endif /* CONFIG_PROC_FS */
5232 scsi_unregister(shp);
5233 asc_board_count--;
5234 continue;
5238 * Initialize board RISC chip and enable interrupts.
5240 if (ASC_NARROW_BOARD(boardp)) {
5241 ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n");
5242 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
5243 err_code = asc_dvc_varp->err_code;
5245 if (warn_code || err_code) {
5246 ASC_PRINT4(
5247 "advansys_detect: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
5248 boardp->id, asc_dvc_varp->init_state,
5249 warn_code, err_code);
5251 } else {
5252 ADV_CARR_T *carrp;
5253 int req_cnt = 0;
5254 adv_req_t *reqp = NULL;
5255 int sg_cnt = 0;
5258 * Allocate buffer carrier structures. The total size
5259 * is about 4 KB, so allocate all at once.
5261 carrp =
5262 (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC);
5263 ASC_DBG1(1, "advansys_detect: carrp 0x%lx\n", (ulong) carrp);
5265 if (carrp == NULL) {
5266 goto kmalloc_error;
5270 * Allocate up to 'max_host_qng' request structures for
5271 * the Wide board. The total size is about 16 KB, so
5272 * allocate all at once. If the allocation fails decrement
5273 * and try again.
5275 for (req_cnt = adv_dvc_varp->max_host_qng;
5276 req_cnt > 0; req_cnt--) {
5278 reqp = (adv_req_t *)
5279 kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC);
5281 ASC_DBG3(1,
5282 "advansys_detect: reqp 0x%lx, req_cnt %d, bytes %lu\n",
5283 (ulong) reqp, req_cnt,
5284 (ulong) sizeof(adv_req_t) * req_cnt);
5286 if (reqp != NULL) {
5287 break;
5290 if (reqp == NULL)
5292 goto kmalloc_error;
5296 * Allocate up to ADV_TOT_SG_BLOCK request structures for
5297 * the Wide board. Each structure is about 136 bytes.
5299 boardp->adv_sgblkp = NULL;
5300 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
5302 sgp = (adv_sgblk_t *)
5303 kmalloc(sizeof(adv_sgblk_t), GFP_ATOMIC);
5305 if (sgp == NULL) {
5306 break;
5309 sgp->next_sgblkp = boardp->adv_sgblkp;
5310 boardp->adv_sgblkp = sgp;
5313 ASC_DBG3(1,
5314 "advansys_detect: sg_cnt %d * %u = %u bytes\n",
5315 sg_cnt, sizeof(adv_sgblk_t),
5316 (unsigned) (sizeof(adv_sgblk_t) * sg_cnt));
5319 * If no request structures or scatter-gather structures could
5320 * be allocated, then return an error. Otherwise continue with
5321 * initialization.
5323 kmalloc_error:
5324 if (carrp == NULL)
5326 ASC_PRINT1(
5327 "advansys_detect: board %d error: failed to kmalloc() carrier buffer.\n",
5328 boardp->id);
5329 err_code = ADV_ERROR;
5330 } else if (reqp == NULL) {
5331 kfree(carrp);
5332 ASC_PRINT1(
5333 "advansys_detect: board %d error: failed to kmalloc() adv_req_t buffer.\n",
5334 boardp->id);
5335 err_code = ADV_ERROR;
5336 } else if (boardp->adv_sgblkp == NULL) {
5337 kfree(carrp);
5338 kfree(reqp);
5339 ASC_PRINT1(
5340 "advansys_detect: board %d error: failed to kmalloc() adv_sgblk_t buffers.\n",
5341 boardp->id);
5342 err_code = ADV_ERROR;
5343 } else {
5345 /* Save carrier buffer pointer. */
5346 boardp->orig_carrp = carrp;
5349 * Save original pointer for kfree() in case the
5350 * driver is built as a module and can be unloaded.
5352 boardp->orig_reqp = reqp;
5354 adv_dvc_varp->carrier_buf = carrp;
5357 * Point 'adv_reqp' to the request structures and
5358 * link them together.
5360 req_cnt--;
5361 reqp[req_cnt].next_reqp = NULL;
5362 for (; req_cnt > 0; req_cnt--) {
5363 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
5365 boardp->adv_reqp = &reqp[0];
5367 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5369 ASC_DBG(2,
5370 "advansys_detect: AdvInitAsc3550Driver()\n");
5371 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
5372 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5373 ASC_DBG(2,
5374 "advansys_detect: AdvInitAsc38C0800Driver()\n");
5375 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
5376 } else {
5377 ASC_DBG(2,
5378 "advansys_detect: AdvInitAsc38C1600Driver()\n");
5379 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
5381 err_code = adv_dvc_varp->err_code;
5383 if (warn_code || err_code) {
5384 ASC_PRINT3(
5385 "advansys_detect: board %d error: warn 0x%x, error 0x%x\n",
5386 boardp->id, warn_code, err_code);
5391 if (err_code != 0) {
5392 release_region(shp->io_port, boardp->asc_n_io_port);
5393 if (ASC_WIDE_BOARD(boardp)) {
5394 iounmap(boardp->ioremap_addr);
5395 kfree(boardp->orig_carrp);
5396 boardp->orig_carrp = NULL;
5397 if (boardp->orig_reqp) {
5398 kfree(boardp->orig_reqp);
5399 boardp->orig_reqp = boardp->adv_reqp = NULL;
5401 while ((sgp = boardp->adv_sgblkp) != NULL)
5403 boardp->adv_sgblkp = sgp->next_sgblkp;
5404 kfree(sgp);
5407 if (shp->dma_channel != NO_ISA_DMA) {
5408 free_dma(shp->dma_channel);
5410 #ifdef CONFIG_PROC_FS
5411 kfree(boardp->prtbuf);
5412 #endif /* CONFIG_PROC_FS */
5413 free_irq(shp->irq, boardp);
5414 scsi_unregister(shp);
5415 asc_board_count--;
5416 continue;
5418 ASC_DBG_PRT_SCSI_HOST(2, shp);
5422 ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count);
5423 return asc_board_count;
5427 * advansys_release()
5429 * Release resources allocated for a single AdvanSys adapter.
5432 advansys_release(struct Scsi_Host *shp)
5434 asc_board_t *boardp;
5436 ASC_DBG(1, "advansys_release: begin\n");
5437 boardp = ASC_BOARDP(shp);
5438 free_irq(shp->irq, boardp);
5439 if (shp->dma_channel != NO_ISA_DMA) {
5440 ASC_DBG(1, "advansys_release: free_dma()\n");
5441 free_dma(shp->dma_channel);
5443 release_region(shp->io_port, boardp->asc_n_io_port);
5444 if (ASC_WIDE_BOARD(boardp)) {
5445 adv_sgblk_t *sgp = NULL;
5447 iounmap(boardp->ioremap_addr);
5448 kfree(boardp->orig_carrp);
5449 boardp->orig_carrp = NULL;
5450 if (boardp->orig_reqp) {
5451 kfree(boardp->orig_reqp);
5452 boardp->orig_reqp = boardp->adv_reqp = NULL;
5454 while ((sgp = boardp->adv_sgblkp) != NULL)
5456 boardp->adv_sgblkp = sgp->next_sgblkp;
5457 kfree(sgp);
5460 #ifdef CONFIG_PROC_FS
5461 ASC_ASSERT(boardp->prtbuf != NULL);
5462 kfree(boardp->prtbuf);
5463 #endif /* CONFIG_PROC_FS */
5464 scsi_unregister(shp);
5465 ASC_DBG(1, "advansys_release: end\n");
5466 return 0;
5470 * advansys_info()
5472 * Return suitable for printing on the console with the argument
5473 * adapter's configuration information.
5475 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
5476 * otherwise the static 'info' array will be overrun.
5478 const char *
5479 advansys_info(struct Scsi_Host *shp)
5481 static char info[ASC_INFO_SIZE];
5482 asc_board_t *boardp;
5483 ASC_DVC_VAR *asc_dvc_varp;
5484 ADV_DVC_VAR *adv_dvc_varp;
5485 char *busname;
5486 int iolen;
5487 char *widename = NULL;
5489 boardp = ASC_BOARDP(shp);
5490 if (ASC_NARROW_BOARD(boardp)) {
5491 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5492 ASC_DBG(1, "advansys_info: begin\n");
5493 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5494 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == ASC_IS_ISAPNP) {
5495 busname = "ISA PnP";
5496 } else {
5497 busname = "ISA";
5499 /* Don't reference 'shp->n_io_port'; It may be truncated. */
5500 sprintf(info,
5501 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
5502 ASC_VERSION, busname,
5503 (ulong) shp->io_port,
5504 (ulong) shp->io_port + boardp->asc_n_io_port - 1,
5505 shp->irq, shp->dma_channel);
5506 } else {
5507 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
5508 busname = "VL";
5509 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
5510 busname = "EISA";
5511 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
5512 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
5513 == ASC_IS_PCI_ULTRA) {
5514 busname = "PCI Ultra";
5515 } else {
5516 busname = "PCI";
5518 } else {
5519 busname = "?";
5520 ASC_PRINT2( "advansys_info: board %d: unknown bus type %d\n",
5521 boardp->id, asc_dvc_varp->bus_type);
5523 /* Don't reference 'shp->n_io_port'; It may be truncated. */
5524 sprintf(info,
5525 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
5526 ASC_VERSION, busname,
5527 (ulong) shp->io_port,
5528 (ulong) shp->io_port + boardp->asc_n_io_port - 1,
5529 shp->irq);
5531 } else {
5533 * Wide Adapter Information
5535 * Memory-mapped I/O is used instead of I/O space to access
5536 * the adapter, but display the I/O Port range. The Memory
5537 * I/O address is displayed through the driver /proc file.
5539 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5540 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5542 iolen = ADV_3550_IOLEN;
5543 widename = "Ultra-Wide";
5544 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
5546 iolen = ADV_38C0800_IOLEN;
5547 widename = "Ultra2-Wide";
5548 } else
5550 iolen = ADV_38C1600_IOLEN;
5551 widename = "Ultra3-Wide";
5553 sprintf(info, "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
5554 ASC_VERSION,
5555 widename,
5556 (ulong) adv_dvc_varp->iop_base,
5557 (ulong) adv_dvc_varp->iop_base + iolen - 1,
5558 shp->irq);
5560 ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
5561 ASC_DBG(1, "advansys_info: end\n");
5562 return info;
5566 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
5568 * This function always returns 0. Command return status is saved
5569 * in the 'scp' result field.
5572 advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
5574 struct Scsi_Host *shp;
5575 asc_board_t *boardp;
5576 ulong flags;
5577 struct scsi_cmnd *done_scp;
5579 shp = scp->device->host;
5580 boardp = ASC_BOARDP(shp);
5581 ASC_STATS(shp, queuecommand);
5583 /* host_lock taken by mid-level prior to call but need to protect */
5584 /* against own ISR */
5585 spin_lock_irqsave(&boardp->lock, flags);
5588 * Block new commands while handling a reset or abort request.
5590 if (boardp->flags & ASC_HOST_IN_RESET) {
5591 ASC_DBG1(1,
5592 "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
5593 (ulong) scp);
5594 scp->result = HOST_BYTE(DID_RESET);
5597 * Add blocked requests to the board's 'done' queue. The queued
5598 * requests will be completed at the end of the abort or reset
5599 * handling.
5601 asc_enqueue(&boardp->done, scp, ASC_BACK);
5602 spin_unlock_irqrestore(&boardp->lock, flags);
5603 return 0;
5607 * Attempt to execute any waiting commands for the board.
5609 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
5610 ASC_DBG(1,
5611 "advansys_queuecommand: before asc_execute_queue() waiting\n");
5612 asc_execute_queue(&boardp->waiting);
5616 * Save the function pointer to Linux mid-level 'done' function
5617 * and attempt to execute the command.
5619 * If ASC_NOERROR is returned the request has been added to the
5620 * board's 'active' queue and will be completed by the interrupt
5621 * handler.
5623 * If ASC_BUSY is returned add the request to the board's per
5624 * target waiting list. This is the first time the request has
5625 * been tried. Add it to the back of the waiting list. It will be
5626 * retried later.
5628 * If an error occurred, the request will have been placed on the
5629 * board's 'done' queue and must be completed before returning.
5631 scp->scsi_done = done;
5632 switch (asc_execute_scsi_cmnd(scp)) {
5633 case ASC_NOERROR:
5634 break;
5635 case ASC_BUSY:
5636 asc_enqueue(&boardp->waiting, scp, ASC_BACK);
5637 break;
5638 case ASC_ERROR:
5639 default:
5640 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
5641 /* Interrupts could be enabled here. */
5642 asc_scsi_done_list(done_scp);
5643 break;
5645 spin_unlock_irqrestore(&boardp->lock, flags);
5647 return 0;
5651 * advansys_reset()
5653 * Reset the bus associated with the command 'scp'.
5655 * This function runs its own thread. Interrupts must be blocked but
5656 * sleeping is allowed and no locking other than for host structures is
5657 * required. Returns SUCCESS or FAILED.
5660 advansys_reset(struct scsi_cmnd *scp)
5662 struct Scsi_Host *shp;
5663 asc_board_t *boardp;
5664 ASC_DVC_VAR *asc_dvc_varp;
5665 ADV_DVC_VAR *adv_dvc_varp;
5666 ulong flags;
5667 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
5668 struct scsi_cmnd *tscp, *new_last_scp;
5669 int status;
5670 int ret = SUCCESS;
5672 ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong) scp);
5674 #ifdef ADVANSYS_STATS
5675 if (scp->device->host != NULL) {
5676 ASC_STATS(scp->device->host, reset);
5678 #endif /* ADVANSYS_STATS */
5680 if ((shp = scp->device->host) == NULL) {
5681 scp->result = HOST_BYTE(DID_ERROR);
5682 return FAILED;
5685 boardp = ASC_BOARDP(shp);
5687 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
5688 boardp->id);
5690 * Check for re-entrancy.
5692 spin_lock_irqsave(&boardp->lock, flags);
5693 if (boardp->flags & ASC_HOST_IN_RESET) {
5694 spin_unlock_irqrestore(&boardp->lock, flags);
5695 return FAILED;
5697 boardp->flags |= ASC_HOST_IN_RESET;
5698 spin_unlock_irqrestore(&boardp->lock, flags);
5700 if (ASC_NARROW_BOARD(boardp)) {
5702 * Narrow Board
5704 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5707 * Reset the chip and SCSI bus.
5709 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
5710 status = AscInitAsc1000Driver(asc_dvc_varp);
5712 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
5713 if (asc_dvc_varp->err_code) {
5714 ASC_PRINT2(
5715 "advansys_reset: board %d: SCSI bus reset error: 0x%x\n",
5716 boardp->id, asc_dvc_varp->err_code);
5717 ret = FAILED;
5718 } else if (status) {
5719 ASC_PRINT2(
5720 "advansys_reset: board %d: SCSI bus reset warning: 0x%x\n",
5721 boardp->id, status);
5722 } else {
5723 ASC_PRINT1(
5724 "advansys_reset: board %d: SCSI bus reset successful.\n",
5725 boardp->id);
5728 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
5729 spin_lock_irqsave(&boardp->lock, flags);
5731 } else {
5733 * Wide Board
5735 * If the suggest reset bus flags are set, then reset the bus.
5736 * Otherwise only reset the device.
5738 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5741 * Reset the target's SCSI bus.
5743 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
5744 switch (AdvResetChipAndSB(adv_dvc_varp)) {
5745 case ASC_TRUE:
5746 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset successful.\n",
5747 boardp->id);
5748 break;
5749 case ASC_FALSE:
5750 default:
5751 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset error.\n",
5752 boardp->id);
5753 ret = FAILED;
5754 break;
5756 spin_lock_irqsave(&boardp->lock, flags);
5757 (void) AdvISR(adv_dvc_varp);
5759 /* Board lock is held. */
5762 * Dequeue all board 'done' requests. A pointer to the last request
5763 * is returned in 'last_scp'.
5765 done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
5768 * Dequeue all board 'active' requests for all devices and set
5769 * the request status to DID_RESET. A pointer to the last request
5770 * is returned in 'last_scp'.
5772 if (done_scp == NULL) {
5773 done_scp = asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL);
5774 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
5775 tscp->result = HOST_BYTE(DID_RESET);
5777 } else {
5778 /* Append to 'done_scp' at the end with 'last_scp'. */
5779 ASC_ASSERT(last_scp != NULL);
5780 last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
5781 &boardp->active, &new_last_scp, ASC_TID_ALL);
5782 if (new_last_scp != NULL) {
5783 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
5784 for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
5785 tscp->result = HOST_BYTE(DID_RESET);
5787 last_scp = new_last_scp;
5792 * Dequeue all 'waiting' requests and set the request status
5793 * to DID_RESET.
5795 if (done_scp == NULL) {
5796 done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL);
5797 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
5798 tscp->result = HOST_BYTE(DID_RESET);
5800 } else {
5801 /* Append to 'done_scp' at the end with 'last_scp'. */
5802 ASC_ASSERT(last_scp != NULL);
5803 last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
5804 &boardp->waiting, &new_last_scp, ASC_TID_ALL);
5805 if (new_last_scp != NULL) {
5806 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
5807 for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
5808 tscp->result = HOST_BYTE(DID_RESET);
5810 last_scp = new_last_scp;
5814 /* Save the time of the most recently completed reset. */
5815 boardp->last_reset = jiffies;
5817 /* Clear reset flag. */
5818 boardp->flags &= ~ASC_HOST_IN_RESET;
5819 spin_unlock_irqrestore(&boardp->lock, flags);
5822 * Complete all the 'done_scp' requests.
5824 if (done_scp != NULL) {
5825 asc_scsi_done_list(done_scp);
5828 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
5830 return ret;
5834 * advansys_biosparam()
5836 * Translate disk drive geometry if the "BIOS greater than 1 GB"
5837 * support is enabled for a drive.
5839 * ip (information pointer) is an int array with the following definition:
5840 * ip[0]: heads
5841 * ip[1]: sectors
5842 * ip[2]: cylinders
5845 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
5846 sector_t capacity, int ip[])
5848 asc_board_t *boardp;
5850 ASC_DBG(1, "advansys_biosparam: begin\n");
5851 ASC_STATS(sdev->host, biosparam);
5852 boardp = ASC_BOARDP(sdev->host);
5853 if (ASC_NARROW_BOARD(boardp)) {
5854 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
5855 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
5856 ip[0] = 255;
5857 ip[1] = 63;
5858 } else {
5859 ip[0] = 64;
5860 ip[1] = 32;
5862 } else {
5863 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
5864 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
5865 ip[0] = 255;
5866 ip[1] = 63;
5867 } else {
5868 ip[0] = 64;
5869 ip[1] = 32;
5872 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
5873 ASC_DBG(1, "advansys_biosparam: end\n");
5874 return 0;
5878 * advansys_setup()
5880 * This function is called from init/main.c at boot time.
5881 * It it passed LILO parameters that can be set from the
5882 * LILO command line or in /etc/lilo.conf.
5884 * It is used by the AdvanSys driver to either disable I/O
5885 * port scanning or to limit scanning to 1 - 4 I/O ports.
5886 * Regardless of the option setting EISA and PCI boards
5887 * will still be searched for and detected. This option
5888 * only affects searching for ISA and VL boards.
5890 * If ADVANSYS_DEBUG is defined the driver debug level may
5891 * be set using the 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port.
5893 * Examples:
5894 * 1. Eliminate I/O port scanning:
5895 * boot: linux advansys=
5896 * or
5897 * boot: linux advansys=0x0
5898 * 2. Limit I/O port scanning to one I/O port:
5899 * boot: linux advansys=0x110
5900 * 3. Limit I/O port scanning to four I/O ports:
5901 * boot: linux advansys=0x110,0x210,0x230,0x330
5902 * 4. If ADVANSYS_DEBUG, limit I/O port scanning to four I/O ports and
5903 * set the driver debug level to 2.
5904 * boot: linux advansys=0x110,0x210,0x230,0x330,0xdeb2
5906 * ints[0] - number of arguments
5907 * ints[1] - first argument
5908 * ints[2] - second argument
5909 * ...
5911 void __init
5912 advansys_setup(char *str, int *ints)
5914 int i;
5916 if (asc_iopflag == ASC_TRUE) {
5917 printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n");
5918 return;
5921 asc_iopflag = ASC_TRUE;
5923 if (ints[0] > ASC_NUM_IOPORT_PROBE) {
5924 #ifdef ADVANSYS_DEBUG
5925 if ((ints[0] == ASC_NUM_IOPORT_PROBE + 1) &&
5926 (ints[ASC_NUM_IOPORT_PROBE + 1] >> 4 == 0xdeb)) {
5927 asc_dbglvl = ints[ASC_NUM_IOPORT_PROBE + 1] & 0xf;
5928 } else {
5929 #endif /* ADVANSYS_DEBUG */
5930 printk("AdvanSys SCSI: only %d I/O ports accepted\n",
5931 ASC_NUM_IOPORT_PROBE);
5932 #ifdef ADVANSYS_DEBUG
5934 #endif /* ADVANSYS_DEBUG */
5937 #ifdef ADVANSYS_DEBUG
5938 ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]);
5939 for (i = 1; i < ints[0]; i++) {
5940 ASC_DBG2(1, " ints[%d] 0x%x", i, ints[i]);
5942 ASC_DBG(1, "\n");
5943 #endif /* ADVANSYS_DEBUG */
5945 for (i = 1; i <= ints[0] && i <= ASC_NUM_IOPORT_PROBE; i++) {
5946 asc_ioport[i-1] = ints[i];
5947 ASC_DBG2(1, "advansys_setup: asc_ioport[%d] 0x%x\n",
5948 i - 1, asc_ioport[i-1]);
5954 * --- Loadable Driver Support
5957 static struct scsi_host_template driver_template = {
5958 .proc_name = "advansys",
5959 #ifdef CONFIG_PROC_FS
5960 .proc_info = advansys_proc_info,
5961 #endif
5962 .name = "advansys",
5963 .detect = advansys_detect,
5964 .release = advansys_release,
5965 .info = advansys_info,
5966 .queuecommand = advansys_queuecommand,
5967 .eh_bus_reset_handler = advansys_reset,
5968 .bios_param = advansys_biosparam,
5969 .slave_configure = advansys_slave_configure,
5971 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
5972 * must be set. The flag will be cleared in advansys_detect for non-ISA
5973 * adapters. Refer to the comment in scsi_module.c for more information.
5975 .unchecked_isa_dma = 1,
5977 * All adapters controlled by this driver are capable of large
5978 * scatter-gather lists. According to the mid-level SCSI documentation
5979 * this obviates any performance gain provided by setting
5980 * 'use_clustering'. But empirically while CPU utilization is increased
5981 * by enabling clustering, I/O throughput increases as well.
5983 .use_clustering = ENABLE_CLUSTERING,
5985 #include "scsi_module.c"
5989 * --- Miscellaneous Driver Functions
5993 * First-level interrupt handler.
5995 * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
5996 * all boards are currently checked for interrupts on each interrupt, 'dev_id'
5997 * is not referenced. 'dev_id' could be used to identify an interrupt passed
5998 * to the AdvanSys driver which is for a device sharing an interrupt with
5999 * an AdvanSys adapter.
6001 STATIC irqreturn_t
6002 advansys_interrupt(int irq, void *dev_id)
6004 ulong flags;
6005 int i;
6006 asc_board_t *boardp;
6007 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
6008 struct scsi_cmnd *new_last_scp;
6009 struct Scsi_Host *shp;
6011 ASC_DBG(1, "advansys_interrupt: begin\n");
6014 * Check for interrupts on all boards.
6015 * AscISR() will call asc_isr_callback().
6017 for (i = 0; i < asc_board_count; i++) {
6018 shp = asc_host[i];
6019 boardp = ASC_BOARDP(shp);
6020 ASC_DBG2(2, "advansys_interrupt: i %d, boardp 0x%lx\n",
6021 i, (ulong) boardp);
6022 spin_lock_irqsave(&boardp->lock, flags);
6023 if (ASC_NARROW_BOARD(boardp)) {
6025 * Narrow Board
6027 if (AscIsIntPending(shp->io_port)) {
6028 ASC_STATS(shp, interrupt);
6029 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
6030 AscISR(&boardp->dvc_var.asc_dvc_var);
6032 } else {
6034 * Wide Board
6036 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
6037 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
6038 ASC_STATS(shp, interrupt);
6043 * Start waiting requests and create a list of completed requests.
6045 * If a reset request is being performed for the board, the reset
6046 * handler will complete pending requests after it has completed.
6048 if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
6049 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%lx, last_scp 0x%lx\n",
6050 (ulong) done_scp, (ulong) last_scp);
6052 /* Start any waiting commands for the board. */
6053 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
6054 ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
6055 asc_execute_queue(&boardp->waiting);
6059 * Add to the list of requests that must be completed.
6061 * 'done_scp' will always be NULL on the first iteration
6062 * of this loop. 'last_scp' is set at the same time as
6063 * 'done_scp'.
6065 if (done_scp == NULL) {
6066 done_scp = asc_dequeue_list(&boardp->done, &last_scp,
6067 ASC_TID_ALL);
6068 } else {
6069 ASC_ASSERT(last_scp != NULL);
6070 last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
6071 &boardp->done, &new_last_scp, ASC_TID_ALL);
6072 if (new_last_scp != NULL) {
6073 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6074 last_scp = new_last_scp;
6078 spin_unlock_irqrestore(&boardp->lock, flags);
6082 * If interrupts were enabled on entry, then they
6083 * are now enabled here.
6085 * Complete all requests on the done list.
6088 asc_scsi_done_list(done_scp);
6090 ASC_DBG(1, "advansys_interrupt: end\n");
6091 return IRQ_HANDLED;
6095 * Set the number of commands to queue per device for the
6096 * specified host adapter.
6098 STATIC int
6099 advansys_slave_configure(struct scsi_device *device)
6101 asc_board_t *boardp;
6103 boardp = ASC_BOARDP(device->host);
6104 boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
6106 * Save a pointer to the device and set its initial/maximum
6107 * queue depth. Only save the pointer for a lun0 dev though.
6109 if(device->lun == 0)
6110 boardp->device[device->id] = device;
6111 if(device->tagged_supported) {
6112 if (ASC_NARROW_BOARD(boardp)) {
6113 scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
6114 boardp->dvc_var.asc_dvc_var.max_dvc_qng[device->id]);
6115 } else {
6116 scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
6117 boardp->dvc_var.adv_dvc_var.max_dvc_qng);
6119 } else {
6120 scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun);
6122 ASC_DBG4(1, "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n",
6123 (ulong) device, (ulong) boardp, device->id, device->queue_depth);
6124 return 0;
6128 * Complete all requests on the singly linked list pointed
6129 * to by 'scp'.
6131 * Interrupts can be enabled on entry.
6133 STATIC void
6134 asc_scsi_done_list(struct scsi_cmnd *scp)
6136 struct scsi_cmnd *tscp;
6138 ASC_DBG(2, "asc_scsi_done_list: begin\n");
6139 while (scp != NULL) {
6140 asc_board_t *boardp;
6141 struct device *dev;
6143 ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong) scp);
6144 tscp = REQPNEXT(scp);
6145 scp->host_scribble = NULL;
6147 boardp = ASC_BOARDP(scp->device->host);
6149 if (ASC_NARROW_BOARD(boardp))
6150 dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
6151 else
6152 dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
6154 if (scp->use_sg)
6155 dma_unmap_sg(dev, (struct scatterlist *)scp->request_buffer,
6156 scp->use_sg, scp->sc_data_direction);
6157 else if (scp->request_bufflen)
6158 dma_unmap_single(dev, scp->SCp.dma_handle,
6159 scp->request_bufflen, scp->sc_data_direction);
6161 ASC_STATS(scp->device->host, done);
6162 ASC_ASSERT(scp->scsi_done != NULL);
6164 scp->scsi_done(scp);
6166 scp = tscp;
6168 ASC_DBG(2, "asc_scsi_done_list: done\n");
6169 return;
6173 * Execute a single 'Scsi_Cmnd'.
6175 * The function 'done' is called when the request has been completed.
6177 * Scsi_Cmnd:
6179 * host - board controlling device
6180 * device - device to send command
6181 * target - target of device
6182 * lun - lun of device
6183 * cmd_len - length of SCSI CDB
6184 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
6185 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
6187 * if (use_sg == 0) {
6188 * request_buffer - buffer address for request
6189 * request_bufflen - length of request buffer
6190 * } else {
6191 * request_buffer - pointer to scatterlist structure
6194 * sense_buffer - sense command buffer
6196 * result (4 bytes of an int):
6197 * Byte Meaning
6198 * 0 SCSI Status Byte Code
6199 * 1 SCSI One Byte Message Code
6200 * 2 Host Error Code
6201 * 3 Mid-Level Error Code
6203 * host driver fields:
6204 * SCp - Scsi_Pointer used for command processing status
6205 * scsi_done - used to save caller's done function
6206 * host_scribble - used for pointer to another struct scsi_cmnd
6208 * If this function returns ASC_NOERROR the request has been enqueued
6209 * on the board's 'active' queue and will be completed from the
6210 * interrupt handler.
6212 * If this function returns ASC_NOERROR the request has been enqueued
6213 * on the board's 'done' queue and must be completed by the caller.
6215 * If ASC_BUSY is returned the request will be enqueued by the
6216 * caller on the target's waiting queue and re-tried later.
6218 STATIC int
6219 asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
6221 asc_board_t *boardp;
6222 ASC_DVC_VAR *asc_dvc_varp;
6223 ADV_DVC_VAR *adv_dvc_varp;
6224 ADV_SCSI_REQ_Q *adv_scsiqp;
6225 struct scsi_device *device;
6226 int ret;
6228 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
6229 (ulong) scp, (ulong) scp->scsi_done);
6231 boardp = ASC_BOARDP(scp->device->host);
6232 device = boardp->device[scp->device->id];
6234 if (ASC_NARROW_BOARD(boardp)) {
6236 * Build and execute Narrow Board request.
6239 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6242 * Build Asc Library request structure using the
6243 * global structures 'asc_scsi_req' and 'asc_sg_head'.
6245 * If an error is returned, then the request has been
6246 * queued on the board done queue. It will be completed
6247 * by the caller.
6249 * asc_build_req() can not return ASC_BUSY.
6251 if (asc_build_req(boardp, scp) == ASC_ERROR) {
6252 ASC_STATS(scp->device->host, build_error);
6253 return ASC_ERROR;
6257 * Execute the command. If there is no error, add the command
6258 * to the active queue.
6260 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
6261 case ASC_NOERROR:
6262 ASC_STATS(scp->device->host, exe_noerror);
6264 * Increment monotonically increasing per device successful
6265 * request counter. Wrapping doesn't matter.
6267 boardp->reqcnt[scp->device->id]++;
6268 asc_enqueue(&boardp->active, scp, ASC_BACK);
6269 ASC_DBG(1,
6270 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
6271 break;
6272 case ASC_BUSY:
6274 * Caller will enqueue request on the target's waiting queue
6275 * and retry later.
6277 ASC_STATS(scp->device->host, exe_busy);
6278 break;
6279 case ASC_ERROR:
6280 ASC_PRINT2(
6281 "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
6282 boardp->id, asc_dvc_varp->err_code);
6283 ASC_STATS(scp->device->host, exe_error);
6284 scp->result = HOST_BYTE(DID_ERROR);
6285 asc_enqueue(&boardp->done, scp, ASC_BACK);
6286 break;
6287 default:
6288 ASC_PRINT2(
6289 "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
6290 boardp->id, asc_dvc_varp->err_code);
6291 ASC_STATS(scp->device->host, exe_unknown);
6292 scp->result = HOST_BYTE(DID_ERROR);
6293 asc_enqueue(&boardp->done, scp, ASC_BACK);
6294 break;
6296 } else {
6298 * Build and execute Wide Board request.
6300 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6303 * Build and get a pointer to an Adv Library request structure.
6305 * If the request is successfully built then send it below,
6306 * otherwise return with an error.
6308 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
6309 case ASC_NOERROR:
6310 ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
6311 break;
6312 case ASC_BUSY:
6313 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
6315 * If busy is returned the request has not been enqueued.
6316 * It will be enqueued by the caller on the target's waiting
6317 * queue and retried later.
6319 * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg'
6320 * count wide board busy conditions. They are updated in
6321 * adv_build_req and adv_get_sglist, respectively.
6323 return ASC_BUSY;
6324 case ASC_ERROR:
6326 * If an error is returned, then the request has been
6327 * queued on the board done queue. It will be completed
6328 * by the caller.
6330 default:
6331 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
6332 ASC_STATS(scp->device->host, build_error);
6333 return ASC_ERROR;
6337 * Execute the command. If there is no error, add the command
6338 * to the active queue.
6340 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
6341 case ASC_NOERROR:
6342 ASC_STATS(scp->device->host, exe_noerror);
6344 * Increment monotonically increasing per device successful
6345 * request counter. Wrapping doesn't matter.
6347 boardp->reqcnt[scp->device->id]++;
6348 asc_enqueue(&boardp->active, scp, ASC_BACK);
6349 ASC_DBG(1,
6350 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
6351 break;
6352 case ASC_BUSY:
6354 * Caller will enqueue request on the target's waiting queue
6355 * and retry later.
6357 ASC_STATS(scp->device->host, exe_busy);
6358 break;
6359 case ASC_ERROR:
6360 ASC_PRINT2(
6361 "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
6362 boardp->id, adv_dvc_varp->err_code);
6363 ASC_STATS(scp->device->host, exe_error);
6364 scp->result = HOST_BYTE(DID_ERROR);
6365 asc_enqueue(&boardp->done, scp, ASC_BACK);
6366 break;
6367 default:
6368 ASC_PRINT2(
6369 "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
6370 boardp->id, adv_dvc_varp->err_code);
6371 ASC_STATS(scp->device->host, exe_unknown);
6372 scp->result = HOST_BYTE(DID_ERROR);
6373 asc_enqueue(&boardp->done, scp, ASC_BACK);
6374 break;
6378 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
6379 return ret;
6383 * Build a request structure for the Asc Library (Narrow Board).
6385 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
6386 * used to build the request.
6388 * If an error occurs, then queue the request on the board done
6389 * queue and return ASC_ERROR.
6391 STATIC int
6392 asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
6394 struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
6397 * Mutually exclusive access is required to 'asc_scsi_q' and
6398 * 'asc_sg_head' until after the request is started.
6400 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
6403 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
6405 asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
6408 * Build the ASC_SCSI_Q request.
6410 * For narrow boards a CDB length maximum of 12 bytes
6411 * is supported.
6413 if (scp->cmd_len > ASC_MAX_CDB_LEN) {
6414 ASC_PRINT3(
6415 "asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN %d\n",
6416 boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN);
6417 scp->result = HOST_BYTE(DID_ERROR);
6418 asc_enqueue(&boardp->done, scp, ASC_BACK);
6419 return ASC_ERROR;
6421 asc_scsi_q.cdbptr = &scp->cmnd[0];
6422 asc_scsi_q.q2.cdb_len = scp->cmd_len;
6423 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
6424 asc_scsi_q.q1.target_lun = scp->device->lun;
6425 asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
6426 asc_scsi_q.q1.sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
6427 asc_scsi_q.q1.sense_len = SCSI_SENSE_BUFFERSIZE;
6430 * If there are any outstanding requests for the current target,
6431 * then every 255th request send an ORDERED request. This heuristic
6432 * tries to retain the benefit of request sorting while preventing
6433 * request starvation. 255 is the max number of tags or pending commands
6434 * a device may have outstanding.
6436 * The request count is incremented below for every successfully
6437 * started request.
6440 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
6441 (boardp->reqcnt[scp->device->id] % 255) == 0) {
6442 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
6443 } else {
6444 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
6448 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
6449 * buffer command.
6451 if (scp->use_sg == 0) {
6453 * CDB request of single contiguous buffer.
6455 ASC_STATS(scp->device->host, cont_cnt);
6456 scp->SCp.dma_handle = scp->request_bufflen ?
6457 dma_map_single(dev, scp->request_buffer,
6458 scp->request_bufflen, scp->sc_data_direction) : 0;
6459 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
6460 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
6461 ASC_STATS_ADD(scp->device->host, cont_xfer,
6462 ASC_CEILING(scp->request_bufflen, 512));
6463 asc_scsi_q.q1.sg_queue_cnt = 0;
6464 asc_scsi_q.sg_head = NULL;
6465 } else {
6467 * CDB scatter-gather request list.
6469 int sgcnt;
6470 int use_sg;
6471 struct scatterlist *slp;
6473 slp = (struct scatterlist *)scp->request_buffer;
6474 use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
6476 if (use_sg > scp->device->host->sg_tablesize) {
6477 ASC_PRINT3(
6478 "asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
6479 boardp->id, use_sg, scp->device->host->sg_tablesize);
6480 dma_unmap_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
6481 scp->result = HOST_BYTE(DID_ERROR);
6482 asc_enqueue(&boardp->done, scp, ASC_BACK);
6483 return ASC_ERROR;
6486 ASC_STATS(scp->device->host, sg_cnt);
6489 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
6490 * structure to point to it.
6492 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
6494 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
6495 asc_scsi_q.sg_head = &asc_sg_head;
6496 asc_scsi_q.q1.data_cnt = 0;
6497 asc_scsi_q.q1.data_addr = 0;
6498 /* This is a byte value, otherwise it would need to be swapped. */
6499 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
6500 ASC_STATS_ADD(scp->device->host, sg_elem, asc_sg_head.entry_cnt);
6503 * Convert scatter-gather list into ASC_SG_HEAD list.
6505 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
6506 asc_sg_head.sg_list[sgcnt].addr = cpu_to_le32(sg_dma_address(slp));
6507 asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(sg_dma_len(slp));
6508 ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512));
6512 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
6513 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6515 return ASC_NOERROR;
6519 * Build a request structure for the Adv Library (Wide Board).
6521 * If an adv_req_t can not be allocated to issue the request,
6522 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
6524 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
6525 * microcode for DMA addresses or math operations are byte swapped
6526 * to little-endian order.
6528 STATIC int
6529 adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
6530 ADV_SCSI_REQ_Q **adv_scsiqpp)
6532 adv_req_t *reqp;
6533 ADV_SCSI_REQ_Q *scsiqp;
6534 int i;
6535 int ret;
6536 struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
6539 * Allocate an adv_req_t structure from the board to execute
6540 * the command.
6542 if (boardp->adv_reqp == NULL) {
6543 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
6544 ASC_STATS(scp->device->host, adv_build_noreq);
6545 return ASC_BUSY;
6546 } else {
6547 reqp = boardp->adv_reqp;
6548 boardp->adv_reqp = reqp->next_reqp;
6549 reqp->next_reqp = NULL;
6553 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
6555 scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
6558 * Initialize the structure.
6560 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
6563 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
6565 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
6568 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
6570 reqp->cmndp = scp;
6573 * Build the ADV_SCSI_REQ_Q request.
6577 * Set CDB length and copy it to the request structure.
6578 * For wide boards a CDB length maximum of 16 bytes
6579 * is supported.
6581 if (scp->cmd_len > ADV_MAX_CDB_LEN) {
6582 ASC_PRINT3(
6583 "adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n",
6584 boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
6585 scp->result = HOST_BYTE(DID_ERROR);
6586 asc_enqueue(&boardp->done, scp, ASC_BACK);
6587 return ASC_ERROR;
6589 scsiqp->cdb_len = scp->cmd_len;
6590 /* Copy first 12 CDB bytes to cdb[]. */
6591 for (i = 0; i < scp->cmd_len && i < 12; i++) {
6592 scsiqp->cdb[i] = scp->cmnd[i];
6594 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
6595 for (; i < scp->cmd_len; i++) {
6596 scsiqp->cdb16[i - 12] = scp->cmnd[i];
6599 scsiqp->target_id = scp->device->id;
6600 scsiqp->target_lun = scp->device->lun;
6602 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
6603 scsiqp->sense_len = SCSI_SENSE_BUFFERSIZE;
6606 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
6607 * buffer command.
6610 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
6611 scsiqp->vdata_addr = scp->request_buffer;
6612 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
6614 if (scp->use_sg == 0) {
6616 * CDB request of single contiguous buffer.
6618 reqp->sgblkp = NULL;
6619 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
6620 if (scp->request_bufflen) {
6621 scsiqp->vdata_addr = scp->request_buffer;
6622 scp->SCp.dma_handle =
6623 dma_map_single(dev, scp->request_buffer,
6624 scp->request_bufflen, scp->sc_data_direction);
6625 } else {
6626 scsiqp->vdata_addr = NULL;
6627 scp->SCp.dma_handle = 0;
6629 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
6630 scsiqp->sg_list_ptr = NULL;
6631 scsiqp->sg_real_addr = 0;
6632 ASC_STATS(scp->device->host, cont_cnt);
6633 ASC_STATS_ADD(scp->device->host, cont_xfer,
6634 ASC_CEILING(scp->request_bufflen, 512));
6635 } else {
6637 * CDB scatter-gather request list.
6639 struct scatterlist *slp;
6640 int use_sg;
6642 slp = (struct scatterlist *)scp->request_buffer;
6643 use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
6645 if (use_sg > ADV_MAX_SG_LIST) {
6646 ASC_PRINT3(
6647 "adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
6648 boardp->id, use_sg, scp->device->host->sg_tablesize);
6649 dma_unmap_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
6650 scp->result = HOST_BYTE(DID_ERROR);
6651 asc_enqueue(&boardp->done, scp, ASC_BACK);
6654 * Free the 'adv_req_t' structure by adding it back to the
6655 * board free list.
6657 reqp->next_reqp = boardp->adv_reqp;
6658 boardp->adv_reqp = reqp;
6660 return ASC_ERROR;
6663 if ((ret = adv_get_sglist(boardp, reqp, scp, use_sg)) != ADV_SUCCESS) {
6665 * Free the adv_req_t structure by adding it back to the
6666 * board free list.
6668 reqp->next_reqp = boardp->adv_reqp;
6669 boardp->adv_reqp = reqp;
6671 return ret;
6674 ASC_STATS(scp->device->host, sg_cnt);
6675 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
6678 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
6679 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6681 *adv_scsiqpp = scsiqp;
6683 return ASC_NOERROR;
6687 * Build scatter-gather list for Adv Library (Wide Board).
6689 * Additional ADV_SG_BLOCK structures will need to be allocated
6690 * if the total number of scatter-gather elements exceeds
6691 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
6692 * assumed to be physically contiguous.
6694 * Return:
6695 * ADV_SUCCESS(1) - SG List successfully created
6696 * ADV_ERROR(-1) - SG List creation failed
6698 STATIC int
6699 adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, int use_sg)
6701 adv_sgblk_t *sgblkp;
6702 ADV_SCSI_REQ_Q *scsiqp;
6703 struct scatterlist *slp;
6704 int sg_elem_cnt;
6705 ADV_SG_BLOCK *sg_block, *prev_sg_block;
6706 ADV_PADDR sg_block_paddr;
6707 int i;
6709 scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
6710 slp = (struct scatterlist *) scp->request_buffer;
6711 sg_elem_cnt = use_sg;
6712 prev_sg_block = NULL;
6713 reqp->sgblkp = NULL;
6718 * Allocate a 'adv_sgblk_t' structure from the board free
6719 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
6720 * (15) scatter-gather elements.
6722 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
6723 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
6724 ASC_STATS(scp->device->host, adv_build_nosg);
6727 * Allocation failed. Free 'adv_sgblk_t' structures already
6728 * allocated for the request.
6730 while ((sgblkp = reqp->sgblkp) != NULL)
6732 /* Remove 'sgblkp' from the request list. */
6733 reqp->sgblkp = sgblkp->next_sgblkp;
6735 /* Add 'sgblkp' to the board free list. */
6736 sgblkp->next_sgblkp = boardp->adv_sgblkp;
6737 boardp->adv_sgblkp = sgblkp;
6739 return ASC_BUSY;
6740 } else {
6741 /* Complete 'adv_sgblk_t' board allocation. */
6742 boardp->adv_sgblkp = sgblkp->next_sgblkp;
6743 sgblkp->next_sgblkp = NULL;
6746 * Get 8 byte aligned virtual and physical addresses for
6747 * the allocated ADV_SG_BLOCK structure.
6749 sg_block = (ADV_SG_BLOCK *) ADV_8BALIGN(&sgblkp->sg_block);
6750 sg_block_paddr = virt_to_bus(sg_block);
6753 * Check if this is the first 'adv_sgblk_t' for the request.
6755 if (reqp->sgblkp == NULL)
6757 /* Request's first scatter-gather block. */
6758 reqp->sgblkp = sgblkp;
6761 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
6762 * address pointers.
6764 scsiqp->sg_list_ptr = sg_block;
6765 scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr);
6766 } else
6768 /* Request's second or later scatter-gather block. */
6769 sgblkp->next_sgblkp = reqp->sgblkp;
6770 reqp->sgblkp = sgblkp;
6773 * Point the previous ADV_SG_BLOCK structure to
6774 * the newly allocated ADV_SG_BLOCK structure.
6776 ASC_ASSERT(prev_sg_block != NULL);
6777 prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr);
6781 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
6783 sg_block->sg_list[i].sg_addr = cpu_to_le32(sg_dma_address(slp));
6784 sg_block->sg_list[i].sg_count = cpu_to_le32(sg_dma_len(slp));
6785 ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512));
6787 if (--sg_elem_cnt == 0)
6788 { /* Last ADV_SG_BLOCK and scatter-gather entry. */
6789 sg_block->sg_cnt = i + 1;
6790 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
6791 return ADV_SUCCESS;
6793 slp++;
6795 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
6796 prev_sg_block = sg_block;
6798 while (1);
6799 /* NOTREACHED */
6803 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
6805 * Interrupt callback function for the Narrow SCSI Asc Library.
6807 STATIC void
6808 asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
6810 asc_board_t *boardp;
6811 struct scsi_cmnd *scp;
6812 struct Scsi_Host *shp;
6813 int i;
6815 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
6816 (ulong) asc_dvc_varp, (ulong) qdonep);
6817 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
6820 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
6821 * command that has been completed.
6823 scp = (struct scsi_cmnd *) ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
6824 ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong) scp);
6826 if (scp == NULL) {
6827 ASC_PRINT("asc_isr_callback: scp is NULL\n");
6828 return;
6830 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
6833 * If the request's host pointer is not valid, display a
6834 * message and return.
6836 shp = scp->device->host;
6837 for (i = 0; i < asc_board_count; i++) {
6838 if (asc_host[i] == shp) {
6839 break;
6842 if (i == asc_board_count) {
6843 ASC_PRINT2(
6844 "asc_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
6845 (ulong) scp, (ulong) shp);
6846 return;
6849 ASC_STATS(shp, callback);
6850 ASC_DBG1(1, "asc_isr_callback: shp 0x%lx\n", (ulong) shp);
6853 * If the request isn't found on the active queue, it may
6854 * have been removed to handle a reset request.
6855 * Display a message and return.
6857 boardp = ASC_BOARDP(shp);
6858 ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
6859 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
6860 ASC_PRINT2(
6861 "asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
6862 boardp->id, (ulong) scp);
6863 return;
6867 * 'qdonep' contains the command's ending status.
6869 switch (qdonep->d3.done_stat) {
6870 case QD_NO_ERROR:
6871 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
6872 scp->result = 0;
6875 * If an INQUIRY command completed successfully, then call
6876 * the AscInquiryHandling() function to set-up the device.
6878 if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 &&
6879 (scp->request_bufflen - qdonep->remain_bytes) >= 8)
6881 AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7,
6882 (ASC_SCSI_INQUIRY *) scp->request_buffer);
6886 * Check for an underrun condition.
6888 * If there was no error and an underrun condition, then
6889 * then return the number of underrun bytes.
6891 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
6892 qdonep->remain_bytes <= scp->request_bufflen) {
6893 ASC_DBG1(1, "asc_isr_callback: underrun condition %u bytes\n",
6894 (unsigned) qdonep->remain_bytes);
6895 scp->resid = qdonep->remain_bytes;
6897 break;
6899 case QD_WITH_ERROR:
6900 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
6901 switch (qdonep->d3.host_stat) {
6902 case QHSTA_NO_ERROR:
6903 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
6904 ASC_DBG(2, "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
6905 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
6906 SCSI_SENSE_BUFFERSIZE);
6908 * Note: The 'status_byte()' macro used by target drivers
6909 * defined in scsi.h shifts the status byte returned by
6910 * host drivers right by 1 bit. This is why target drivers
6911 * also use right shifted status byte definitions. For
6912 * instance target drivers use CHECK_CONDITION, defined to
6913 * 0x1, instead of the SCSI defined check condition value
6914 * of 0x2. Host drivers are supposed to return the status
6915 * byte as it is defined by SCSI.
6917 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
6918 STATUS_BYTE(qdonep->d3.scsi_stat);
6919 } else {
6920 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
6922 break;
6924 default:
6925 /* QHSTA error occurred */
6926 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
6927 qdonep->d3.host_stat);
6928 scp->result = HOST_BYTE(DID_BAD_TARGET);
6929 break;
6931 break;
6933 case QD_ABORTED_BY_HOST:
6934 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
6935 scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.scsi_msg) |
6936 STATUS_BYTE(qdonep->d3.scsi_stat);
6937 break;
6939 default:
6940 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n", qdonep->d3.done_stat);
6941 scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
6942 STATUS_BYTE(qdonep->d3.scsi_stat);
6943 break;
6947 * If the 'init_tidmask' bit isn't already set for the target and the
6948 * current request finished normally, then set the bit for the target
6949 * to indicate that a device is present.
6951 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
6952 qdonep->d3.done_stat == QD_NO_ERROR &&
6953 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
6954 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
6958 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
6959 * function, add the command to the end of the board's done queue.
6960 * The done function for the command will be called from
6961 * advansys_interrupt().
6963 asc_enqueue(&boardp->done, scp, ASC_BACK);
6965 return;
6969 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
6971 * Callback function for the Wide SCSI Adv Library.
6973 STATIC void
6974 adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
6976 asc_board_t *boardp;
6977 adv_req_t *reqp;
6978 adv_sgblk_t *sgblkp;
6979 struct scsi_cmnd *scp;
6980 struct Scsi_Host *shp;
6981 int i;
6982 ADV_DCNT resid_cnt;
6985 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
6986 (ulong) adv_dvc_varp, (ulong) scsiqp);
6987 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
6990 * Get the adv_req_t structure for the command that has been
6991 * completed. The adv_req_t structure actually contains the
6992 * completed ADV_SCSI_REQ_Q structure.
6994 reqp = (adv_req_t *) ADV_U32_TO_VADDR(scsiqp->srb_ptr);
6995 ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong) reqp);
6996 if (reqp == NULL) {
6997 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
6998 return;
7002 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
7003 * command that has been completed.
7005 * Note: The adv_req_t request structure and adv_sgblk_t structure,
7006 * if any, are dropped, because a board structure pointer can not be
7007 * determined.
7009 scp = reqp->cmndp;
7010 ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong) scp);
7011 if (scp == NULL) {
7012 ASC_PRINT("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
7013 return;
7015 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
7018 * If the request's host pointer is not valid, display a message
7019 * and return.
7021 shp = scp->device->host;
7022 for (i = 0; i < asc_board_count; i++) {
7023 if (asc_host[i] == shp) {
7024 break;
7028 * Note: If the host structure is not found, the adv_req_t request
7029 * structure and adv_sgblk_t structure, if any, is dropped.
7031 if (i == asc_board_count) {
7032 ASC_PRINT2(
7033 "adv_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
7034 (ulong) scp, (ulong) shp);
7035 return;
7038 ASC_STATS(shp, callback);
7039 ASC_DBG1(1, "adv_isr_callback: shp 0x%lx\n", (ulong) shp);
7042 * If the request isn't found on the active queue, it may have been
7043 * removed to handle a reset request. Display a message and return.
7045 * Note: Because the structure may still be in use don't attempt
7046 * to free the adv_req_t and adv_sgblk_t, if any, structures.
7048 boardp = ASC_BOARDP(shp);
7049 ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
7050 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
7051 ASC_PRINT2(
7052 "adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
7053 boardp->id, (ulong) scp);
7054 return;
7058 * 'done_status' contains the command's ending status.
7060 switch (scsiqp->done_status) {
7061 case QD_NO_ERROR:
7062 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
7063 scp->result = 0;
7066 * Check for an underrun condition.
7068 * If there was no error and an underrun condition, then
7069 * then return the number of underrun bytes.
7071 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
7072 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
7073 resid_cnt <= scp->request_bufflen) {
7074 ASC_DBG1(1, "adv_isr_callback: underrun condition %lu bytes\n",
7075 (ulong) resid_cnt);
7076 scp->resid = resid_cnt;
7078 break;
7080 case QD_WITH_ERROR:
7081 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
7082 switch (scsiqp->host_status) {
7083 case QHSTA_NO_ERROR:
7084 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
7085 ASC_DBG(2, "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
7086 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
7087 SCSI_SENSE_BUFFERSIZE);
7089 * Note: The 'status_byte()' macro used by target drivers
7090 * defined in scsi.h shifts the status byte returned by
7091 * host drivers right by 1 bit. This is why target drivers
7092 * also use right shifted status byte definitions. For
7093 * instance target drivers use CHECK_CONDITION, defined to
7094 * 0x1, instead of the SCSI defined check condition value
7095 * of 0x2. Host drivers are supposed to return the status
7096 * byte as it is defined by SCSI.
7098 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
7099 STATUS_BYTE(scsiqp->scsi_status);
7100 } else {
7101 scp->result = STATUS_BYTE(scsiqp->scsi_status);
7103 break;
7105 default:
7106 /* Some other QHSTA error occurred. */
7107 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
7108 scsiqp->host_status);
7109 scp->result = HOST_BYTE(DID_BAD_TARGET);
7110 break;
7112 break;
7114 case QD_ABORTED_BY_HOST:
7115 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
7116 scp->result = HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
7117 break;
7119 default:
7120 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n", scsiqp->done_status);
7121 scp->result = HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
7122 break;
7126 * If the 'init_tidmask' bit isn't already set for the target and the
7127 * current request finished normally, then set the bit for the target
7128 * to indicate that a device is present.
7130 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
7131 scsiqp->done_status == QD_NO_ERROR &&
7132 scsiqp->host_status == QHSTA_NO_ERROR) {
7133 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
7137 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
7138 * function, add the command to the end of the board's done queue.
7139 * The done function for the command will be called from
7140 * advansys_interrupt().
7142 asc_enqueue(&boardp->done, scp, ASC_BACK);
7145 * Free all 'adv_sgblk_t' structures allocated for the request.
7147 while ((sgblkp = reqp->sgblkp) != NULL)
7149 /* Remove 'sgblkp' from the request list. */
7150 reqp->sgblkp = sgblkp->next_sgblkp;
7152 /* Add 'sgblkp' to the board free list. */
7153 sgblkp->next_sgblkp = boardp->adv_sgblkp;
7154 boardp->adv_sgblkp = sgblkp;
7158 * Free the adv_req_t structure used with the command by adding
7159 * it back to the board free list.
7161 reqp->next_reqp = boardp->adv_reqp;
7162 boardp->adv_reqp = reqp;
7164 ASC_DBG(1, "adv_isr_callback: done\n");
7166 return;
7170 * adv_async_callback() - Adv Library asynchronous event callback function.
7172 STATIC void
7173 adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
7175 switch (code)
7177 case ADV_ASYNC_SCSI_BUS_RESET_DET:
7179 * The firmware detected a SCSI Bus reset.
7181 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
7182 break;
7184 case ADV_ASYNC_RDMA_FAILURE:
7186 * Handle RDMA failure by resetting the SCSI Bus and
7187 * possibly the chip if it is unresponsive. Log the error
7188 * with a unique code.
7190 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
7191 AdvResetChipAndSB(adv_dvc_varp);
7192 break;
7194 case ADV_HOST_SCSI_BUS_RESET:
7196 * Host generated SCSI bus reset occurred.
7198 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
7199 break;
7201 default:
7202 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
7203 break;
7208 * Add a 'REQP' to the end of specified queue. Set 'tidmask'
7209 * to indicate a command is queued for the device.
7211 * 'flag' may be either ASC_FRONT or ASC_BACK.
7213 * 'REQPNEXT(reqp)' returns reqp's next pointer.
7215 STATIC void
7216 asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
7218 int tid;
7220 ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
7221 (ulong) ascq, (ulong) reqp, flag);
7222 ASC_ASSERT(reqp != NULL);
7223 ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
7224 tid = REQPTID(reqp);
7225 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7226 if (flag == ASC_FRONT) {
7227 reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
7228 ascq->q_first[tid] = reqp;
7229 /* If the queue was empty, set the last pointer. */
7230 if (ascq->q_last[tid] == NULL) {
7231 ascq->q_last[tid] = reqp;
7233 } else { /* ASC_BACK */
7234 if (ascq->q_last[tid] != NULL) {
7235 ascq->q_last[tid]->host_scribble = (unsigned char *)reqp;
7237 ascq->q_last[tid] = reqp;
7238 reqp->host_scribble = NULL;
7239 /* If the queue was empty, set the first pointer. */
7240 if (ascq->q_first[tid] == NULL) {
7241 ascq->q_first[tid] = reqp;
7244 /* The queue has at least one entry, set its bit. */
7245 ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
7246 #ifdef ADVANSYS_STATS
7247 /* Maintain request queue statistics. */
7248 ascq->q_tot_cnt[tid]++;
7249 ascq->q_cur_cnt[tid]++;
7250 if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
7251 ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
7252 ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
7253 tid, ascq->q_max_cnt[tid]);
7255 REQPTIME(reqp) = REQTIMESTAMP();
7256 #endif /* ADVANSYS_STATS */
7257 ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong) reqp);
7258 return;
7262 * Return first queued 'REQP' on the specified queue for
7263 * the specified target device. Clear the 'tidmask' bit for
7264 * the device if no more commands are left queued for it.
7266 * 'REQPNEXT(reqp)' returns reqp's next pointer.
7268 STATIC REQP
7269 asc_dequeue(asc_queue_t *ascq, int tid)
7271 REQP reqp;
7273 ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong) ascq, tid);
7274 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7275 if ((reqp = ascq->q_first[tid]) != NULL) {
7276 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
7277 ascq->q_first[tid] = REQPNEXT(reqp);
7278 /* If the queue is empty, clear its bit and the last pointer. */
7279 if (ascq->q_first[tid] == NULL) {
7280 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7281 ASC_ASSERT(ascq->q_last[tid] == reqp);
7282 ascq->q_last[tid] = NULL;
7284 #ifdef ADVANSYS_STATS
7285 /* Maintain request queue statistics. */
7286 ascq->q_cur_cnt[tid]--;
7287 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
7288 REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
7289 #endif /* ADVANSYS_STATS */
7291 ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong) reqp);
7292 return reqp;
7296 * Return a pointer to a singly linked list of all the requests queued
7297 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
7299 * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
7300 * the last request returned in the singly linked list.
7302 * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
7303 * then all queued requests are concatenated into one list and
7304 * returned.
7306 * Note: If 'lastpp' is used to append a new list to the end of
7307 * an old list, only change the old list last pointer if '*lastpp'
7308 * (or the function return value) is not NULL, i.e. use a temporary
7309 * variable for 'lastpp' and check its value after the function return
7310 * before assigning it to the list last pointer.
7312 * Unfortunately collecting queuing time statistics adds overhead to
7313 * the function that isn't inherent to the function's algorithm.
7315 STATIC REQP
7316 asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
7318 REQP firstp, lastp;
7319 int i;
7321 ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong) ascq, tid);
7322 ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
7325 * If 'tid' is not ASC_TID_ALL, return requests only for
7326 * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
7327 * requests for all tids.
7329 if (tid != ASC_TID_ALL) {
7330 /* Return all requests for the specified 'tid'. */
7331 if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
7332 /* List is empty; Set first and last return pointers to NULL. */
7333 firstp = lastp = NULL;
7334 } else {
7335 firstp = ascq->q_first[tid];
7336 lastp = ascq->q_last[tid];
7337 ascq->q_first[tid] = ascq->q_last[tid] = NULL;
7338 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7339 #ifdef ADVANSYS_STATS
7341 REQP reqp;
7342 ascq->q_cur_cnt[tid] = 0;
7343 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
7344 REQTIMESTAT("asc_dequeue_list", ascq, reqp, tid);
7347 #endif /* ADVANSYS_STATS */
7349 } else {
7350 /* Return all requests for all tids. */
7351 firstp = lastp = NULL;
7352 for (i = 0; i <= ADV_MAX_TID; i++) {
7353 if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
7354 if (firstp == NULL) {
7355 firstp = ascq->q_first[i];
7356 lastp = ascq->q_last[i];
7357 } else {
7358 ASC_ASSERT(lastp != NULL);
7359 lastp->host_scribble = (unsigned char *)ascq->q_first[i];
7360 lastp = ascq->q_last[i];
7362 ascq->q_first[i] = ascq->q_last[i] = NULL;
7363 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7364 #ifdef ADVANSYS_STATS
7365 ascq->q_cur_cnt[i] = 0;
7366 #endif /* ADVANSYS_STATS */
7369 #ifdef ADVANSYS_STATS
7371 REQP reqp;
7372 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
7373 REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->device->id);
7376 #endif /* ADVANSYS_STATS */
7378 if (lastpp) {
7379 *lastpp = lastp;
7381 ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong) firstp);
7382 return firstp;
7386 * Remove the specified 'REQP' from the specified queue for
7387 * the specified target device. Clear the 'tidmask' bit for the
7388 * device if no more commands are left queued for it.
7390 * 'REQPNEXT(reqp)' returns reqp's the next pointer.
7392 * Return ASC_TRUE if the command was found and removed,
7393 * otherwise return ASC_FALSE.
7395 STATIC int
7396 asc_rmqueue(asc_queue_t *ascq, REQP reqp)
7398 REQP currp, prevp;
7399 int tid;
7400 int ret = ASC_FALSE;
7402 ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
7403 (ulong) ascq, (ulong) reqp);
7404 ASC_ASSERT(reqp != NULL);
7406 tid = REQPTID(reqp);
7407 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7410 * Handle the common case of 'reqp' being the first
7411 * entry on the queue.
7413 if (reqp == ascq->q_first[tid]) {
7414 ret = ASC_TRUE;
7415 ascq->q_first[tid] = REQPNEXT(reqp);
7416 /* If the queue is now empty, clear its bit and the last pointer. */
7417 if (ascq->q_first[tid] == NULL) {
7418 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7419 ASC_ASSERT(ascq->q_last[tid] == reqp);
7420 ascq->q_last[tid] = NULL;
7422 } else if (ascq->q_first[tid] != NULL) {
7423 ASC_ASSERT(ascq->q_last[tid] != NULL);
7425 * Because the case of 'reqp' being the first entry has been
7426 * handled above and it is known the queue is not empty, if
7427 * 'reqp' is found on the queue it is guaranteed the queue will
7428 * not become empty and that 'q_first[tid]' will not be changed.
7430 * Set 'prevp' to the first entry, 'currp' to the second entry,
7431 * and search for 'reqp'.
7433 for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
7434 currp; prevp = currp, currp = REQPNEXT(currp)) {
7435 if (currp == reqp) {
7436 ret = ASC_TRUE;
7437 prevp->host_scribble = (unsigned char *)REQPNEXT(currp);
7438 reqp->host_scribble = NULL;
7439 if (ascq->q_last[tid] == reqp) {
7440 ascq->q_last[tid] = prevp;
7442 break;
7446 #ifdef ADVANSYS_STATS
7447 /* Maintain request queue statistics. */
7448 if (ret == ASC_TRUE) {
7449 ascq->q_cur_cnt[tid]--;
7450 REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
7452 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
7453 #endif /* ADVANSYS_STATS */
7454 ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong) reqp, ret);
7455 return ret;
7459 * Execute as many queued requests as possible for the specified queue.
7461 * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd.
7463 STATIC void
7464 asc_execute_queue(asc_queue_t *ascq)
7466 ADV_SCSI_BIT_ID_TYPE scan_tidmask;
7467 REQP reqp;
7468 int i;
7470 ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong) ascq);
7472 * Execute queued commands for devices attached to
7473 * the current board in round-robin fashion.
7475 scan_tidmask = ascq->q_tidmask;
7476 do {
7477 for (i = 0; i <= ADV_MAX_TID; i++) {
7478 if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
7479 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
7480 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7481 } else if (asc_execute_scsi_cmnd((struct scsi_cmnd *) reqp)
7482 == ASC_BUSY) {
7483 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7485 * The request returned ASC_BUSY. Enqueue at the front of
7486 * target's waiting list to maintain correct ordering.
7488 asc_enqueue(ascq, reqp, ASC_FRONT);
7492 } while (scan_tidmask);
7493 return;
7496 #ifdef CONFIG_PROC_FS
7498 * asc_prt_board_devices()
7500 * Print driver information for devices attached to the board.
7502 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7503 * cf. asc_prt_line().
7505 * Return the number of characters copied into 'cp'. No more than
7506 * 'cplen' characters will be copied to 'cp'.
7508 STATIC int
7509 asc_prt_board_devices(struct Scsi_Host *shp, char *cp, int cplen)
7511 asc_board_t *boardp;
7512 int leftlen;
7513 int totlen;
7514 int len;
7515 int chip_scsi_id;
7516 int i;
7518 boardp = ASC_BOARDP(shp);
7519 leftlen = cplen;
7520 totlen = len = 0;
7522 len = asc_prt_line(cp, leftlen,
7523 "\nDevice Information for AdvanSys SCSI Host %d:\n", shp->host_no);
7524 ASC_PRT_NEXT();
7526 if (ASC_NARROW_BOARD(boardp)) {
7527 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7528 } else {
7529 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7532 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
7533 ASC_PRT_NEXT();
7534 for (i = 0; i <= ADV_MAX_TID; i++) {
7535 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
7536 len = asc_prt_line(cp, leftlen, " %X,", i);
7537 ASC_PRT_NEXT();
7540 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
7541 ASC_PRT_NEXT();
7543 return totlen;
7547 * Display Wide Board BIOS Information.
7549 STATIC int
7550 asc_prt_adv_bios(struct Scsi_Host *shp, char *cp, int cplen)
7552 asc_board_t *boardp;
7553 int leftlen;
7554 int totlen;
7555 int len;
7556 ushort major, minor, letter;
7558 boardp = ASC_BOARDP(shp);
7559 leftlen = cplen;
7560 totlen = len = 0;
7562 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
7563 ASC_PRT_NEXT();
7566 * If the BIOS saved a valid signature, then fill in
7567 * the BIOS code segment base address.
7569 if (boardp->bios_signature != 0x55AA) {
7570 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
7571 ASC_PRT_NEXT();
7572 len = asc_prt_line(cp, leftlen,
7573 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
7574 ASC_PRT_NEXT();
7575 len = asc_prt_line(cp, leftlen,
7576 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
7577 ASC_PRT_NEXT();
7578 } else {
7579 major = (boardp->bios_version >> 12) & 0xF;
7580 minor = (boardp->bios_version >> 8) & 0xF;
7581 letter = (boardp->bios_version & 0xFF);
7583 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
7584 major, minor, letter >= 26 ? '?' : letter + 'A');
7585 ASC_PRT_NEXT();
7588 * Current available ROM BIOS release is 3.1I for UW
7589 * and 3.2I for U2W. This code doesn't differentiate
7590 * UW and U2W boards.
7592 if (major < 3 || (major <= 3 && minor < 1) ||
7593 (major <= 3 && minor <= 1 && letter < ('I'- 'A'))) {
7594 len = asc_prt_line(cp, leftlen,
7595 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
7596 ASC_PRT_NEXT();
7597 len = asc_prt_line(cp, leftlen,
7598 "ftp://ftp.connectcom.net/pub\n");
7599 ASC_PRT_NEXT();
7603 return totlen;
7607 * Add serial number to information bar if signature AAh
7608 * is found in at bit 15-9 (7 bits) of word 1.
7610 * Serial Number consists fo 12 alpha-numeric digits.
7612 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
7613 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
7614 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
7615 * 5 - Product revision (A-J) Word0: " "
7617 * Signature Word1: 15-9 (7 bits)
7618 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
7619 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
7621 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
7623 * Note 1: Only production cards will have a serial number.
7625 * Note 2: Signature is most significant 7 bits (0xFE).
7627 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
7629 STATIC int
7630 asc_get_eeprom_string(ushort *serialnum, uchar *cp)
7632 ushort w, num;
7634 if ((serialnum[1] & 0xFE00) != ((ushort) 0xAA << 8)) {
7635 return ASC_FALSE;
7636 } else {
7638 * First word - 6 digits.
7640 w = serialnum[0];
7642 /* Product type - 1st digit. */
7643 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
7644 /* Product type is P=Prototype */
7645 *cp += 0x8;
7647 cp++;
7649 /* Manufacturing location - 2nd digit. */
7650 *cp++ = 'A' + ((w & 0x1C00) >> 10);
7652 /* Product ID - 3rd, 4th digits. */
7653 num = w & 0x3FF;
7654 *cp++ = '0' + (num / 100);
7655 num %= 100;
7656 *cp++ = '0' + (num / 10);
7658 /* Product revision - 5th digit. */
7659 *cp++ = 'A' + (num % 10);
7662 * Second word
7664 w = serialnum[1];
7667 * Year - 6th digit.
7669 * If bit 15 of third word is set, then the
7670 * last digit of the year is greater than 7.
7672 if (serialnum[2] & 0x8000) {
7673 *cp++ = '8' + ((w & 0x1C0) >> 6);
7674 } else {
7675 *cp++ = '0' + ((w & 0x1C0) >> 6);
7678 /* Week of year - 7th, 8th digits. */
7679 num = w & 0x003F;
7680 *cp++ = '0' + num / 10;
7681 num %= 10;
7682 *cp++ = '0' + num;
7685 * Third word
7687 w = serialnum[2] & 0x7FFF;
7689 /* Serial number - 9th digit. */
7690 *cp++ = 'A' + (w / 1000);
7692 /* 10th, 11th, 12th digits. */
7693 num = w % 1000;
7694 *cp++ = '0' + num / 100;
7695 num %= 100;
7696 *cp++ = '0' + num / 10;
7697 num %= 10;
7698 *cp++ = '0' + num;
7700 *cp = '\0'; /* Null Terminate the string. */
7701 return ASC_TRUE;
7706 * asc_prt_asc_board_eeprom()
7708 * Print board EEPROM configuration.
7710 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7711 * cf. asc_prt_line().
7713 * Return the number of characters copied into 'cp'. No more than
7714 * 'cplen' characters will be copied to 'cp'.
7716 STATIC int
7717 asc_prt_asc_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
7719 asc_board_t *boardp;
7720 ASC_DVC_VAR *asc_dvc_varp;
7721 int leftlen;
7722 int totlen;
7723 int len;
7724 ASCEEP_CONFIG *ep;
7725 int i;
7726 #ifdef CONFIG_ISA
7727 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
7728 #endif /* CONFIG_ISA */
7729 uchar serialstr[13];
7731 boardp = ASC_BOARDP(shp);
7732 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
7733 ep = &boardp->eep_config.asc_eep;
7735 leftlen = cplen;
7736 totlen = len = 0;
7738 len = asc_prt_line(cp, leftlen,
7739 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
7740 ASC_PRT_NEXT();
7742 if (asc_get_eeprom_string((ushort *) &ep->adapter_info[0], serialstr) ==
7743 ASC_TRUE) {
7744 len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
7745 ASC_PRT_NEXT();
7746 } else {
7747 if (ep->adapter_info[5] == 0xBB) {
7748 len = asc_prt_line(cp, leftlen,
7749 " Default Settings Used for EEPROM-less Adapter.\n");
7750 ASC_PRT_NEXT();
7751 } else {
7752 len = asc_prt_line(cp, leftlen,
7753 " Serial Number Signature Not Present.\n");
7754 ASC_PRT_NEXT();
7758 len = asc_prt_line(cp, leftlen,
7759 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7760 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng, ep->max_tag_qng);
7761 ASC_PRT_NEXT();
7763 len = asc_prt_line(cp, leftlen,
7764 " cntl 0x%x, no_scam 0x%x\n",
7765 ep->cntl, ep->no_scam);
7766 ASC_PRT_NEXT();
7768 len = asc_prt_line(cp, leftlen,
7769 " Target ID: ");
7770 ASC_PRT_NEXT();
7771 for (i = 0; i <= ASC_MAX_TID; i++) {
7772 len = asc_prt_line(cp, leftlen, " %d", i);
7773 ASC_PRT_NEXT();
7775 len = asc_prt_line(cp, leftlen, "\n");
7776 ASC_PRT_NEXT();
7778 len = asc_prt_line(cp, leftlen,
7779 " Disconnects: ");
7780 ASC_PRT_NEXT();
7781 for (i = 0; i <= ASC_MAX_TID; i++) {
7782 len = asc_prt_line(cp, leftlen, " %c",
7783 (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7784 ASC_PRT_NEXT();
7786 len = asc_prt_line(cp, leftlen, "\n");
7787 ASC_PRT_NEXT();
7789 len = asc_prt_line(cp, leftlen,
7790 " Command Queuing: ");
7791 ASC_PRT_NEXT();
7792 for (i = 0; i <= ASC_MAX_TID; i++) {
7793 len = asc_prt_line(cp, leftlen, " %c",
7794 (ep->use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7795 ASC_PRT_NEXT();
7797 len = asc_prt_line(cp, leftlen, "\n");
7798 ASC_PRT_NEXT();
7800 len = asc_prt_line(cp, leftlen,
7801 " Start Motor: ");
7802 ASC_PRT_NEXT();
7803 for (i = 0; i <= ASC_MAX_TID; i++) {
7804 len = asc_prt_line(cp, leftlen, " %c",
7805 (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7806 ASC_PRT_NEXT();
7808 len = asc_prt_line(cp, leftlen, "\n");
7809 ASC_PRT_NEXT();
7811 len = asc_prt_line(cp, leftlen,
7812 " Synchronous Transfer:");
7813 ASC_PRT_NEXT();
7814 for (i = 0; i <= ASC_MAX_TID; i++) {
7815 len = asc_prt_line(cp, leftlen, " %c",
7816 (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7817 ASC_PRT_NEXT();
7819 len = asc_prt_line(cp, leftlen, "\n");
7820 ASC_PRT_NEXT();
7822 #ifdef CONFIG_ISA
7823 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
7824 len = asc_prt_line(cp, leftlen,
7825 " Host ISA DMA speed: %d MB/S\n",
7826 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
7827 ASC_PRT_NEXT();
7829 #endif /* CONFIG_ISA */
7831 return totlen;
7835 * asc_prt_adv_board_eeprom()
7837 * Print board EEPROM configuration.
7839 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7840 * cf. asc_prt_line().
7842 * Return the number of characters copied into 'cp'. No more than
7843 * 'cplen' characters will be copied to 'cp'.
7845 STATIC int
7846 asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
7848 asc_board_t *boardp;
7849 ADV_DVC_VAR *adv_dvc_varp;
7850 int leftlen;
7851 int totlen;
7852 int len;
7853 int i;
7854 char *termstr;
7855 uchar serialstr[13];
7856 ADVEEP_3550_CONFIG *ep_3550 = NULL;
7857 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
7858 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
7859 ushort word;
7860 ushort *wordp;
7861 ushort sdtr_speed = 0;
7863 boardp = ASC_BOARDP(shp);
7864 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
7865 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7867 ep_3550 = &boardp->eep_config.adv_3550_eep;
7868 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7870 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
7871 } else
7873 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
7876 leftlen = cplen;
7877 totlen = len = 0;
7879 len = asc_prt_line(cp, leftlen,
7880 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
7881 ASC_PRT_NEXT();
7883 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7885 wordp = &ep_3550->serial_number_word1;
7886 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7888 wordp = &ep_38C0800->serial_number_word1;
7889 } else
7891 wordp = &ep_38C1600->serial_number_word1;
7894 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
7895 len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
7896 ASC_PRT_NEXT();
7897 } else {
7898 len = asc_prt_line(cp, leftlen,
7899 " Serial Number Signature Not Present.\n");
7900 ASC_PRT_NEXT();
7903 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7905 len = asc_prt_line(cp, leftlen,
7906 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7907 ep_3550->adapter_scsi_id, ep_3550->max_host_qng,
7908 ep_3550->max_dvc_qng);
7909 ASC_PRT_NEXT();
7910 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7912 len = asc_prt_line(cp, leftlen,
7913 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7914 ep_38C0800->adapter_scsi_id, ep_38C0800->max_host_qng,
7915 ep_38C0800->max_dvc_qng);
7916 ASC_PRT_NEXT();
7917 } else
7919 len = asc_prt_line(cp, leftlen,
7920 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7921 ep_38C1600->adapter_scsi_id, ep_38C1600->max_host_qng,
7922 ep_38C1600->max_dvc_qng);
7923 ASC_PRT_NEXT();
7925 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7927 word = ep_3550->termination;
7928 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7930 word = ep_38C0800->termination_lvd;
7931 } else
7933 word = ep_38C1600->termination_lvd;
7935 switch (word) {
7936 case 1:
7937 termstr = "Low Off/High Off";
7938 break;
7939 case 2:
7940 termstr = "Low Off/High On";
7941 break;
7942 case 3:
7943 termstr = "Low On/High On";
7944 break;
7945 default:
7946 case 0:
7947 termstr = "Automatic";
7948 break;
7951 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7953 len = asc_prt_line(cp, leftlen,
7954 " termination: %u (%s), bios_ctrl: 0x%x\n",
7955 ep_3550->termination, termstr, ep_3550->bios_ctrl);
7956 ASC_PRT_NEXT();
7957 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7959 len = asc_prt_line(cp, leftlen,
7960 " termination: %u (%s), bios_ctrl: 0x%x\n",
7961 ep_38C0800->termination_lvd, termstr, ep_38C0800->bios_ctrl);
7962 ASC_PRT_NEXT();
7963 } else
7965 len = asc_prt_line(cp, leftlen,
7966 " termination: %u (%s), bios_ctrl: 0x%x\n",
7967 ep_38C1600->termination_lvd, termstr, ep_38C1600->bios_ctrl);
7968 ASC_PRT_NEXT();
7971 len = asc_prt_line(cp, leftlen,
7972 " Target ID: ");
7973 ASC_PRT_NEXT();
7974 for (i = 0; i <= ADV_MAX_TID; i++) {
7975 len = asc_prt_line(cp, leftlen, " %X", i);
7976 ASC_PRT_NEXT();
7978 len = asc_prt_line(cp, leftlen, "\n");
7979 ASC_PRT_NEXT();
7981 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7983 word = ep_3550->disc_enable;
7984 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7986 word = ep_38C0800->disc_enable;
7987 } else
7989 word = ep_38C1600->disc_enable;
7991 len = asc_prt_line(cp, leftlen,
7992 " Disconnects: ");
7993 ASC_PRT_NEXT();
7994 for (i = 0; i <= ADV_MAX_TID; i++) {
7995 len = asc_prt_line(cp, leftlen, " %c",
7996 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7997 ASC_PRT_NEXT();
7999 len = asc_prt_line(cp, leftlen, "\n");
8000 ASC_PRT_NEXT();
8002 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8004 word = ep_3550->tagqng_able;
8005 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8007 word = ep_38C0800->tagqng_able;
8008 } else
8010 word = ep_38C1600->tagqng_able;
8012 len = asc_prt_line(cp, leftlen,
8013 " Command Queuing: ");
8014 ASC_PRT_NEXT();
8015 for (i = 0; i <= ADV_MAX_TID; i++) {
8016 len = asc_prt_line(cp, leftlen, " %c",
8017 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8018 ASC_PRT_NEXT();
8020 len = asc_prt_line(cp, leftlen, "\n");
8021 ASC_PRT_NEXT();
8023 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8025 word = ep_3550->start_motor;
8026 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8028 word = ep_38C0800->start_motor;
8029 } else
8031 word = ep_38C1600->start_motor;
8033 len = asc_prt_line(cp, leftlen,
8034 " Start Motor: ");
8035 ASC_PRT_NEXT();
8036 for (i = 0; i <= ADV_MAX_TID; i++) {
8037 len = asc_prt_line(cp, leftlen, " %c",
8038 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8039 ASC_PRT_NEXT();
8041 len = asc_prt_line(cp, leftlen, "\n");
8042 ASC_PRT_NEXT();
8044 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8046 len = asc_prt_line(cp, leftlen,
8047 " Synchronous Transfer:");
8048 ASC_PRT_NEXT();
8049 for (i = 0; i <= ADV_MAX_TID; i++) {
8050 len = asc_prt_line(cp, leftlen, " %c",
8051 (ep_3550->sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8052 ASC_PRT_NEXT();
8054 len = asc_prt_line(cp, leftlen, "\n");
8055 ASC_PRT_NEXT();
8058 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8060 len = asc_prt_line(cp, leftlen,
8061 " Ultra Transfer: ");
8062 ASC_PRT_NEXT();
8063 for (i = 0; i <= ADV_MAX_TID; i++) {
8064 len = asc_prt_line(cp, leftlen, " %c",
8065 (ep_3550->ultra_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8066 ASC_PRT_NEXT();
8068 len = asc_prt_line(cp, leftlen, "\n");
8069 ASC_PRT_NEXT();
8072 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8074 word = ep_3550->wdtr_able;
8075 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8077 word = ep_38C0800->wdtr_able;
8078 } else
8080 word = ep_38C1600->wdtr_able;
8082 len = asc_prt_line(cp, leftlen,
8083 " Wide Transfer: ");
8084 ASC_PRT_NEXT();
8085 for (i = 0; i <= ADV_MAX_TID; i++) {
8086 len = asc_prt_line(cp, leftlen, " %c",
8087 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8088 ASC_PRT_NEXT();
8090 len = asc_prt_line(cp, leftlen, "\n");
8091 ASC_PRT_NEXT();
8093 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
8094 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600)
8096 len = asc_prt_line(cp, leftlen,
8097 " Synchronous Transfer Speed (Mhz):\n ");
8098 ASC_PRT_NEXT();
8099 for (i = 0; i <= ADV_MAX_TID; i++) {
8100 char *speed_str;
8102 if (i == 0)
8104 sdtr_speed = adv_dvc_varp->sdtr_speed1;
8105 } else if (i == 4)
8107 sdtr_speed = adv_dvc_varp->sdtr_speed2;
8108 } else if (i == 8)
8110 sdtr_speed = adv_dvc_varp->sdtr_speed3;
8111 } else if (i == 12)
8113 sdtr_speed = adv_dvc_varp->sdtr_speed4;
8115 switch (sdtr_speed & ADV_MAX_TID)
8117 case 0: speed_str = "Off"; break;
8118 case 1: speed_str = " 5"; break;
8119 case 2: speed_str = " 10"; break;
8120 case 3: speed_str = " 20"; break;
8121 case 4: speed_str = " 40"; break;
8122 case 5: speed_str = " 80"; break;
8123 default: speed_str = "Unk"; break;
8125 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
8126 ASC_PRT_NEXT();
8127 if (i == 7)
8129 len = asc_prt_line(cp, leftlen, "\n ");
8130 ASC_PRT_NEXT();
8132 sdtr_speed >>= 4;
8134 len = asc_prt_line(cp, leftlen, "\n");
8135 ASC_PRT_NEXT();
8138 return totlen;
8142 * asc_prt_driver_conf()
8144 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8145 * cf. asc_prt_line().
8147 * Return the number of characters copied into 'cp'. No more than
8148 * 'cplen' characters will be copied to 'cp'.
8150 STATIC int
8151 asc_prt_driver_conf(struct Scsi_Host *shp, char *cp, int cplen)
8153 asc_board_t *boardp;
8154 int leftlen;
8155 int totlen;
8156 int len;
8157 int chip_scsi_id;
8159 boardp = ASC_BOARDP(shp);
8161 leftlen = cplen;
8162 totlen = len = 0;
8164 len = asc_prt_line(cp, leftlen,
8165 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
8166 shp->host_no);
8167 ASC_PRT_NEXT();
8169 len = asc_prt_line(cp, leftlen,
8170 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
8171 shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun,
8172 shp->max_channel);
8173 ASC_PRT_NEXT();
8175 len = asc_prt_line(cp, leftlen,
8176 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
8177 shp->unique_id, shp->can_queue, shp->this_id, shp->sg_tablesize,
8178 shp->cmd_per_lun);
8179 ASC_PRT_NEXT();
8181 len = asc_prt_line(cp, leftlen,
8182 " unchecked_isa_dma %d, use_clustering %d\n",
8183 shp->unchecked_isa_dma, shp->use_clustering);
8184 ASC_PRT_NEXT();
8186 len = asc_prt_line(cp, leftlen,
8187 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
8188 boardp->flags, boardp->last_reset, jiffies, boardp->asc_n_io_port);
8189 ASC_PRT_NEXT();
8191 /* 'shp->n_io_port' may be truncated because it is only one byte. */
8192 len = asc_prt_line(cp, leftlen,
8193 " io_port 0x%x, n_io_port 0x%x\n",
8194 shp->io_port, shp->n_io_port);
8195 ASC_PRT_NEXT();
8197 if (ASC_NARROW_BOARD(boardp)) {
8198 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
8199 } else {
8200 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
8203 return totlen;
8207 * asc_prt_asc_board_info()
8209 * Print dynamic board configuration information.
8211 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8212 * cf. asc_prt_line().
8214 * Return the number of characters copied into 'cp'. No more than
8215 * 'cplen' characters will be copied to 'cp'.
8217 STATIC int
8218 asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8220 asc_board_t *boardp;
8221 int chip_scsi_id;
8222 int leftlen;
8223 int totlen;
8224 int len;
8225 ASC_DVC_VAR *v;
8226 ASC_DVC_CFG *c;
8227 int i;
8228 int renegotiate = 0;
8230 boardp = ASC_BOARDP(shp);
8231 v = &boardp->dvc_var.asc_dvc_var;
8232 c = &boardp->dvc_cfg.asc_dvc_cfg;
8233 chip_scsi_id = c->chip_scsi_id;
8235 leftlen = cplen;
8236 totlen = len = 0;
8238 len = asc_prt_line(cp, leftlen,
8239 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8240 shp->host_no);
8241 ASC_PRT_NEXT();
8243 len = asc_prt_line(cp, leftlen,
8244 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
8245 c->chip_version, c->lib_version, c->lib_serial_no, c->mcode_date);
8246 ASC_PRT_NEXT();
8248 len = asc_prt_line(cp, leftlen,
8249 " mcode_version 0x%x, err_code %u\n",
8250 c->mcode_version, v->err_code);
8251 ASC_PRT_NEXT();
8253 /* Current number of commands waiting for the host. */
8254 len = asc_prt_line(cp, leftlen,
8255 " Total Command Pending: %d\n", v->cur_total_qng);
8256 ASC_PRT_NEXT();
8258 len = asc_prt_line(cp, leftlen,
8259 " Command Queuing:");
8260 ASC_PRT_NEXT();
8261 for (i = 0; i <= ASC_MAX_TID; i++) {
8262 if ((chip_scsi_id == i) ||
8263 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8264 continue;
8266 len = asc_prt_line(cp, leftlen, " %X:%c",
8267 i, (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8268 ASC_PRT_NEXT();
8270 len = asc_prt_line(cp, leftlen, "\n");
8271 ASC_PRT_NEXT();
8273 /* Current number of commands waiting for a device. */
8274 len = asc_prt_line(cp, leftlen,
8275 " Command Queue Pending:");
8276 ASC_PRT_NEXT();
8277 for (i = 0; i <= ASC_MAX_TID; i++) {
8278 if ((chip_scsi_id == i) ||
8279 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8280 continue;
8282 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
8283 ASC_PRT_NEXT();
8285 len = asc_prt_line(cp, leftlen, "\n");
8286 ASC_PRT_NEXT();
8288 /* Current limit on number of commands that can be sent to a device. */
8289 len = asc_prt_line(cp, leftlen,
8290 " Command Queue Limit:");
8291 ASC_PRT_NEXT();
8292 for (i = 0; i <= ASC_MAX_TID; i++) {
8293 if ((chip_scsi_id == i) ||
8294 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8295 continue;
8297 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
8298 ASC_PRT_NEXT();
8300 len = asc_prt_line(cp, leftlen, "\n");
8301 ASC_PRT_NEXT();
8303 /* Indicate whether the device has returned queue full status. */
8304 len = asc_prt_line(cp, leftlen,
8305 " Command Queue Full:");
8306 ASC_PRT_NEXT();
8307 for (i = 0; i <= ASC_MAX_TID; i++) {
8308 if ((chip_scsi_id == i) ||
8309 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8310 continue;
8312 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
8313 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
8314 i, boardp->queue_full_cnt[i]);
8315 } else {
8316 len = asc_prt_line(cp, leftlen, " %X:N", i);
8318 ASC_PRT_NEXT();
8320 len = asc_prt_line(cp, leftlen, "\n");
8321 ASC_PRT_NEXT();
8323 len = asc_prt_line(cp, leftlen,
8324 " Synchronous Transfer:");
8325 ASC_PRT_NEXT();
8326 for (i = 0; i <= ASC_MAX_TID; i++) {
8327 if ((chip_scsi_id == i) ||
8328 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8329 continue;
8331 len = asc_prt_line(cp, leftlen, " %X:%c",
8332 i, (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8333 ASC_PRT_NEXT();
8335 len = asc_prt_line(cp, leftlen, "\n");
8336 ASC_PRT_NEXT();
8338 for (i = 0; i <= ASC_MAX_TID; i++) {
8339 uchar syn_period_ix;
8341 if ((chip_scsi_id == i) ||
8342 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
8343 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
8344 continue;
8347 len = asc_prt_line(cp, leftlen, " %X:", i);
8348 ASC_PRT_NEXT();
8350 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0)
8352 len = asc_prt_line(cp, leftlen, " Asynchronous");
8353 ASC_PRT_NEXT();
8354 } else
8356 syn_period_ix =
8357 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1);
8359 len = asc_prt_line(cp, leftlen,
8360 " Transfer Period Factor: %d (%d.%d Mhz),",
8361 v->sdtr_period_tbl[syn_period_ix],
8362 250 / v->sdtr_period_tbl[syn_period_ix],
8363 ASC_TENTHS(250, v->sdtr_period_tbl[syn_period_ix]));
8364 ASC_PRT_NEXT();
8366 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
8367 boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET);
8368 ASC_PRT_NEXT();
8371 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8372 len = asc_prt_line(cp, leftlen, "*\n");
8373 renegotiate = 1;
8374 } else
8376 len = asc_prt_line(cp, leftlen, "\n");
8378 ASC_PRT_NEXT();
8381 if (renegotiate)
8383 len = asc_prt_line(cp, leftlen,
8384 " * = Re-negotiation pending before next command.\n");
8385 ASC_PRT_NEXT();
8388 return totlen;
8392 * asc_prt_adv_board_info()
8394 * Print dynamic board configuration information.
8396 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8397 * cf. asc_prt_line().
8399 * Return the number of characters copied into 'cp'. No more than
8400 * 'cplen' characters will be copied to 'cp'.
8402 STATIC int
8403 asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8405 asc_board_t *boardp;
8406 int leftlen;
8407 int totlen;
8408 int len;
8409 int i;
8410 ADV_DVC_VAR *v;
8411 ADV_DVC_CFG *c;
8412 AdvPortAddr iop_base;
8413 ushort chip_scsi_id;
8414 ushort lramword;
8415 uchar lrambyte;
8416 ushort tagqng_able;
8417 ushort sdtr_able, wdtr_able;
8418 ushort wdtr_done, sdtr_done;
8419 ushort period = 0;
8420 int renegotiate = 0;
8422 boardp = ASC_BOARDP(shp);
8423 v = &boardp->dvc_var.adv_dvc_var;
8424 c = &boardp->dvc_cfg.adv_dvc_cfg;
8425 iop_base = v->iop_base;
8426 chip_scsi_id = v->chip_scsi_id;
8428 leftlen = cplen;
8429 totlen = len = 0;
8431 len = asc_prt_line(cp, leftlen,
8432 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8433 shp->host_no);
8434 ASC_PRT_NEXT();
8436 len = asc_prt_line(cp, leftlen,
8437 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
8438 v->iop_base,
8439 AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1) & CABLE_DETECT,
8440 v->err_code);
8441 ASC_PRT_NEXT();
8443 len = asc_prt_line(cp, leftlen,
8444 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
8445 c->chip_version, c->lib_version, c->mcode_date, c->mcode_version);
8446 ASC_PRT_NEXT();
8448 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8449 len = asc_prt_line(cp, leftlen,
8450 " Queuing Enabled:");
8451 ASC_PRT_NEXT();
8452 for (i = 0; i <= ADV_MAX_TID; i++) {
8453 if ((chip_scsi_id == i) ||
8454 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8455 continue;
8458 len = asc_prt_line(cp, leftlen, " %X:%c",
8459 i, (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8460 ASC_PRT_NEXT();
8462 len = asc_prt_line(cp, leftlen, "\n");
8463 ASC_PRT_NEXT();
8465 len = asc_prt_line(cp, leftlen,
8466 " Queue Limit:");
8467 ASC_PRT_NEXT();
8468 for (i = 0; i <= ADV_MAX_TID; i++) {
8469 if ((chip_scsi_id == i) ||
8470 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8471 continue;
8474 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, lrambyte);
8476 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
8477 ASC_PRT_NEXT();
8479 len = asc_prt_line(cp, leftlen, "\n");
8480 ASC_PRT_NEXT();
8482 len = asc_prt_line(cp, leftlen,
8483 " Command Pending:");
8484 ASC_PRT_NEXT();
8485 for (i = 0; i <= ADV_MAX_TID; i++) {
8486 if ((chip_scsi_id == i) ||
8487 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8488 continue;
8491 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, lrambyte);
8493 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
8494 ASC_PRT_NEXT();
8496 len = asc_prt_line(cp, leftlen, "\n");
8497 ASC_PRT_NEXT();
8499 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8500 len = asc_prt_line(cp, leftlen,
8501 " Wide Enabled:");
8502 ASC_PRT_NEXT();
8503 for (i = 0; i <= ADV_MAX_TID; i++) {
8504 if ((chip_scsi_id == i) ||
8505 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8506 continue;
8509 len = asc_prt_line(cp, leftlen, " %X:%c",
8510 i, (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8511 ASC_PRT_NEXT();
8513 len = asc_prt_line(cp, leftlen, "\n");
8514 ASC_PRT_NEXT();
8516 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
8517 len = asc_prt_line(cp, leftlen,
8518 " Transfer Bit Width:");
8519 ASC_PRT_NEXT();
8520 for (i = 0; i <= ADV_MAX_TID; i++) {
8521 if ((chip_scsi_id == i) ||
8522 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8523 continue;
8526 AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
8527 lramword);
8529 len = asc_prt_line(cp, leftlen, " %X:%d",
8530 i, (lramword & 0x8000) ? 16 : 8);
8531 ASC_PRT_NEXT();
8533 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
8534 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8535 len = asc_prt_line(cp, leftlen, "*");
8536 ASC_PRT_NEXT();
8537 renegotiate = 1;
8540 len = asc_prt_line(cp, leftlen, "\n");
8541 ASC_PRT_NEXT();
8543 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8544 len = asc_prt_line(cp, leftlen,
8545 " Synchronous Enabled:");
8546 ASC_PRT_NEXT();
8547 for (i = 0; i <= ADV_MAX_TID; i++) {
8548 if ((chip_scsi_id == i) ||
8549 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8550 continue;
8553 len = asc_prt_line(cp, leftlen, " %X:%c",
8554 i, (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8555 ASC_PRT_NEXT();
8557 len = asc_prt_line(cp, leftlen, "\n");
8558 ASC_PRT_NEXT();
8560 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
8561 for (i = 0; i <= ADV_MAX_TID; i++) {
8563 AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
8564 lramword);
8565 lramword &= ~0x8000;
8567 if ((chip_scsi_id == i) ||
8568 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
8569 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
8570 continue;
8573 len = asc_prt_line(cp, leftlen, " %X:", i);
8574 ASC_PRT_NEXT();
8576 if ((lramword & 0x1F) == 0) /* Check for REQ/ACK Offset 0. */
8578 len = asc_prt_line(cp, leftlen, " Asynchronous");
8579 ASC_PRT_NEXT();
8580 } else
8582 len = asc_prt_line(cp, leftlen, " Transfer Period Factor: ");
8583 ASC_PRT_NEXT();
8585 if ((lramword & 0x1F00) == 0x1100) /* 80 Mhz */
8587 len = asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
8588 ASC_PRT_NEXT();
8589 } else if ((lramword & 0x1F00) == 0x1000) /* 40 Mhz */
8591 len = asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
8592 ASC_PRT_NEXT();
8593 } else /* 20 Mhz or below. */
8595 period = (((lramword >> 8) * 25) + 50)/4;
8597 if (period == 0) /* Should never happen. */
8599 len = asc_prt_line(cp, leftlen, "%d (? Mhz), ");
8600 ASC_PRT_NEXT();
8601 } else
8603 len = asc_prt_line(cp, leftlen,
8604 "%d (%d.%d Mhz),",
8605 period, 250/period, ASC_TENTHS(250, period));
8606 ASC_PRT_NEXT();
8610 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
8611 lramword & 0x1F);
8612 ASC_PRT_NEXT();
8615 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8616 len = asc_prt_line(cp, leftlen, "*\n");
8617 renegotiate = 1;
8618 } else
8620 len = asc_prt_line(cp, leftlen, "\n");
8622 ASC_PRT_NEXT();
8625 if (renegotiate)
8627 len = asc_prt_line(cp, leftlen,
8628 " * = Re-negotiation pending before next command.\n");
8629 ASC_PRT_NEXT();
8632 return totlen;
8636 * asc_proc_copy()
8638 * Copy proc information to a read buffer taking into account the current
8639 * read offset in the file and the remaining space in the read buffer.
8641 STATIC int
8642 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
8643 char *cp, int cplen)
8645 int cnt = 0;
8647 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
8648 (unsigned) offset, (unsigned) advoffset, cplen);
8649 if (offset <= advoffset) {
8650 /* Read offset below current offset, copy everything. */
8651 cnt = min(cplen, leftlen);
8652 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
8653 (ulong) curbuf, (ulong) cp, cnt);
8654 memcpy(curbuf, cp, cnt);
8655 } else if (offset < advoffset + cplen) {
8656 /* Read offset within current range, partial copy. */
8657 cnt = (advoffset + cplen) - offset;
8658 cp = (cp + cplen) - cnt;
8659 cnt = min(cnt, leftlen);
8660 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
8661 (ulong) curbuf, (ulong) cp, cnt);
8662 memcpy(curbuf, cp, cnt);
8664 return cnt;
8668 * asc_prt_line()
8670 * If 'cp' is NULL print to the console, otherwise print to a buffer.
8672 * Return 0 if printing to the console, otherwise return the number of
8673 * bytes written to the buffer.
8675 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
8676 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
8678 STATIC int
8679 asc_prt_line(char *buf, int buflen, char *fmt, ...)
8681 va_list args;
8682 int ret;
8683 char s[ASC_PRTLINE_SIZE];
8685 va_start(args, fmt);
8686 ret = vsprintf(s, fmt, args);
8687 ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
8688 if (buf == NULL) {
8689 (void) printk(s);
8690 ret = 0;
8691 } else {
8692 ret = min(buflen, ret);
8693 memcpy(buf, s, ret);
8695 va_end(args);
8696 return ret;
8698 #endif /* CONFIG_PROC_FS */
8702 * --- Functions Required by the Asc Library
8706 * Delay for 'n' milliseconds. Don't use the 'jiffies'
8707 * global variable which is incremented once every 5 ms
8708 * from a timer interrupt, because this function may be
8709 * called when interrupts are disabled.
8711 STATIC void
8712 DvcSleepMilliSecond(ADV_DCNT n)
8714 ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong) n);
8715 mdelay(n);
8719 * Currently and inline noop but leave as a placeholder.
8720 * Leave DvcEnterCritical() as a noop placeholder.
8722 STATIC inline ulong
8723 DvcEnterCritical(void)
8725 return 0;
8729 * Critical sections are all protected by the board spinlock.
8730 * Leave DvcLeaveCritical() as a noop placeholder.
8732 STATIC inline void
8733 DvcLeaveCritical(ulong flags)
8735 return;
8739 * void
8740 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
8742 * Calling/Exit State:
8743 * none
8745 * Description:
8746 * Output an ASC_SCSI_Q structure to the chip
8748 STATIC void
8749 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
8751 int i;
8753 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
8754 AscSetChipLramAddr(iop_base, s_addr);
8755 for (i = 0; i < 2 * words; i += 2) {
8756 if (i == 4 || i == 20) {
8757 continue;
8759 outpw(iop_base + IOP_RAM_DATA,
8760 ((ushort) outbuf[i + 1] << 8) | outbuf[i]);
8765 * void
8766 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
8768 * Calling/Exit State:
8769 * none
8771 * Description:
8772 * Input an ASC_QDONE_INFO structure from the chip
8774 STATIC void
8775 DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
8777 int i;
8778 ushort word;
8780 AscSetChipLramAddr(iop_base, s_addr);
8781 for (i = 0; i < 2 * words; i += 2) {
8782 if (i == 10) {
8783 continue;
8785 word = inpw(iop_base + IOP_RAM_DATA);
8786 inbuf[i] = word & 0xff;
8787 inbuf[i + 1] = (word >> 8) & 0xff;
8789 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
8793 * Read a PCI configuration byte.
8795 STATIC uchar __init
8796 DvcReadPCIConfigByte(
8797 ASC_DVC_VAR *asc_dvc,
8798 ushort offset)
8800 #ifdef CONFIG_PCI
8801 uchar byte_data;
8802 pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
8803 return byte_data;
8804 #else /* !defined(CONFIG_PCI) */
8805 return 0;
8806 #endif /* !defined(CONFIG_PCI) */
8810 * Write a PCI configuration byte.
8812 STATIC void __init
8813 DvcWritePCIConfigByte(
8814 ASC_DVC_VAR *asc_dvc,
8815 ushort offset,
8816 uchar byte_data)
8818 #ifdef CONFIG_PCI
8819 pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
8820 #endif /* CONFIG_PCI */
8824 * Return the BIOS address of the adapter at the specified
8825 * I/O port and with the specified bus type.
8827 STATIC ushort __init
8828 AscGetChipBiosAddress(
8829 PortAddr iop_base,
8830 ushort bus_type)
8832 ushort cfg_lsw;
8833 ushort bios_addr;
8836 * The PCI BIOS is re-located by the motherboard BIOS. Because
8837 * of this the driver can not determine where a PCI BIOS is
8838 * loaded and executes.
8840 if (bus_type & ASC_IS_PCI)
8842 return(0);
8845 #ifdef CONFIG_ISA
8846 if((bus_type & ASC_IS_EISA) != 0)
8848 cfg_lsw = AscGetEisaChipCfg(iop_base);
8849 cfg_lsw &= 0x000F;
8850 bios_addr = (ushort)(ASC_BIOS_MIN_ADDR +
8851 (cfg_lsw * ASC_BIOS_BANK_SIZE));
8852 return(bios_addr);
8853 }/* if */
8854 #endif /* CONFIG_ISA */
8856 cfg_lsw = AscGetChipCfgLsw(iop_base);
8859 * ISA PnP uses the top bit as the 32K BIOS flag
8861 if (bus_type == ASC_IS_ISAPNP)
8863 cfg_lsw &= 0x7FFF;
8864 }/* if */
8866 bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
8867 ASC_BIOS_MIN_ADDR);
8868 return(bios_addr);
8873 * --- Functions Required by the Adv Library
8877 * DvcGetPhyAddr()
8879 * Return the physical address of 'vaddr' and set '*lenp' to the
8880 * number of physically contiguous bytes that follow 'vaddr'.
8881 * 'flag' indicates the type of structure whose physical address
8882 * is being translated.
8884 * Note: Because Linux currently doesn't page the kernel and all
8885 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
8887 ADV_PADDR
8888 DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
8889 uchar *vaddr, ADV_SDCNT *lenp, int flag)
8891 ADV_PADDR paddr;
8893 paddr = virt_to_bus(vaddr);
8895 ASC_DBG4(4,
8896 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
8897 (ulong) vaddr, (ulong) lenp, (ulong) *((ulong *) lenp), (ulong) paddr);
8899 return paddr;
8903 * Read a PCI configuration byte.
8905 STATIC uchar __init
8906 DvcAdvReadPCIConfigByte(
8907 ADV_DVC_VAR *asc_dvc,
8908 ushort offset)
8910 #ifdef CONFIG_PCI
8911 uchar byte_data;
8912 pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
8913 return byte_data;
8914 #else /* CONFIG_PCI */
8915 return 0;
8916 #endif /* CONFIG_PCI */
8920 * Write a PCI configuration byte.
8922 STATIC void __init
8923 DvcAdvWritePCIConfigByte(
8924 ADV_DVC_VAR *asc_dvc,
8925 ushort offset,
8926 uchar byte_data)
8928 #ifdef CONFIG_PCI
8929 pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
8930 #else /* CONFIG_PCI */
8931 return;
8932 #endif /* CONFIG_PCI */
8936 * --- Tracing and Debugging Functions
8939 #ifdef ADVANSYS_STATS
8940 #ifdef CONFIG_PROC_FS
8942 * asc_prt_board_stats()
8944 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8945 * cf. asc_prt_line().
8947 * Return the number of characters copied into 'cp'. No more than
8948 * 'cplen' characters will be copied to 'cp'.
8950 STATIC int
8951 asc_prt_board_stats(struct Scsi_Host *shp, char *cp, int cplen)
8953 int leftlen;
8954 int totlen;
8955 int len;
8956 struct asc_stats *s;
8957 asc_board_t *boardp;
8959 leftlen = cplen;
8960 totlen = len = 0;
8962 boardp = ASC_BOARDP(shp);
8963 s = &boardp->asc_stats;
8965 len = asc_prt_line(cp, leftlen,
8966 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", shp->host_no);
8967 ASC_PRT_NEXT();
8969 len = asc_prt_line(cp, leftlen,
8970 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
8971 s->queuecommand, s->reset, s->biosparam, s->interrupt);
8972 ASC_PRT_NEXT();
8974 len = asc_prt_line(cp, leftlen,
8975 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
8976 s->callback, s->done, s->build_error, s->adv_build_noreq,
8977 s->adv_build_nosg);
8978 ASC_PRT_NEXT();
8980 len = asc_prt_line(cp, leftlen,
8981 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
8982 s->exe_noerror, s->exe_busy, s->exe_error, s->exe_unknown);
8983 ASC_PRT_NEXT();
8986 * Display data transfer statistics.
8988 if (s->cont_cnt > 0) {
8989 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
8990 ASC_PRT_NEXT();
8992 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
8993 s->cont_xfer/2,
8994 ASC_TENTHS(s->cont_xfer, 2));
8995 ASC_PRT_NEXT();
8997 /* Contiguous transfer average size */
8998 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
8999 (s->cont_xfer/2)/s->cont_cnt,
9000 ASC_TENTHS((s->cont_xfer/2), s->cont_cnt));
9001 ASC_PRT_NEXT();
9004 if (s->sg_cnt > 0) {
9006 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
9007 s->sg_cnt, s->sg_elem);
9008 ASC_PRT_NEXT();
9010 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
9011 s->sg_xfer/2,
9012 ASC_TENTHS(s->sg_xfer, 2));
9013 ASC_PRT_NEXT();
9015 /* Scatter gather transfer statistics */
9016 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
9017 s->sg_elem/s->sg_cnt,
9018 ASC_TENTHS(s->sg_elem, s->sg_cnt));
9019 ASC_PRT_NEXT();
9021 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
9022 (s->sg_xfer/2)/s->sg_elem,
9023 ASC_TENTHS((s->sg_xfer/2), s->sg_elem));
9024 ASC_PRT_NEXT();
9026 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
9027 (s->sg_xfer/2)/s->sg_cnt,
9028 ASC_TENTHS((s->sg_xfer/2), s->sg_cnt));
9029 ASC_PRT_NEXT();
9033 * Display request queuing statistics.
9035 len = asc_prt_line(cp, leftlen,
9036 " Active and Waiting Request Queues (Time Unit: %d HZ):\n", HZ);
9037 ASC_PRT_NEXT();
9040 return totlen;
9044 * asc_prt_target_stats()
9046 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
9047 * cf. asc_prt_line().
9049 * This is separated from asc_prt_board_stats because a full set
9050 * of targets will overflow ASC_PRTBUF_SIZE.
9052 * Return the number of characters copied into 'cp'. No more than
9053 * 'cplen' characters will be copied to 'cp'.
9055 STATIC int
9056 asc_prt_target_stats(struct Scsi_Host *shp, int tgt_id, char *cp, int cplen)
9058 int leftlen;
9059 int totlen;
9060 int len;
9061 struct asc_stats *s;
9062 ushort chip_scsi_id;
9063 asc_board_t *boardp;
9064 asc_queue_t *active;
9065 asc_queue_t *waiting;
9067 leftlen = cplen;
9068 totlen = len = 0;
9070 boardp = ASC_BOARDP(shp);
9071 s = &boardp->asc_stats;
9073 active = &ASC_BOARDP(shp)->active;
9074 waiting = &ASC_BOARDP(shp)->waiting;
9076 if (ASC_NARROW_BOARD(boardp)) {
9077 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
9078 } else {
9079 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
9082 if ((chip_scsi_id == tgt_id) ||
9083 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
9084 return 0;
9087 do {
9088 if (active->q_tot_cnt[tgt_id] > 0 || waiting->q_tot_cnt[tgt_id] > 0) {
9089 len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
9090 ASC_PRT_NEXT();
9092 len = asc_prt_line(cp, leftlen,
9093 " active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
9094 active->q_cur_cnt[tgt_id], active->q_max_cnt[tgt_id],
9095 active->q_tot_cnt[tgt_id],
9096 active->q_min_tim[tgt_id], active->q_max_tim[tgt_id],
9097 (active->q_tot_cnt[tgt_id] == 0) ? 0 :
9098 (active->q_tot_tim[tgt_id]/active->q_tot_cnt[tgt_id]),
9099 (active->q_tot_cnt[tgt_id] == 0) ? 0 :
9100 ASC_TENTHS(active->q_tot_tim[tgt_id],
9101 active->q_tot_cnt[tgt_id]));
9102 ASC_PRT_NEXT();
9104 len = asc_prt_line(cp, leftlen,
9105 " waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
9106 waiting->q_cur_cnt[tgt_id], waiting->q_max_cnt[tgt_id],
9107 waiting->q_tot_cnt[tgt_id],
9108 waiting->q_min_tim[tgt_id], waiting->q_max_tim[tgt_id],
9109 (waiting->q_tot_cnt[tgt_id] == 0) ? 0 :
9110 (waiting->q_tot_tim[tgt_id]/waiting->q_tot_cnt[tgt_id]),
9111 (waiting->q_tot_cnt[tgt_id] == 0) ? 0 :
9112 ASC_TENTHS(waiting->q_tot_tim[tgt_id],
9113 waiting->q_tot_cnt[tgt_id]));
9114 ASC_PRT_NEXT();
9116 } while (0);
9118 return totlen;
9120 #endif /* CONFIG_PROC_FS */
9121 #endif /* ADVANSYS_STATS */
9123 #ifdef ADVANSYS_DEBUG
9125 * asc_prt_scsi_host()
9127 STATIC void
9128 asc_prt_scsi_host(struct Scsi_Host *s)
9130 asc_board_t *boardp;
9132 boardp = ASC_BOARDP(s);
9134 printk("Scsi_Host at addr 0x%lx\n", (ulong) s);
9135 printk(
9136 " host_busy %u, host_no %d, last_reset %d,\n",
9137 s->host_busy, s->host_no,
9138 (unsigned) s->last_reset);
9140 printk(
9141 " base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
9142 (ulong) s->base, (ulong) s->io_port, s->n_io_port, s->irq);
9144 printk(
9145 " dma_channel %d, this_id %d, can_queue %d,\n",
9146 s->dma_channel, s->this_id, s->can_queue);
9148 printk(
9149 " cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
9150 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
9152 if (ASC_NARROW_BOARD(boardp)) {
9153 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
9154 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
9155 } else {
9156 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
9157 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
9162 * asc_prt_scsi_cmnd()
9164 STATIC void
9165 asc_prt_scsi_cmnd(struct scsi_cmnd *s)
9167 printk("struct scsi_cmnd at addr 0x%lx\n", (ulong) s);
9169 printk(
9170 " host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
9171 (ulong) s->device->host, (ulong) s->device, s->device->id, s->device->lun,
9172 s->device->channel);
9174 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
9176 printk (
9177 "sc_data_direction %u, resid %d\n",
9178 s->sc_data_direction, s->resid);
9180 printk(
9181 " use_sg %u, sglist_len %u\n",
9182 s->use_sg, s->sglist_len);
9184 printk(
9185 " serial_number 0x%x, retries %d, allowed %d\n",
9186 (unsigned) s->serial_number, s->retries, s->allowed);
9188 printk(
9189 " timeout_per_command %d\n",
9190 s->timeout_per_command);
9192 printk(
9193 " scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
9194 (ulong) s->scsi_done, (ulong) s->done,
9195 (ulong) s->host_scribble, s->result);
9197 printk(
9198 " tag %u, pid %u\n",
9199 (unsigned) s->tag, (unsigned) s->pid);
9203 * asc_prt_asc_dvc_var()
9205 STATIC void
9206 asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
9208 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong) h);
9210 printk(
9211 " iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n",
9212 h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
9214 printk(
9215 " bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n",
9216 h->bus_type, (ulong) h->isr_callback, (ulong) h->exe_callback,
9217 (unsigned) h->init_sdtr);
9219 printk(
9220 " sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n",
9221 (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng,
9222 (unsigned) h->unit_not_ready, (unsigned) h->chip_no);
9224 printk(
9225 " queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n",
9226 (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor,
9227 (unsigned) h->scsi_reset_wait);
9229 printk(
9230 " is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n",
9231 (unsigned) h->is_in_int, (unsigned) h->max_total_qng,
9232 (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt);
9234 printk(
9235 " last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n",
9236 (unsigned) h->last_q_shortage, (unsigned) h->init_state,
9237 (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer);
9239 printk(
9240 " cfg 0x%lx, irq_no 0x%x\n",
9241 (ulong) h->cfg, (unsigned) h->irq_no);
9245 * asc_prt_asc_dvc_cfg()
9247 STATIC void
9248 asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
9250 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong) h);
9252 printk(
9253 " can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
9254 h->can_tagged_qng, h->cmd_qng_enabled);
9255 printk(
9256 " disc_enable 0x%x, sdtr_enable 0x%x,\n",
9257 h->disc_enable, h->sdtr_enable);
9259 printk(
9260 " chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
9261 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
9262 h->chip_version);
9264 printk(
9265 " pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
9266 to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
9267 h->mcode_date);
9269 printk(
9270 " mcode_version %d, overrun_buf 0x%lx\n",
9271 h->mcode_version, (ulong) h->overrun_buf);
9275 * asc_prt_asc_scsi_q()
9277 STATIC void
9278 asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
9280 ASC_SG_HEAD *sgp;
9281 int i;
9283 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong) q);
9285 printk(
9286 " target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
9287 q->q2.target_ix, q->q1.target_lun,
9288 (ulong) q->q2.srb_ptr, q->q2.tag_code);
9290 printk(
9291 " data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
9292 (ulong) le32_to_cpu(q->q1.data_addr),
9293 (ulong) le32_to_cpu(q->q1.data_cnt),
9294 (ulong) le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
9296 printk(
9297 " cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
9298 (ulong) q->cdbptr, q->q2.cdb_len,
9299 (ulong) q->sg_head, q->q1.sg_queue_cnt);
9301 if (q->sg_head) {
9302 sgp = q->sg_head;
9303 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong) sgp);
9304 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt);
9305 for (i = 0; i < sgp->entry_cnt; i++) {
9306 printk(" [%u]: addr 0x%lx, bytes %lu\n",
9307 i, (ulong) le32_to_cpu(sgp->sg_list[i].addr),
9308 (ulong) le32_to_cpu(sgp->sg_list[i].bytes));
9315 * asc_prt_asc_qdone_info()
9317 STATIC void
9318 asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
9320 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong) q);
9321 printk(
9322 " srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
9323 (ulong) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
9324 q->d2.tag_code);
9325 printk(
9326 " done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
9327 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
9331 * asc_prt_adv_dvc_var()
9333 * Display an ADV_DVC_VAR structure.
9335 STATIC void
9336 asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
9338 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong) h);
9340 printk(
9341 " iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
9342 (ulong) h->iop_base, h->err_code, (unsigned) h->ultra_able);
9344 printk(
9345 " isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
9346 (ulong) h->isr_callback, (unsigned) h->sdtr_able,
9347 (unsigned) h->wdtr_able);
9349 printk(
9350 " start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
9351 (unsigned) h->start_motor,
9352 (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
9354 printk(
9355 " max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
9356 (unsigned) h->max_host_qng, (unsigned) h->max_dvc_qng,
9357 (ulong) h->carr_freelist);
9359 printk(
9360 " icq_sp 0x%lx, irq_sp 0x%lx\n",
9361 (ulong) h->icq_sp, (ulong) h->irq_sp);
9363 printk(
9364 " no_scam 0x%x, tagqng_able 0x%x\n",
9365 (unsigned) h->no_scam, (unsigned) h->tagqng_able);
9367 printk(
9368 " chip_scsi_id 0x%x, cfg 0x%lx\n",
9369 (unsigned) h->chip_scsi_id, (ulong) h->cfg);
9373 * asc_prt_adv_dvc_cfg()
9375 * Display an ADV_DVC_CFG structure.
9377 STATIC void
9378 asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
9380 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong) h);
9382 printk(
9383 " disc_enable 0x%x, termination 0x%x\n",
9384 h->disc_enable, h->termination);
9386 printk(
9387 " chip_version 0x%x, mcode_date 0x%x\n",
9388 h->chip_version, h->mcode_date);
9390 printk(
9391 " mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
9392 h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
9394 printk(
9395 " control_flag 0x%x, pci_slot_info 0x%x\n",
9396 h->control_flag, h->pci_slot_info);
9400 * asc_prt_adv_scsi_req_q()
9402 * Display an ADV_SCSI_REQ_Q structure.
9404 STATIC void
9405 asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
9407 int sg_blk_cnt;
9408 struct asc_sg_block *sg_ptr;
9410 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong) q);
9412 printk(
9413 " target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
9414 q->target_id, q->target_lun, (ulong) q->srb_ptr, q->a_flag);
9416 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
9417 q->cntl, (ulong) le32_to_cpu(q->data_addr), (ulong) q->vdata_addr);
9419 printk(
9420 " data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
9421 (ulong) le32_to_cpu(q->data_cnt),
9422 (ulong) le32_to_cpu(q->sense_addr), q->sense_len);
9424 printk(
9425 " cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
9426 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
9428 printk(
9429 " sg_working_ix 0x%x, target_cmd %u\n",
9430 q->sg_working_ix, q->target_cmd);
9432 printk(
9433 " scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
9434 (ulong) le32_to_cpu(q->scsiq_rptr),
9435 (ulong) le32_to_cpu(q->sg_real_addr), (ulong) q->sg_list_ptr);
9437 /* Display the request's ADV_SG_BLOCK structures. */
9438 if (q->sg_list_ptr != NULL)
9440 sg_blk_cnt = 0;
9441 while (1) {
9443 * 'sg_ptr' is a physical address. Convert it to a virtual
9444 * address by indexing 'sg_blk_cnt' into the virtual address
9445 * array 'sg_list_ptr'.
9447 * XXX - Assumes all SG physical blocks are virtually contiguous.
9449 sg_ptr = &(((ADV_SG_BLOCK *) (q->sg_list_ptr))[sg_blk_cnt]);
9450 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
9451 if (sg_ptr->sg_ptr == 0)
9453 break;
9455 sg_blk_cnt++;
9461 * asc_prt_adv_sgblock()
9463 * Display an ADV_SG_BLOCK structure.
9465 STATIC void
9466 asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
9468 int i;
9470 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
9471 (ulong) b, sgblockno);
9472 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
9473 b->sg_cnt, (ulong) le32_to_cpu(b->sg_ptr));
9474 ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
9475 if (b->sg_ptr != 0)
9477 ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
9479 for (i = 0; i < b->sg_cnt; i++) {
9480 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
9481 i, (ulong) b->sg_list[i].sg_addr, (ulong) b->sg_list[i].sg_count);
9486 * asc_prt_hex()
9488 * Print hexadecimal output in 4 byte groupings 32 bytes
9489 * or 8 double-words per line.
9491 STATIC void
9492 asc_prt_hex(char *f, uchar *s, int l)
9494 int i;
9495 int j;
9496 int k;
9497 int m;
9499 printk("%s: (%d bytes)\n", f, l);
9501 for (i = 0; i < l; i += 32) {
9503 /* Display a maximum of 8 double-words per line. */
9504 if ((k = (l - i) / 4) >= 8) {
9505 k = 8;
9506 m = 0;
9507 } else {
9508 m = (l - i) % 4;
9511 for (j = 0; j < k; j++) {
9512 printk(" %2.2X%2.2X%2.2X%2.2X",
9513 (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1],
9514 (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]);
9517 switch (m) {
9518 case 0:
9519 default:
9520 break;
9521 case 1:
9522 printk(" %2.2X",
9523 (unsigned) s[i+(j*4)]);
9524 break;
9525 case 2:
9526 printk(" %2.2X%2.2X",
9527 (unsigned) s[i+(j*4)],
9528 (unsigned) s[i+(j*4)+1]);
9529 break;
9530 case 3:
9531 printk(" %2.2X%2.2X%2.2X",
9532 (unsigned) s[i+(j*4)+1],
9533 (unsigned) s[i+(j*4)+2],
9534 (unsigned) s[i+(j*4)+3]);
9535 break;
9538 printk("\n");
9541 #endif /* ADVANSYS_DEBUG */
9544 * --- Asc Library Functions
9547 STATIC ushort __init
9548 AscGetEisaChipCfg(
9549 PortAddr iop_base)
9551 PortAddr eisa_cfg_iop;
9553 eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
9554 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
9555 return (inpw(eisa_cfg_iop));
9558 STATIC uchar __init
9559 AscSetChipScsiID(
9560 PortAddr iop_base,
9561 uchar new_host_id
9564 ushort cfg_lsw;
9566 if (AscGetChipScsiID(iop_base) == new_host_id) {
9567 return (new_host_id);
9569 cfg_lsw = AscGetChipCfgLsw(iop_base);
9570 cfg_lsw &= 0xF8FF;
9571 cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID) << 8);
9572 AscSetChipCfgLsw(iop_base, cfg_lsw);
9573 return (AscGetChipScsiID(iop_base));
9576 STATIC uchar __init
9577 AscGetChipScsiCtrl(
9578 PortAddr iop_base)
9580 uchar sc;
9582 AscSetBank(iop_base, 1);
9583 sc = inp(iop_base + IOP_REG_SC);
9584 AscSetBank(iop_base, 0);
9585 return (sc);
9588 STATIC uchar __init
9589 AscGetChipVersion(
9590 PortAddr iop_base,
9591 ushort bus_type
9594 if ((bus_type & ASC_IS_EISA) != 0) {
9595 PortAddr eisa_iop;
9596 uchar revision;
9597 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
9598 (PortAddr) ASC_EISA_REV_IOP_MASK;
9599 revision = inp(eisa_iop);
9600 return ((uchar) ((ASC_CHIP_MIN_VER_EISA - 1) + revision));
9602 return (AscGetChipVerNo(iop_base));
9605 STATIC ushort __init
9606 AscGetChipBusType(
9607 PortAddr iop_base)
9609 ushort chip_ver;
9611 chip_ver = AscGetChipVerNo(iop_base);
9612 if (
9613 (chip_ver >= ASC_CHIP_MIN_VER_VL)
9614 && (chip_ver <= ASC_CHIP_MAX_VER_VL)
9616 if (
9617 ((iop_base & 0x0C30) == 0x0C30)
9618 || ((iop_base & 0x0C50) == 0x0C50)
9620 return (ASC_IS_EISA);
9622 return (ASC_IS_VL);
9624 if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
9625 (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
9626 if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
9627 return (ASC_IS_ISAPNP);
9629 return (ASC_IS_ISA);
9630 } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
9631 (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
9632 return (ASC_IS_PCI);
9634 return (0);
9637 STATIC ASC_DCNT
9638 AscLoadMicroCode(
9639 PortAddr iop_base,
9640 ushort s_addr,
9641 uchar *mcode_buf,
9642 ushort mcode_size
9645 ASC_DCNT chksum;
9646 ushort mcode_word_size;
9647 ushort mcode_chksum;
9649 /* Write the microcode buffer starting at LRAM address 0. */
9650 mcode_word_size = (ushort) (mcode_size >> 1);
9651 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
9652 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
9654 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
9655 ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong) chksum);
9656 mcode_chksum = (ushort) AscMemSumLramWord(iop_base,
9657 (ushort) ASC_CODE_SEC_BEG,
9658 (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2));
9659 ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
9660 (ulong) mcode_chksum);
9661 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
9662 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
9663 return (chksum);
9666 STATIC int
9667 AscFindSignature(
9668 PortAddr iop_base
9671 ushort sig_word;
9673 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
9674 iop_base, AscGetChipSignatureByte(iop_base));
9675 if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) {
9676 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
9677 iop_base, AscGetChipSignatureWord(iop_base));
9678 sig_word = AscGetChipSignatureWord(iop_base);
9679 if ((sig_word == (ushort) ASC_1000_ID0W) ||
9680 (sig_word == (ushort) ASC_1000_ID0W_FIX)) {
9681 return (1);
9684 return (0);
9687 STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __initdata =
9689 0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
9690 ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
9693 #ifdef CONFIG_ISA
9694 STATIC uchar _isa_pnp_inited __initdata = 0;
9696 STATIC PortAddr __init
9697 AscSearchIOPortAddr(
9698 PortAddr iop_beg,
9699 ushort bus_type)
9701 if (bus_type & ASC_IS_VL) {
9702 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
9703 if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL) {
9704 return (iop_beg);
9707 return (0);
9709 if (bus_type & ASC_IS_ISA) {
9710 if (_isa_pnp_inited == 0) {
9711 AscSetISAPNPWaitForKey();
9712 _isa_pnp_inited++;
9714 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
9715 if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT) != 0) {
9716 return (iop_beg);
9719 return (0);
9721 if (bus_type & ASC_IS_EISA) {
9722 if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
9723 return (iop_beg);
9725 return (0);
9727 return (0);
9730 STATIC PortAddr __init
9731 AscSearchIOPortAddr11(
9732 PortAddr s_addr
9735 int i;
9736 PortAddr iop_base;
9738 for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
9739 if (_asc_def_iop_base[i] > s_addr) {
9740 break;
9743 for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
9744 iop_base = _asc_def_iop_base[i];
9745 if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")){
9746 ASC_DBG1(1,
9747 "AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n",
9748 iop_base);
9749 continue;
9751 ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n", iop_base);
9752 release_region(iop_base, ASC_IOADR_GAP);
9753 if (AscFindSignature(iop_base)) {
9754 return (iop_base);
9757 return (0);
9760 STATIC void __init
9761 AscSetISAPNPWaitForKey(void)
9763 outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
9764 outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
9765 return;
9767 #endif /* CONFIG_ISA */
9769 STATIC void __init
9770 AscToggleIRQAct(
9771 PortAddr iop_base
9774 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
9775 AscSetChipStatus(iop_base, 0);
9776 return;
9779 STATIC uchar __init
9780 AscGetChipIRQ(
9781 PortAddr iop_base,
9782 ushort bus_type)
9784 ushort cfg_lsw;
9785 uchar chip_irq;
9787 if ((bus_type & ASC_IS_EISA) != 0) {
9788 cfg_lsw = AscGetEisaChipCfg(iop_base);
9789 chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10);
9790 if ((chip_irq == 13) || (chip_irq > 15)) {
9791 return (0);
9793 return (chip_irq);
9795 if ((bus_type & ASC_IS_VL) != 0) {
9796 cfg_lsw = AscGetChipCfgLsw(iop_base);
9797 chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07));
9798 if ((chip_irq == 0) ||
9799 (chip_irq == 4) ||
9800 (chip_irq == 7)) {
9801 return (0);
9803 return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1)));
9805 cfg_lsw = AscGetChipCfgLsw(iop_base);
9806 chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03));
9807 if (chip_irq == 3)
9808 chip_irq += (uchar) 2;
9809 return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
9812 STATIC uchar __init
9813 AscSetChipIRQ(
9814 PortAddr iop_base,
9815 uchar irq_no,
9816 ushort bus_type)
9818 ushort cfg_lsw;
9820 if ((bus_type & ASC_IS_VL) != 0) {
9821 if (irq_no != 0) {
9822 if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) {
9823 irq_no = 0;
9824 } else {
9825 irq_no -= (uchar) ((ASC_MIN_IRQ_NO - 1));
9828 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE3);
9829 cfg_lsw |= (ushort) 0x0010;
9830 AscSetChipCfgLsw(iop_base, cfg_lsw);
9831 AscToggleIRQAct(iop_base);
9832 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE0);
9833 cfg_lsw |= (ushort) ((irq_no & 0x07) << 2);
9834 AscSetChipCfgLsw(iop_base, cfg_lsw);
9835 AscToggleIRQAct(iop_base);
9836 return (AscGetChipIRQ(iop_base, bus_type));
9838 if ((bus_type & (ASC_IS_ISA)) != 0) {
9839 if (irq_no == 15)
9840 irq_no -= (uchar) 2;
9841 irq_no -= (uchar) ASC_MIN_IRQ_NO;
9842 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFF3);
9843 cfg_lsw |= (ushort) ((irq_no & 0x03) << 2);
9844 AscSetChipCfgLsw(iop_base, cfg_lsw);
9845 return (AscGetChipIRQ(iop_base, bus_type));
9847 return (0);
9850 #ifdef CONFIG_ISA
9851 STATIC void __init
9852 AscEnableIsaDma(
9853 uchar dma_channel)
9855 if (dma_channel < 4) {
9856 outp(0x000B, (ushort) (0xC0 | dma_channel));
9857 outp(0x000A, dma_channel);
9858 } else if (dma_channel < 8) {
9859 outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4)));
9860 outp(0x00D4, (ushort) (dma_channel - 4));
9862 return;
9864 #endif /* CONFIG_ISA */
9866 STATIC int
9867 AscIsrChipHalted(
9868 ASC_DVC_VAR *asc_dvc
9871 EXT_MSG ext_msg;
9872 EXT_MSG out_msg;
9873 ushort halt_q_addr;
9874 int sdtr_accept;
9875 ushort int_halt_code;
9876 ASC_SCSI_BIT_ID_TYPE scsi_busy;
9877 ASC_SCSI_BIT_ID_TYPE target_id;
9878 PortAddr iop_base;
9879 uchar tag_code;
9880 uchar q_status;
9881 uchar halt_qp;
9882 uchar sdtr_data;
9883 uchar target_ix;
9884 uchar q_cntl, tid_no;
9885 uchar cur_dvc_qng;
9886 uchar asyn_sdtr;
9887 uchar scsi_status;
9888 asc_board_t *boardp;
9890 ASC_ASSERT(asc_dvc->drv_ptr != NULL);
9891 boardp = asc_dvc->drv_ptr;
9893 iop_base = asc_dvc->iop_base;
9894 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
9896 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
9897 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
9898 target_ix = AscReadLramByte(iop_base,
9899 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX));
9900 q_cntl = AscReadLramByte(iop_base,
9901 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL));
9902 tid_no = ASC_TIX_TO_TID(target_ix);
9903 target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no);
9904 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
9905 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
9906 } else {
9907 asyn_sdtr = 0;
9909 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
9910 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
9911 AscSetChipSDTR(iop_base, 0, tid_no);
9912 boardp->sdtr_data[tid_no] = 0;
9914 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9915 return (0);
9916 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
9917 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
9918 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
9919 boardp->sdtr_data[tid_no] = asyn_sdtr;
9921 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9922 return (0);
9923 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
9925 AscMemWordCopyPtrFromLram(iop_base,
9926 ASCV_MSGIN_BEG,
9927 (uchar *) &ext_msg,
9928 sizeof(EXT_MSG) >> 1);
9930 if (ext_msg.msg_type == MS_EXTEND &&
9931 ext_msg.msg_req == MS_SDTR_CODE &&
9932 ext_msg.msg_len == MS_SDTR_LEN) {
9933 sdtr_accept = TRUE;
9934 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
9936 sdtr_accept = FALSE;
9937 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
9939 if ((ext_msg.xfer_period <
9940 asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index]) ||
9941 (ext_msg.xfer_period >
9942 asc_dvc->sdtr_period_tbl[asc_dvc->max_sdtr_index])) {
9943 sdtr_accept = FALSE;
9944 ext_msg.xfer_period =
9945 asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index];
9947 if (sdtr_accept) {
9948 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
9949 ext_msg.req_ack_offset);
9950 if ((sdtr_data == 0xFF)) {
9952 q_cntl |= QC_MSG_OUT;
9953 asc_dvc->init_sdtr &= ~target_id;
9954 asc_dvc->sdtr_done &= ~target_id;
9955 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
9956 boardp->sdtr_data[tid_no] = asyn_sdtr;
9959 if (ext_msg.req_ack_offset == 0) {
9961 q_cntl &= ~QC_MSG_OUT;
9962 asc_dvc->init_sdtr &= ~target_id;
9963 asc_dvc->sdtr_done &= ~target_id;
9964 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
9965 } else {
9966 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
9968 q_cntl &= ~QC_MSG_OUT;
9969 asc_dvc->sdtr_done |= target_id;
9970 asc_dvc->init_sdtr |= target_id;
9971 asc_dvc->pci_fix_asyn_xfer &= ~target_id;
9972 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
9973 ext_msg.req_ack_offset);
9974 AscSetChipSDTR(iop_base, sdtr_data, tid_no);
9975 boardp->sdtr_data[tid_no] = sdtr_data;
9976 } else {
9978 q_cntl |= QC_MSG_OUT;
9979 AscMsgOutSDTR(asc_dvc,
9980 ext_msg.xfer_period,
9981 ext_msg.req_ack_offset);
9982 asc_dvc->pci_fix_asyn_xfer &= ~target_id;
9983 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
9984 ext_msg.req_ack_offset);
9985 AscSetChipSDTR(iop_base, sdtr_data, tid_no);
9986 boardp->sdtr_data[tid_no] = sdtr_data;
9987 asc_dvc->sdtr_done |= target_id;
9988 asc_dvc->init_sdtr |= target_id;
9992 AscWriteLramByte(iop_base,
9993 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
9994 q_cntl);
9995 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9996 return (0);
9997 } else if (ext_msg.msg_type == MS_EXTEND &&
9998 ext_msg.msg_req == MS_WDTR_CODE &&
9999 ext_msg.msg_len == MS_WDTR_LEN) {
10001 ext_msg.wdtr_width = 0;
10002 AscMemWordCopyPtrToLram(iop_base,
10003 ASCV_MSGOUT_BEG,
10004 (uchar *) &ext_msg,
10005 sizeof(EXT_MSG) >> 1);
10006 q_cntl |= QC_MSG_OUT;
10007 AscWriteLramByte(iop_base,
10008 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10009 q_cntl);
10010 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10011 return (0);
10012 } else {
10014 ext_msg.msg_type = MESSAGE_REJECT;
10015 AscMemWordCopyPtrToLram(iop_base,
10016 ASCV_MSGOUT_BEG,
10017 (uchar *) &ext_msg,
10018 sizeof(EXT_MSG) >> 1);
10019 q_cntl |= QC_MSG_OUT;
10020 AscWriteLramByte(iop_base,
10021 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10022 q_cntl);
10023 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10024 return (0);
10026 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
10028 q_cntl |= QC_REQ_SENSE;
10030 if ((asc_dvc->init_sdtr & target_id) != 0) {
10032 asc_dvc->sdtr_done &= ~target_id;
10034 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10035 q_cntl |= QC_MSG_OUT;
10036 AscMsgOutSDTR(asc_dvc,
10037 asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
10038 (uchar) (asc_dvc->max_sdtr_index - 1)],
10039 (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
10042 AscWriteLramByte(iop_base,
10043 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10044 q_cntl);
10046 tag_code = AscReadLramByte(iop_base,
10047 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
10048 tag_code &= 0xDC;
10049 if (
10050 (asc_dvc->pci_fix_asyn_xfer & target_id)
10051 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
10054 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
10055 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
10058 AscWriteLramByte(iop_base,
10059 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE),
10060 tag_code);
10062 q_status = AscReadLramByte(iop_base,
10063 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS));
10064 q_status |= (QS_READY | QS_BUSY);
10065 AscWriteLramByte(iop_base,
10066 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10067 q_status);
10069 scsi_busy = AscReadLramByte(iop_base,
10070 (ushort) ASCV_SCSIBUSY_B);
10071 scsi_busy &= ~target_id;
10072 AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10074 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10075 return (0);
10076 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
10078 AscMemWordCopyPtrFromLram(iop_base,
10079 ASCV_MSGOUT_BEG,
10080 (uchar *) &out_msg,
10081 sizeof(EXT_MSG) >> 1);
10083 if ((out_msg.msg_type == MS_EXTEND) &&
10084 (out_msg.msg_len == MS_SDTR_LEN) &&
10085 (out_msg.msg_req == MS_SDTR_CODE)) {
10087 asc_dvc->init_sdtr &= ~target_id;
10088 asc_dvc->sdtr_done &= ~target_id;
10089 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10090 boardp->sdtr_data[tid_no] = asyn_sdtr;
10092 q_cntl &= ~QC_MSG_OUT;
10093 AscWriteLramByte(iop_base,
10094 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10095 q_cntl);
10096 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10097 return (0);
10098 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
10100 scsi_status = AscReadLramByte(iop_base,
10101 (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS));
10102 cur_dvc_qng = AscReadLramByte(iop_base,
10103 (ushort) ((ushort) ASC_QADR_BEG + (ushort) target_ix));
10104 if ((cur_dvc_qng > 0) &&
10105 (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
10107 scsi_busy = AscReadLramByte(iop_base,
10108 (ushort) ASCV_SCSIBUSY_B);
10109 scsi_busy |= target_id;
10110 AscWriteLramByte(iop_base,
10111 (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10112 asc_dvc->queue_full_or_busy |= target_id;
10114 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
10115 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
10116 cur_dvc_qng -= 1;
10117 asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
10119 AscWriteLramByte(iop_base,
10120 (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG +
10121 (ushort) tid_no),
10122 cur_dvc_qng);
10125 * Set the device queue depth to the number of
10126 * active requests when the QUEUE FULL condition
10127 * was encountered.
10129 boardp->queue_full |= target_id;
10130 boardp->queue_full_cnt[tid_no] = cur_dvc_qng;
10134 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10135 return (0);
10137 #if CC_VERY_LONG_SG_LIST
10138 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC)
10140 uchar q_no;
10141 ushort q_addr;
10142 uchar sg_wk_q_no;
10143 uchar first_sg_wk_q_no;
10144 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
10145 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
10146 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
10147 ushort sg_list_dwords;
10148 ushort sg_entry_cnt;
10149 uchar next_qp;
10150 int i;
10152 q_no = AscReadLramByte(iop_base, (ushort) ASCV_REQ_SG_LIST_QP);
10153 if (q_no == ASC_QLINK_END)
10155 return(0);
10158 q_addr = ASC_QNO_TO_QADDR(q_no);
10161 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
10162 * structure pointer using a macro provided by the driver.
10163 * The ASC_SCSI_REQ pointer provides a pointer to the
10164 * host ASC_SG_HEAD structure.
10166 /* Read request's SRB pointer. */
10167 scsiq = (ASC_SCSI_Q *)
10168 ASC_SRB2SCSIQ(
10169 ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
10170 (ushort) (q_addr + ASC_SCSIQ_D_SRBPTR))));
10173 * Get request's first and working SG queue.
10175 sg_wk_q_no = AscReadLramByte(iop_base,
10176 (ushort) (q_addr + ASC_SCSIQ_B_SG_WK_QP));
10178 first_sg_wk_q_no = AscReadLramByte(iop_base,
10179 (ushort) (q_addr + ASC_SCSIQ_B_FIRST_SG_WK_QP));
10182 * Reset request's working SG queue back to the
10183 * first SG queue.
10185 AscWriteLramByte(iop_base,
10186 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SG_WK_QP),
10187 first_sg_wk_q_no);
10189 sg_head = scsiq->sg_head;
10192 * Set sg_entry_cnt to the number of SG elements
10193 * that will be completed on this interrupt.
10195 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
10196 * SG elements. The data_cnt and data_addr fields which
10197 * add 1 to the SG element capacity are not used when
10198 * restarting SG handling after a halt.
10200 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1))
10202 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
10205 * Keep track of remaining number of SG elements that will
10206 * need to be handled on the next interrupt.
10208 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
10209 } else
10211 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
10212 scsiq->remain_sg_entry_cnt = 0;
10216 * Copy SG elements into the list of allocated SG queues.
10218 * Last index completed is saved in scsiq->next_sg_index.
10220 next_qp = first_sg_wk_q_no;
10221 q_addr = ASC_QNO_TO_QADDR(next_qp);
10222 scsi_sg_q.sg_head_qp = q_no;
10223 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
10224 for( i = 0; i < sg_head->queue_cnt; i++)
10226 scsi_sg_q.seq_no = i + 1;
10227 if (sg_entry_cnt > ASC_SG_LIST_PER_Q)
10229 sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
10230 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
10232 * After very first SG queue RISC FW uses next
10233 * SG queue first element then checks sg_list_cnt
10234 * against zero and then decrements, so set
10235 * sg_list_cnt 1 less than number of SG elements
10236 * in each SG queue.
10238 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
10239 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
10240 } else {
10242 * This is the last SG queue in the list of
10243 * allocated SG queues. If there are more
10244 * SG elements than will fit in the allocated
10245 * queues, then set the QCSG_SG_XFER_MORE flag.
10247 if (scsiq->remain_sg_entry_cnt != 0)
10249 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
10250 } else
10252 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
10254 /* equals sg_entry_cnt * 2 */
10255 sg_list_dwords = sg_entry_cnt << 1;
10256 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
10257 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
10258 sg_entry_cnt = 0;
10261 scsi_sg_q.q_no = next_qp;
10262 AscMemWordCopyPtrToLram(iop_base,
10263 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
10264 (uchar *) &scsi_sg_q,
10265 sizeof(ASC_SG_LIST_Q) >> 1);
10267 AscMemDWordCopyPtrToLram(iop_base,
10268 q_addr + ASC_SGQ_LIST_BEG,
10269 (uchar *) &sg_head->sg_list[scsiq->next_sg_index],
10270 sg_list_dwords);
10272 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
10275 * If the just completed SG queue contained the
10276 * last SG element, then no more SG queues need
10277 * to be written.
10279 if (scsi_sg_q.cntl & QCSG_SG_XFER_END)
10281 break;
10284 next_qp = AscReadLramByte( iop_base,
10285 ( ushort )( q_addr+ASC_SCSIQ_B_FWD ) );
10286 q_addr = ASC_QNO_TO_QADDR( next_qp );
10290 * Clear the halt condition so the RISC will be restarted
10291 * after the return.
10293 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10294 return(0);
10296 #endif /* CC_VERY_LONG_SG_LIST */
10297 return (0);
10300 STATIC uchar
10301 _AscCopyLramScsiDoneQ(
10302 PortAddr iop_base,
10303 ushort q_addr,
10304 ASC_QDONE_INFO * scsiq,
10305 ASC_DCNT max_dma_count
10308 ushort _val;
10309 uchar sg_queue_cnt;
10311 DvcGetQinfo(iop_base,
10312 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
10313 (uchar *) scsiq,
10314 (sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2);
10316 _val = AscReadLramWord(iop_base,
10317 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS));
10318 scsiq->q_status = (uchar) _val;
10319 scsiq->q_no = (uchar) (_val >> 8);
10320 _val = AscReadLramWord(iop_base,
10321 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL));
10322 scsiq->cntl = (uchar) _val;
10323 sg_queue_cnt = (uchar) (_val >> 8);
10324 _val = AscReadLramWord(iop_base,
10325 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN));
10326 scsiq->sense_len = (uchar) _val;
10327 scsiq->extra_bytes = (uchar) (_val >> 8);
10330 * Read high word of remain bytes from alternate location.
10332 scsiq->remain_bytes = (((ADV_DCNT) AscReadLramWord( iop_base,
10333 (ushort) (q_addr+ (ushort) ASC_SCSIQ_W_ALT_DC1))) << 16);
10335 * Read low word of remain bytes from original location.
10337 scsiq->remain_bytes += AscReadLramWord(iop_base,
10338 (ushort) (q_addr+ (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT));
10340 scsiq->remain_bytes &= max_dma_count;
10341 return (sg_queue_cnt);
10344 STATIC int
10345 AscIsrQDone(
10346 ASC_DVC_VAR *asc_dvc
10349 uchar next_qp;
10350 uchar n_q_used;
10351 uchar sg_list_qp;
10352 uchar sg_queue_cnt;
10353 uchar q_cnt;
10354 uchar done_q_tail;
10355 uchar tid_no;
10356 ASC_SCSI_BIT_ID_TYPE scsi_busy;
10357 ASC_SCSI_BIT_ID_TYPE target_id;
10358 PortAddr iop_base;
10359 ushort q_addr;
10360 ushort sg_q_addr;
10361 uchar cur_target_qng;
10362 ASC_QDONE_INFO scsiq_buf;
10363 ASC_QDONE_INFO *scsiq;
10364 int false_overrun;
10365 ASC_ISR_CALLBACK asc_isr_callback;
10367 iop_base = asc_dvc->iop_base;
10368 asc_isr_callback = asc_dvc->isr_callback;
10369 n_q_used = 1;
10370 scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
10371 done_q_tail = (uchar) AscGetVarDoneQTail(iop_base);
10372 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
10373 next_qp = AscReadLramByte(iop_base,
10374 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD));
10375 if (next_qp != ASC_QLINK_END) {
10376 AscPutVarDoneQTail(iop_base, next_qp);
10377 q_addr = ASC_QNO_TO_QADDR(next_qp);
10378 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
10379 asc_dvc->max_dma_count);
10380 AscWriteLramByte(iop_base,
10381 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10382 (uchar) (scsiq->q_status & (uchar) ~ (QS_READY | QS_ABORTED)));
10383 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
10384 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
10385 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
10386 sg_q_addr = q_addr;
10387 sg_list_qp = next_qp;
10388 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
10389 sg_list_qp = AscReadLramByte(iop_base,
10390 (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_FWD));
10391 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
10392 if (sg_list_qp == ASC_QLINK_END) {
10393 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_Q_LINKS);
10394 scsiq->d3.done_stat = QD_WITH_ERROR;
10395 scsiq->d3.host_stat = QHSTA_D_QDONE_SG_LIST_CORRUPTED;
10396 goto FATAL_ERR_QDONE;
10398 AscWriteLramByte(iop_base,
10399 (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10400 QS_FREE);
10402 n_q_used = sg_queue_cnt + 1;
10403 AscPutVarDoneQTail(iop_base, sg_list_qp);
10405 if (asc_dvc->queue_full_or_busy & target_id) {
10406 cur_target_qng = AscReadLramByte(iop_base,
10407 (ushort) ((ushort) ASC_QADR_BEG + (ushort) scsiq->d2.target_ix));
10408 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
10409 scsi_busy = AscReadLramByte(iop_base,
10410 (ushort) ASCV_SCSIBUSY_B);
10411 scsi_busy &= ~target_id;
10412 AscWriteLramByte(iop_base,
10413 (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10414 asc_dvc->queue_full_or_busy &= ~target_id;
10417 if (asc_dvc->cur_total_qng >= n_q_used) {
10418 asc_dvc->cur_total_qng -= n_q_used;
10419 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
10420 asc_dvc->cur_dvc_qng[tid_no]--;
10422 } else {
10423 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
10424 scsiq->d3.done_stat = QD_WITH_ERROR;
10425 goto FATAL_ERR_QDONE;
10427 if ((scsiq->d2.srb_ptr == 0UL) ||
10428 ((scsiq->q_status & QS_ABORTED) != 0)) {
10429 return (0x11);
10430 } else if (scsiq->q_status == QS_DONE) {
10431 false_overrun = FALSE;
10432 if (scsiq->extra_bytes != 0) {
10433 scsiq->remain_bytes += (ADV_DCNT) scsiq->extra_bytes;
10435 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
10436 if (scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN) {
10437 if ((scsiq->cntl & (QC_DATA_IN | QC_DATA_OUT)) == 0) {
10438 scsiq->d3.done_stat = QD_NO_ERROR;
10439 scsiq->d3.host_stat = QHSTA_NO_ERROR;
10440 } else if (false_overrun) {
10441 scsiq->d3.done_stat = QD_NO_ERROR;
10442 scsiq->d3.host_stat = QHSTA_NO_ERROR;
10444 } else if (scsiq->d3.host_stat ==
10445 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
10446 AscStopChip(iop_base);
10447 AscSetChipControl(iop_base,
10448 (uchar) (CC_SCSI_RESET | CC_HALT));
10449 DvcDelayNanoSecond(asc_dvc, 60000);
10450 AscSetChipControl(iop_base, CC_HALT);
10451 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10452 AscSetChipStatus(iop_base, 0);
10453 AscSetChipControl(iop_base, 0);
10456 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
10457 (*asc_isr_callback) (asc_dvc, scsiq);
10458 } else {
10459 if ((AscReadLramByte(iop_base,
10460 (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) ==
10461 START_STOP)) {
10462 asc_dvc->unit_not_ready &= ~target_id;
10463 if (scsiq->d3.done_stat != QD_NO_ERROR) {
10464 asc_dvc->start_motor &= ~target_id;
10468 return (1);
10469 } else {
10470 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
10471 FATAL_ERR_QDONE:
10472 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
10473 (*asc_isr_callback) (asc_dvc, scsiq);
10475 return (0x80);
10478 return (0);
10481 STATIC int
10482 AscISR(
10483 ASC_DVC_VAR *asc_dvc
10486 ASC_CS_TYPE chipstat;
10487 PortAddr iop_base;
10488 ushort saved_ram_addr;
10489 uchar ctrl_reg;
10490 uchar saved_ctrl_reg;
10491 int int_pending;
10492 int status;
10493 uchar host_flag;
10495 iop_base = asc_dvc->iop_base;
10496 int_pending = FALSE;
10498 if (AscIsIntPending(iop_base) == 0)
10500 return int_pending;
10503 if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
10504 || (asc_dvc->isr_callback == 0)
10506 return (ERR);
10508 if (asc_dvc->in_critical_cnt != 0) {
10509 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
10510 return (ERR);
10512 if (asc_dvc->is_in_int) {
10513 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
10514 return (ERR);
10516 asc_dvc->is_in_int = TRUE;
10517 ctrl_reg = AscGetChipControl(iop_base);
10518 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
10519 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
10520 chipstat = AscGetChipStatus(iop_base);
10521 if (chipstat & CSW_SCSI_RESET_LATCH) {
10522 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
10523 int i = 10;
10524 int_pending = TRUE;
10525 asc_dvc->sdtr_done = 0;
10526 saved_ctrl_reg &= (uchar) (~CC_HALT);
10527 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) &&
10528 (i-- > 0))
10530 DvcSleepMilliSecond(100);
10532 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
10533 AscSetChipControl(iop_base, CC_HALT);
10534 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10535 AscSetChipStatus(iop_base, 0);
10536 chipstat = AscGetChipStatus(iop_base);
10539 saved_ram_addr = AscGetChipLramAddr(iop_base);
10540 host_flag = AscReadLramByte(iop_base,
10541 ASCV_HOST_FLAG_B) & (uchar) (~ASC_HOST_FLAG_IN_ISR);
10542 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10543 (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR));
10544 if ((chipstat & CSW_INT_PENDING)
10545 || (int_pending)
10547 AscAckInterrupt(iop_base);
10548 int_pending = TRUE;
10549 if ((chipstat & CSW_HALTED) &&
10550 (ctrl_reg & CC_SINGLE_STEP)) {
10551 if (AscIsrChipHalted(asc_dvc) == ERR) {
10552 goto ISR_REPORT_QDONE_FATAL_ERROR;
10553 } else {
10554 saved_ctrl_reg &= (uchar) (~CC_HALT);
10556 } else {
10557 ISR_REPORT_QDONE_FATAL_ERROR:
10558 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
10559 while (((status = AscIsrQDone(asc_dvc)) & 0x01) != 0) {
10561 } else {
10562 do {
10563 if ((status = AscIsrQDone(asc_dvc)) == 1) {
10564 break;
10566 } while (status == 0x11);
10568 if ((status & 0x80) != 0)
10569 int_pending = ERR;
10572 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10573 AscSetChipLramAddr(iop_base, saved_ram_addr);
10574 AscSetChipControl(iop_base, saved_ctrl_reg);
10575 asc_dvc->is_in_int = FALSE;
10576 return (int_pending);
10579 /* Microcode buffer is kept after initialization for error recovery. */
10580 STATIC uchar _asc_mcode_buf[] =
10582 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10583 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10584 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10585 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10586 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
10587 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10588 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
10589 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00,
10590 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
10591 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2, 0xC2, 0x00, 0x92, 0x80,
10592 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80,
10593 0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
10594 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8, 0xCD, 0x04, 0x4D, 0x00,
10595 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1,
10596 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88,
10597 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00, 0x84, 0x97, 0x07, 0xA6,
10598 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00,
10599 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6,
10600 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6, 0x34, 0x01, 0x00, 0x33,
10601 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04,
10602 0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23,
10603 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01, 0x00, 0x33, 0x0A, 0x00,
10604 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04,
10605 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01,
10606 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3, 0x3C, 0x01, 0x00, 0x05,
10607 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01,
10608 0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0,
10609 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00, 0xC2, 0x88, 0x06, 0x23,
10610 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0,
10611 0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61,
10612 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC, 0x4F, 0x00, 0x84, 0x97,
10613 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80,
10614 0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
10615 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88, 0x04, 0x98, 0xF0, 0x80,
10616 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6,
10617 0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95,
10618 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02, 0x07, 0xA6, 0x5A, 0x02,
10619 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96,
10620 0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC,
10621 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01, 0x6F, 0x00, 0xA5, 0x01,
10622 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02,
10623 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02,
10624 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E, 0x80, 0x63, 0x00, 0x43,
10625 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01,
10626 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82,
10627 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8, 0x00, 0x33, 0x1F, 0x00,
10628 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6,
10629 0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6,
10630 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xEE, 0x82,
10631 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8,
10632 0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98,
10633 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6, 0x3C, 0x04, 0x06, 0xA6,
10634 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83,
10635 0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33,
10636 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05, 0xFF, 0xA2, 0x7A, 0x03,
10637 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03,
10638 0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03,
10639 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6, 0xA4, 0x03, 0x00, 0xA6,
10640 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03,
10641 0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42,
10642 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95, 0xC0, 0x83, 0x00, 0x33,
10643 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23,
10644 0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
10645 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04, 0x06, 0xA6, 0x0A, 0x04,
10646 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84,
10647 0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
10648 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6, 0x38, 0x04, 0x00, 0x33,
10649 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC,
10650 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
10651 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0xA3, 0x01,
10652 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00,
10653 0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
10654 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04, 0x08, 0x23, 0x22, 0xA3,
10655 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23,
10656 0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98,
10657 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20, 0x81, 0x62, 0xE8, 0x81,
10658 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81,
10659 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23,
10660 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3, 0xF4, 0x04, 0x00, 0x33,
10661 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01,
10662 0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
10663 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85, 0x46, 0x97, 0xCD, 0x04,
10664 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85,
10665 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
10666 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x49, 0x00, 0x81, 0x01,
10667 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01,
10668 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
10669 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63, 0x07, 0xA4, 0xF8, 0x05,
10670 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0,
10671 0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
10672 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00, 0x62, 0x97, 0x04, 0x85,
10673 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0,
10674 0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
10675 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05, 0x80, 0x67, 0x80, 0x63,
10676 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23,
10677 0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
10678 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23, 0x07, 0x41, 0x83, 0x03,
10679 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6,
10680 0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
10681 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00, 0x52, 0x00, 0x06, 0x61,
10682 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01,
10683 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
10684 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23, 0xDF, 0x00, 0x06, 0xA6,
10685 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20,
10686 0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
10687 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B, 0x40, 0x0E, 0x80, 0x63,
10688 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43,
10689 0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
10690 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x07, 0xA6, 0xD6, 0x06,
10691 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6,
10692 0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
10693 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20, 0x81, 0x62, 0x04, 0x01,
10694 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33,
10695 0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
10696 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88, 0x00, 0x00, 0x80, 0x67,
10697 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61,
10698 0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
10699 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04, 0x80, 0x05, 0x81, 0x05,
10700 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01,
10701 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
10702 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01, 0xF1, 0x00, 0x70, 0x00,
10703 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00,
10704 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
10705 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1, 0xC4, 0x07, 0x00, 0x33,
10706 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01,
10707 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
10708 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x05, 0x05, 0x00, 0x63,
10709 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02,
10710 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
10711 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63, 0xF3, 0x04,
10712 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08,
10713 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
10714 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04, 0x5A, 0x88, 0x02, 0x01,
10715 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08,
10716 0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
10717 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x38, 0x2B,
10718 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09,
10719 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
10720 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32, 0x40, 0x36, 0x40, 0x3A,
10721 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3,
10722 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
10723 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01, 0xA1, 0x23, 0xA1, 0x01,
10724 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2,
10725 0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
10728 STATIC ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
10729 STATIC ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
10731 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
10732 STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] =
10734 INQUIRY,
10735 REQUEST_SENSE,
10736 READ_CAPACITY,
10737 READ_TOC,
10738 MODE_SELECT,
10739 MODE_SENSE,
10740 MODE_SELECT_10,
10741 MODE_SENSE_10,
10742 0xFF,
10743 0xFF,
10744 0xFF,
10745 0xFF,
10746 0xFF,
10747 0xFF,
10748 0xFF,
10749 0xFF
10752 STATIC int
10753 AscExeScsiQueue(
10754 ASC_DVC_VAR *asc_dvc,
10755 ASC_SCSI_Q *scsiq
10758 PortAddr iop_base;
10759 ulong last_int_level;
10760 int sta;
10761 int n_q_required;
10762 int disable_syn_offset_one_fix;
10763 int i;
10764 ASC_PADDR addr;
10765 ASC_EXE_CALLBACK asc_exe_callback;
10766 ushort sg_entry_cnt = 0;
10767 ushort sg_entry_cnt_minus_one = 0;
10768 uchar target_ix;
10769 uchar tid_no;
10770 uchar sdtr_data;
10771 uchar extra_bytes;
10772 uchar scsi_cmd;
10773 uchar disable_cmd;
10774 ASC_SG_HEAD *sg_head;
10775 ASC_DCNT data_cnt;
10777 iop_base = asc_dvc->iop_base;
10778 sg_head = scsiq->sg_head;
10779 asc_exe_callback = asc_dvc->exe_callback;
10780 if (asc_dvc->err_code != 0)
10781 return (ERR);
10782 if (scsiq == (ASC_SCSI_Q *) 0L) {
10783 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
10784 return (ERR);
10786 scsiq->q1.q_no = 0;
10787 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
10788 scsiq->q1.extra_bytes = 0;
10790 sta = 0;
10791 target_ix = scsiq->q2.target_ix;
10792 tid_no = ASC_TIX_TO_TID(target_ix);
10793 n_q_required = 1;
10794 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
10795 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
10796 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
10797 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10798 AscMsgOutSDTR(asc_dvc,
10799 asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
10800 (uchar) (asc_dvc->max_sdtr_index - 1)],
10801 (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
10802 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
10805 last_int_level = DvcEnterCritical();
10806 if (asc_dvc->in_critical_cnt != 0) {
10807 DvcLeaveCritical(last_int_level);
10808 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
10809 return (ERR);
10811 asc_dvc->in_critical_cnt++;
10812 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10813 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
10814 asc_dvc->in_critical_cnt--;
10815 DvcLeaveCritical(last_int_level);
10816 return (ERR);
10818 #if !CC_VERY_LONG_SG_LIST
10819 if (sg_entry_cnt > ASC_MAX_SG_LIST)
10821 asc_dvc->in_critical_cnt--;
10822 DvcLeaveCritical(last_int_level);
10823 return(ERR);
10825 #endif /* !CC_VERY_LONG_SG_LIST */
10826 if (sg_entry_cnt == 1) {
10827 scsiq->q1.data_addr = (ADV_PADDR) sg_head->sg_list[0].addr;
10828 scsiq->q1.data_cnt = (ADV_DCNT) sg_head->sg_list[0].bytes;
10829 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
10831 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
10833 scsi_cmd = scsiq->cdbptr[0];
10834 disable_syn_offset_one_fix = FALSE;
10835 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
10836 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
10837 if (scsiq->q1.cntl & QC_SG_HEAD) {
10838 data_cnt = 0;
10839 for (i = 0; i < sg_entry_cnt; i++) {
10840 data_cnt += (ADV_DCNT) le32_to_cpu(sg_head->sg_list[i].bytes);
10842 } else {
10843 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
10845 if (data_cnt != 0UL) {
10846 if (data_cnt < 512UL) {
10847 disable_syn_offset_one_fix = TRUE;
10848 } else {
10849 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST; i++) {
10850 disable_cmd = _syn_offset_one_disable_cmd[i];
10851 if (disable_cmd == 0xFF) {
10852 break;
10854 if (scsi_cmd == disable_cmd) {
10855 disable_syn_offset_one_fix = TRUE;
10856 break;
10862 if (disable_syn_offset_one_fix) {
10863 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
10864 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
10865 ASC_TAG_FLAG_DISABLE_DISCONNECT);
10866 } else {
10867 scsiq->q2.tag_code &= 0x27;
10869 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10870 if (asc_dvc->bug_fix_cntl) {
10871 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10872 if ((scsi_cmd == READ_6) ||
10873 (scsi_cmd == READ_10)) {
10874 addr =
10875 (ADV_PADDR) le32_to_cpu(
10876 sg_head->sg_list[sg_entry_cnt_minus_one].addr) +
10877 (ADV_DCNT) le32_to_cpu(
10878 sg_head->sg_list[sg_entry_cnt_minus_one].bytes);
10879 extra_bytes = (uchar) ((ushort) addr & 0x0003);
10880 if ((extra_bytes != 0) &&
10881 ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
10882 == 0)) {
10883 scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
10884 scsiq->q1.extra_bytes = extra_bytes;
10885 data_cnt = le32_to_cpu(
10886 sg_head->sg_list[sg_entry_cnt_minus_one].bytes);
10887 data_cnt -= (ASC_DCNT) extra_bytes;
10888 sg_head->sg_list[sg_entry_cnt_minus_one].bytes =
10889 cpu_to_le32(data_cnt);
10894 sg_head->entry_to_copy = sg_head->entry_cnt;
10895 #if CC_VERY_LONG_SG_LIST
10897 * Set the sg_entry_cnt to the maximum possible. The rest of
10898 * the SG elements will be copied when the RISC completes the
10899 * SG elements that fit and halts.
10901 if (sg_entry_cnt > ASC_MAX_SG_LIST)
10903 sg_entry_cnt = ASC_MAX_SG_LIST;
10905 #endif /* CC_VERY_LONG_SG_LIST */
10906 n_q_required = AscSgListToQueue(sg_entry_cnt);
10907 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
10908 (uint) n_q_required) || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
10909 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
10910 n_q_required)) == 1) {
10911 asc_dvc->in_critical_cnt--;
10912 if (asc_exe_callback != 0) {
10913 (*asc_exe_callback) (asc_dvc, scsiq);
10915 DvcLeaveCritical(last_int_level);
10916 return (sta);
10919 } else {
10920 if (asc_dvc->bug_fix_cntl) {
10921 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10922 if ((scsi_cmd == READ_6) ||
10923 (scsi_cmd == READ_10)) {
10924 addr = le32_to_cpu(scsiq->q1.data_addr) +
10925 le32_to_cpu(scsiq->q1.data_cnt);
10926 extra_bytes = (uchar) ((ushort) addr & 0x0003);
10927 if ((extra_bytes != 0) &&
10928 ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
10929 == 0)) {
10930 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
10931 if (((ushort) data_cnt & 0x01FF) == 0) {
10932 scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
10933 data_cnt -= (ASC_DCNT) extra_bytes;
10934 scsiq->q1.data_cnt = cpu_to_le32(data_cnt);
10935 scsiq->q1.extra_bytes = extra_bytes;
10941 n_q_required = 1;
10942 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
10943 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
10944 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
10945 n_q_required)) == 1) {
10946 asc_dvc->in_critical_cnt--;
10947 if (asc_exe_callback != 0) {
10948 (*asc_exe_callback) (asc_dvc, scsiq);
10950 DvcLeaveCritical(last_int_level);
10951 return (sta);
10955 asc_dvc->in_critical_cnt--;
10956 DvcLeaveCritical(last_int_level);
10957 return (sta);
10960 STATIC int
10961 AscSendScsiQueue(
10962 ASC_DVC_VAR *asc_dvc,
10963 ASC_SCSI_Q *scsiq,
10964 uchar n_q_required
10967 PortAddr iop_base;
10968 uchar free_q_head;
10969 uchar next_qp;
10970 uchar tid_no;
10971 uchar target_ix;
10972 int sta;
10974 iop_base = asc_dvc->iop_base;
10975 target_ix = scsiq->q2.target_ix;
10976 tid_no = ASC_TIX_TO_TID(target_ix);
10977 sta = 0;
10978 free_q_head = (uchar) AscGetVarFreeQHead(iop_base);
10979 if (n_q_required > 1) {
10980 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
10981 free_q_head, (uchar) (n_q_required)))
10982 != (uchar) ASC_QLINK_END) {
10983 asc_dvc->last_q_shortage = 0;
10984 scsiq->sg_head->queue_cnt = n_q_required - 1;
10985 scsiq->q1.q_no = free_q_head;
10986 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
10987 free_q_head)) == 1) {
10988 AscPutVarFreeQHead(iop_base, next_qp);
10989 asc_dvc->cur_total_qng += (uchar) (n_q_required);
10990 asc_dvc->cur_dvc_qng[tid_no]++;
10992 return (sta);
10994 } else if (n_q_required == 1) {
10995 if ((next_qp = AscAllocFreeQueue(iop_base,
10996 free_q_head)) != ASC_QLINK_END) {
10997 scsiq->q1.q_no = free_q_head;
10998 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
10999 free_q_head)) == 1) {
11000 AscPutVarFreeQHead(iop_base, next_qp);
11001 asc_dvc->cur_total_qng++;
11002 asc_dvc->cur_dvc_qng[tid_no]++;
11004 return (sta);
11007 return (sta);
11010 STATIC int
11011 AscSgListToQueue(
11012 int sg_list
11015 int n_sg_list_qs;
11017 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
11018 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
11019 n_sg_list_qs++;
11020 return (n_sg_list_qs + 1);
11024 STATIC uint
11025 AscGetNumOfFreeQueue(
11026 ASC_DVC_VAR *asc_dvc,
11027 uchar target_ix,
11028 uchar n_qs
11031 uint cur_used_qs;
11032 uint cur_free_qs;
11033 ASC_SCSI_BIT_ID_TYPE target_id;
11034 uchar tid_no;
11036 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
11037 tid_no = ASC_TIX_TO_TID(target_ix);
11038 if ((asc_dvc->unit_not_ready & target_id) ||
11039 (asc_dvc->queue_full_or_busy & target_id)) {
11040 return (0);
11042 if (n_qs == 1) {
11043 cur_used_qs = (uint) asc_dvc->cur_total_qng +
11044 (uint) asc_dvc->last_q_shortage +
11045 (uint) ASC_MIN_FREE_Q;
11046 } else {
11047 cur_used_qs = (uint) asc_dvc->cur_total_qng +
11048 (uint) ASC_MIN_FREE_Q;
11050 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
11051 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
11052 if (asc_dvc->cur_dvc_qng[tid_no] >=
11053 asc_dvc->max_dvc_qng[tid_no]) {
11054 return (0);
11056 return (cur_free_qs);
11058 if (n_qs > 1) {
11059 if ((n_qs > asc_dvc->last_q_shortage) && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
11060 asc_dvc->last_q_shortage = n_qs;
11063 return (0);
11066 STATIC int
11067 AscPutReadyQueue(
11068 ASC_DVC_VAR *asc_dvc,
11069 ASC_SCSI_Q *scsiq,
11070 uchar q_no
11073 ushort q_addr;
11074 uchar tid_no;
11075 uchar sdtr_data;
11076 uchar syn_period_ix;
11077 uchar syn_offset;
11078 PortAddr iop_base;
11080 iop_base = asc_dvc->iop_base;
11081 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
11082 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
11083 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
11084 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
11085 syn_period_ix = (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
11086 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
11087 AscMsgOutSDTR(asc_dvc,
11088 asc_dvc->sdtr_period_tbl[syn_period_ix],
11089 syn_offset);
11090 scsiq->q1.cntl |= QC_MSG_OUT;
11092 q_addr = ASC_QNO_TO_QADDR(q_no);
11093 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
11094 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG ;
11096 scsiq->q1.status = QS_FREE;
11097 AscMemWordCopyPtrToLram(iop_base,
11098 q_addr + ASC_SCSIQ_CDB_BEG,
11099 (uchar *) scsiq->cdbptr,
11100 scsiq->q2.cdb_len >> 1);
11102 DvcPutScsiQ(iop_base,
11103 q_addr + ASC_SCSIQ_CPY_BEG,
11104 (uchar *) &scsiq->q1.cntl,
11105 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
11106 AscWriteLramWord(iop_base,
11107 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
11108 (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY));
11109 return (1);
11112 STATIC int
11113 AscPutReadySgListQueue(
11114 ASC_DVC_VAR *asc_dvc,
11115 ASC_SCSI_Q *scsiq,
11116 uchar q_no
11119 int sta;
11120 int i;
11121 ASC_SG_HEAD *sg_head;
11122 ASC_SG_LIST_Q scsi_sg_q;
11123 ASC_DCNT saved_data_addr;
11124 ASC_DCNT saved_data_cnt;
11125 PortAddr iop_base;
11126 ushort sg_list_dwords;
11127 ushort sg_index;
11128 ushort sg_entry_cnt;
11129 ushort q_addr;
11130 uchar next_qp;
11132 iop_base = asc_dvc->iop_base;
11133 sg_head = scsiq->sg_head;
11134 saved_data_addr = scsiq->q1.data_addr;
11135 saved_data_cnt = scsiq->q1.data_cnt;
11136 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
11137 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
11138 #if CC_VERY_LONG_SG_LIST
11140 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
11141 * then not all SG elements will fit in the allocated queues.
11142 * The rest of the SG elements will be copied when the RISC
11143 * completes the SG elements that fit and halts.
11145 if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
11148 * Set sg_entry_cnt to be the number of SG elements that
11149 * will fit in the allocated SG queues. It is minus 1, because
11150 * the first SG element is handled above. ASC_MAX_SG_LIST is
11151 * already inflated by 1 to account for this. For example it
11152 * may be 50 which is 1 + 7 queues * 7 SG elements.
11154 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
11157 * Keep track of remaining number of SG elements that will
11158 * need to be handled from a_isr.c.
11160 scsiq->remain_sg_entry_cnt = sg_head->entry_cnt - ASC_MAX_SG_LIST;
11161 } else
11163 #endif /* CC_VERY_LONG_SG_LIST */
11165 * Set sg_entry_cnt to be the number of SG elements that
11166 * will fit in the allocated SG queues. It is minus 1, because
11167 * the first SG element is handled above.
11169 sg_entry_cnt = sg_head->entry_cnt - 1;
11170 #if CC_VERY_LONG_SG_LIST
11172 #endif /* CC_VERY_LONG_SG_LIST */
11173 if (sg_entry_cnt != 0) {
11174 scsiq->q1.cntl |= QC_SG_HEAD;
11175 q_addr = ASC_QNO_TO_QADDR(q_no);
11176 sg_index = 1;
11177 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
11178 scsi_sg_q.sg_head_qp = q_no;
11179 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
11180 for (i = 0; i < sg_head->queue_cnt; i++) {
11181 scsi_sg_q.seq_no = i + 1;
11182 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
11183 sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
11184 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
11185 if (i == 0) {
11186 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q;
11187 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q;
11188 } else {
11189 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
11190 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
11192 } else {
11193 #if CC_VERY_LONG_SG_LIST
11195 * This is the last SG queue in the list of
11196 * allocated SG queues. If there are more
11197 * SG elements than will fit in the allocated
11198 * queues, then set the QCSG_SG_XFER_MORE flag.
11200 if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
11202 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
11203 } else
11205 #endif /* CC_VERY_LONG_SG_LIST */
11206 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
11207 #if CC_VERY_LONG_SG_LIST
11209 #endif /* CC_VERY_LONG_SG_LIST */
11210 sg_list_dwords = sg_entry_cnt << 1;
11211 if (i == 0) {
11212 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
11213 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt;
11214 } else {
11215 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
11216 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
11218 sg_entry_cnt = 0;
11220 next_qp = AscReadLramByte(iop_base,
11221 (ushort) (q_addr + ASC_SCSIQ_B_FWD));
11222 scsi_sg_q.q_no = next_qp;
11223 q_addr = ASC_QNO_TO_QADDR(next_qp);
11224 AscMemWordCopyPtrToLram(iop_base,
11225 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
11226 (uchar *) &scsi_sg_q,
11227 sizeof(ASC_SG_LIST_Q) >> 1);
11228 AscMemDWordCopyPtrToLram(iop_base,
11229 q_addr + ASC_SGQ_LIST_BEG,
11230 (uchar *) &sg_head->sg_list[sg_index],
11231 sg_list_dwords);
11232 sg_index += ASC_SG_LIST_PER_Q;
11233 scsiq->next_sg_index = sg_index;
11235 } else {
11236 scsiq->q1.cntl &= ~QC_SG_HEAD;
11238 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
11239 scsiq->q1.data_addr = saved_data_addr;
11240 scsiq->q1.data_cnt = saved_data_cnt;
11241 return (sta);
11244 STATIC int
11245 AscSetRunChipSynRegAtID(
11246 PortAddr iop_base,
11247 uchar tid_no,
11248 uchar sdtr_data
11251 int sta = FALSE;
11253 if (AscHostReqRiscHalt(iop_base)) {
11254 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
11255 AscStartChip(iop_base);
11256 return (sta);
11258 return (sta);
11261 STATIC int
11262 AscSetChipSynRegAtID(
11263 PortAddr iop_base,
11264 uchar id,
11265 uchar sdtr_data
11268 ASC_SCSI_BIT_ID_TYPE org_id;
11269 int i;
11270 int sta = TRUE;
11272 AscSetBank(iop_base, 1);
11273 org_id = AscReadChipDvcID(iop_base);
11274 for (i = 0; i <= ASC_MAX_TID; i++) {
11275 if (org_id == (0x01 << i))
11276 break;
11278 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
11279 AscWriteChipDvcID(iop_base, id);
11280 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
11281 AscSetBank(iop_base, 0);
11282 AscSetChipSyn(iop_base, sdtr_data);
11283 if (AscGetChipSyn(iop_base) != sdtr_data) {
11284 sta = FALSE;
11286 } else {
11287 sta = FALSE;
11289 AscSetBank(iop_base, 1);
11290 AscWriteChipDvcID(iop_base, org_id);
11291 AscSetBank(iop_base, 0);
11292 return (sta);
11295 STATIC ushort
11296 AscInitLram(
11297 ASC_DVC_VAR *asc_dvc
11300 uchar i;
11301 ushort s_addr;
11302 PortAddr iop_base;
11303 ushort warn_code;
11305 iop_base = asc_dvc->iop_base;
11306 warn_code = 0;
11307 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
11308 (ushort) (((int) (asc_dvc->max_total_qng + 2 + 1) * 64) >> 1)
11310 i = ASC_MIN_ACTIVE_QNO;
11311 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
11312 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11313 (uchar) (i + 1));
11314 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11315 (uchar) (asc_dvc->max_total_qng));
11316 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11317 (uchar) i);
11318 i++;
11319 s_addr += ASC_QBLK_SIZE;
11320 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
11321 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11322 (uchar) (i + 1));
11323 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11324 (uchar) (i - 1));
11325 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11326 (uchar) i);
11328 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11329 (uchar) ASC_QLINK_END);
11330 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11331 (uchar) (asc_dvc->max_total_qng - 1));
11332 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11333 (uchar) asc_dvc->max_total_qng);
11334 i++;
11335 s_addr += ASC_QBLK_SIZE;
11336 for (; i <= (uchar) (asc_dvc->max_total_qng + 3);
11337 i++, s_addr += ASC_QBLK_SIZE) {
11338 AscWriteLramByte(iop_base,
11339 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_FWD), i);
11340 AscWriteLramByte(iop_base,
11341 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_BWD), i);
11342 AscWriteLramByte(iop_base,
11343 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_QNO), i);
11345 return (warn_code);
11348 STATIC ushort
11349 AscInitQLinkVar(
11350 ASC_DVC_VAR *asc_dvc
11353 PortAddr iop_base;
11354 int i;
11355 ushort lram_addr;
11357 iop_base = asc_dvc->iop_base;
11358 AscPutRiscVarFreeQHead(iop_base, 1);
11359 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
11360 AscPutVarFreeQHead(iop_base, 1);
11361 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
11362 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
11363 (uchar) ((int) asc_dvc->max_total_qng + 1));
11364 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
11365 (uchar) ((int) asc_dvc->max_total_qng + 2));
11366 AscWriteLramByte(iop_base, (ushort) ASCV_TOTAL_READY_Q_B,
11367 asc_dvc->max_total_qng);
11368 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
11369 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
11370 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
11371 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
11372 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
11373 AscPutQDoneInProgress(iop_base, 0);
11374 lram_addr = ASC_QADR_BEG;
11375 for (i = 0; i < 32; i++, lram_addr += 2) {
11376 AscWriteLramWord(iop_base, lram_addr, 0);
11378 return (0);
11381 STATIC int
11382 AscSetLibErrorCode(
11383 ASC_DVC_VAR *asc_dvc,
11384 ushort err_code
11387 if (asc_dvc->err_code == 0) {
11388 asc_dvc->err_code = err_code;
11389 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
11390 err_code);
11392 return (err_code);
11396 STATIC uchar
11397 AscMsgOutSDTR(
11398 ASC_DVC_VAR *asc_dvc,
11399 uchar sdtr_period,
11400 uchar sdtr_offset
11403 EXT_MSG sdtr_buf;
11404 uchar sdtr_period_index;
11405 PortAddr iop_base;
11407 iop_base = asc_dvc->iop_base;
11408 sdtr_buf.msg_type = MS_EXTEND;
11409 sdtr_buf.msg_len = MS_SDTR_LEN;
11410 sdtr_buf.msg_req = MS_SDTR_CODE;
11411 sdtr_buf.xfer_period = sdtr_period;
11412 sdtr_offset &= ASC_SYN_MAX_OFFSET;
11413 sdtr_buf.req_ack_offset = sdtr_offset;
11414 if ((sdtr_period_index =
11415 AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
11416 asc_dvc->max_sdtr_index) {
11417 AscMemWordCopyPtrToLram(iop_base,
11418 ASCV_MSGOUT_BEG,
11419 (uchar *) &sdtr_buf,
11420 sizeof (EXT_MSG) >> 1);
11421 return ((sdtr_period_index << 4) | sdtr_offset);
11422 } else {
11424 sdtr_buf.req_ack_offset = 0;
11425 AscMemWordCopyPtrToLram(iop_base,
11426 ASCV_MSGOUT_BEG,
11427 (uchar *) &sdtr_buf,
11428 sizeof (EXT_MSG) >> 1);
11429 return (0);
11433 STATIC uchar
11434 AscCalSDTRData(
11435 ASC_DVC_VAR *asc_dvc,
11436 uchar sdtr_period,
11437 uchar syn_offset
11440 uchar byte;
11441 uchar sdtr_period_ix;
11443 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
11444 if (
11445 (sdtr_period_ix > asc_dvc->max_sdtr_index)
11447 return (0xFF);
11449 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
11450 return (byte);
11453 STATIC void
11454 AscSetChipSDTR(
11455 PortAddr iop_base,
11456 uchar sdtr_data,
11457 uchar tid_no
11460 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
11461 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
11462 return;
11465 STATIC uchar
11466 AscGetSynPeriodIndex(
11467 ASC_DVC_VAR *asc_dvc,
11468 uchar syn_time
11471 uchar *period_table;
11472 int max_index;
11473 int min_index;
11474 int i;
11476 period_table = asc_dvc->sdtr_period_tbl;
11477 max_index = (int) asc_dvc->max_sdtr_index;
11478 min_index = (int)asc_dvc->host_init_sdtr_index;
11479 if ((syn_time <= period_table[max_index])) {
11480 for (i = min_index; i < (max_index - 1); i++) {
11481 if (syn_time <= period_table[i]) {
11482 return ((uchar) i);
11485 return ((uchar) max_index);
11486 } else {
11487 return ((uchar) (max_index + 1));
11491 STATIC uchar
11492 AscAllocFreeQueue(
11493 PortAddr iop_base,
11494 uchar free_q_head
11497 ushort q_addr;
11498 uchar next_qp;
11499 uchar q_status;
11501 q_addr = ASC_QNO_TO_QADDR(free_q_head);
11502 q_status = (uchar) AscReadLramByte(iop_base,
11503 (ushort) (q_addr + ASC_SCSIQ_B_STATUS));
11504 next_qp = AscReadLramByte(iop_base,
11505 (ushort) (q_addr + ASC_SCSIQ_B_FWD));
11506 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
11507 return (next_qp);
11509 return (ASC_QLINK_END);
11512 STATIC uchar
11513 AscAllocMultipleFreeQueue(
11514 PortAddr iop_base,
11515 uchar free_q_head,
11516 uchar n_free_q
11519 uchar i;
11521 for (i = 0; i < n_free_q; i++) {
11522 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
11523 == ASC_QLINK_END) {
11524 return (ASC_QLINK_END);
11527 return (free_q_head);
11530 STATIC int
11531 AscHostReqRiscHalt(
11532 PortAddr iop_base
11535 int count = 0;
11536 int sta = 0;
11537 uchar saved_stop_code;
11539 if (AscIsChipHalted(iop_base))
11540 return (1);
11541 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
11542 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11543 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP
11545 do {
11546 if (AscIsChipHalted(iop_base)) {
11547 sta = 1;
11548 break;
11550 DvcSleepMilliSecond(100);
11551 } while (count++ < 20);
11552 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
11553 return (sta);
11556 STATIC int
11557 AscStopQueueExe(
11558 PortAddr iop_base
11561 int count = 0;
11563 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
11564 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11565 ASC_STOP_REQ_RISC_STOP);
11566 do {
11567 if (
11568 AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
11569 ASC_STOP_ACK_RISC_STOP) {
11570 return (1);
11572 DvcSleepMilliSecond(100);
11573 } while (count++ < 20);
11575 return (0);
11578 STATIC void
11579 DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
11581 udelay(micro_sec);
11584 STATIC void
11585 DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
11587 udelay((nano_sec + 999)/1000);
11590 #ifdef CONFIG_ISA
11591 STATIC ASC_DCNT __init
11592 AscGetEisaProductID(
11593 PortAddr iop_base)
11595 PortAddr eisa_iop;
11596 ushort product_id_high, product_id_low;
11597 ASC_DCNT product_id;
11599 eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
11600 product_id_low = inpw(eisa_iop);
11601 product_id_high = inpw(eisa_iop + 2);
11602 product_id = ((ASC_DCNT) product_id_high << 16) |
11603 (ASC_DCNT) product_id_low;
11604 return (product_id);
11607 STATIC PortAddr __init
11608 AscSearchIOPortAddrEISA(
11609 PortAddr iop_base)
11611 ASC_DCNT eisa_product_id;
11613 if (iop_base == 0) {
11614 iop_base = ASC_EISA_MIN_IOP_ADDR;
11615 } else {
11616 if (iop_base == ASC_EISA_MAX_IOP_ADDR)
11617 return (0);
11618 if ((iop_base & 0x0050) == 0x0050) {
11619 iop_base += ASC_EISA_BIG_IOP_GAP;
11620 } else {
11621 iop_base += ASC_EISA_SMALL_IOP_GAP;
11624 while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
11625 eisa_product_id = AscGetEisaProductID(iop_base);
11626 if ((eisa_product_id == ASC_EISA_ID_740) ||
11627 (eisa_product_id == ASC_EISA_ID_750)) {
11628 if (AscFindSignature(iop_base)) {
11629 inpw(iop_base + 4);
11630 return (iop_base);
11633 if (iop_base == ASC_EISA_MAX_IOP_ADDR)
11634 return (0);
11635 if ((iop_base & 0x0050) == 0x0050) {
11636 iop_base += ASC_EISA_BIG_IOP_GAP;
11637 } else {
11638 iop_base += ASC_EISA_SMALL_IOP_GAP;
11641 return (0);
11643 #endif /* CONFIG_ISA */
11645 STATIC int
11646 AscStartChip(
11647 PortAddr iop_base
11650 AscSetChipControl(iop_base, 0);
11651 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
11652 return (0);
11654 return (1);
11657 STATIC int
11658 AscStopChip(
11659 PortAddr iop_base
11662 uchar cc_val;
11664 cc_val = AscGetChipControl(iop_base) & (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
11665 AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT));
11666 AscSetChipIH(iop_base, INS_HALT);
11667 AscSetChipIH(iop_base, INS_RFLAG_WTM);
11668 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
11669 return (0);
11671 return (1);
11674 STATIC int
11675 AscIsChipHalted(
11676 PortAddr iop_base
11679 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
11680 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
11681 return (1);
11684 return (0);
11687 STATIC void
11688 AscSetChipIH(
11689 PortAddr iop_base,
11690 ushort ins_code
11693 AscSetBank(iop_base, 1);
11694 AscWriteChipIH(iop_base, ins_code);
11695 AscSetBank(iop_base, 0);
11696 return;
11699 STATIC void
11700 AscAckInterrupt(
11701 PortAddr iop_base
11704 uchar host_flag;
11705 uchar risc_flag;
11706 ushort loop;
11708 loop = 0;
11709 do {
11710 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
11711 if (loop++ > 0x7FFF) {
11712 break;
11714 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
11715 host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
11716 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
11717 (uchar) (host_flag | ASC_HOST_FLAG_ACK_INT));
11718 AscSetChipStatus(iop_base, CIW_INT_ACK);
11719 loop = 0;
11720 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
11721 AscSetChipStatus(iop_base, CIW_INT_ACK);
11722 if (loop++ > 3) {
11723 break;
11726 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
11727 return;
11730 STATIC void
11731 AscDisableInterrupt(
11732 PortAddr iop_base
11735 ushort cfg;
11737 cfg = AscGetChipCfgLsw(iop_base);
11738 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
11739 return;
11742 STATIC void
11743 AscEnableInterrupt(
11744 PortAddr iop_base
11747 ushort cfg;
11749 cfg = AscGetChipCfgLsw(iop_base);
11750 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
11751 return;
11756 STATIC void
11757 AscSetBank(
11758 PortAddr iop_base,
11759 uchar bank
11762 uchar val;
11764 val = AscGetChipControl(iop_base) &
11765 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | CC_CHIP_RESET));
11766 if (bank == 1) {
11767 val |= CC_BANK_ONE;
11768 } else if (bank == 2) {
11769 val |= CC_DIAG | CC_BANK_ONE;
11770 } else {
11771 val &= ~CC_BANK_ONE;
11773 AscSetChipControl(iop_base, val);
11774 return;
11777 STATIC int
11778 AscResetChipAndScsiBus(
11779 ASC_DVC_VAR *asc_dvc
11782 PortAddr iop_base;
11783 int i = 10;
11785 iop_base = asc_dvc->iop_base;
11786 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) && (i-- > 0))
11788 DvcSleepMilliSecond(100);
11790 AscStopChip(iop_base);
11791 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
11792 DvcDelayNanoSecond(asc_dvc, 60000);
11793 AscSetChipIH(iop_base, INS_RFLAG_WTM);
11794 AscSetChipIH(iop_base, INS_HALT);
11795 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
11796 AscSetChipControl(iop_base, CC_HALT);
11797 DvcSleepMilliSecond(200);
11798 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
11799 AscSetChipStatus(iop_base, 0);
11800 return (AscIsChipHalted(iop_base));
11803 STATIC ASC_DCNT __init
11804 AscGetMaxDmaCount(
11805 ushort bus_type)
11807 if (bus_type & ASC_IS_ISA)
11808 return (ASC_MAX_ISA_DMA_COUNT);
11809 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
11810 return (ASC_MAX_VL_DMA_COUNT);
11811 return (ASC_MAX_PCI_DMA_COUNT);
11814 #ifdef CONFIG_ISA
11815 STATIC ushort __init
11816 AscGetIsaDmaChannel(
11817 PortAddr iop_base)
11819 ushort channel;
11821 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
11822 if (channel == 0x03)
11823 return (0);
11824 else if (channel == 0x00)
11825 return (7);
11826 return (channel + 4);
11829 STATIC ushort __init
11830 AscSetIsaDmaChannel(
11831 PortAddr iop_base,
11832 ushort dma_channel)
11834 ushort cfg_lsw;
11835 uchar value;
11837 if ((dma_channel >= 5) && (dma_channel <= 7)) {
11838 if (dma_channel == 7)
11839 value = 0x00;
11840 else
11841 value = dma_channel - 4;
11842 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
11843 cfg_lsw |= value;
11844 AscSetChipCfgLsw(iop_base, cfg_lsw);
11845 return (AscGetIsaDmaChannel(iop_base));
11847 return (0);
11850 STATIC uchar __init
11851 AscSetIsaDmaSpeed(
11852 PortAddr iop_base,
11853 uchar speed_value)
11855 speed_value &= 0x07;
11856 AscSetBank(iop_base, 1);
11857 AscWriteChipDmaSpeed(iop_base, speed_value);
11858 AscSetBank(iop_base, 0);
11859 return (AscGetIsaDmaSpeed(iop_base));
11862 STATIC uchar __init
11863 AscGetIsaDmaSpeed(
11864 PortAddr iop_base
11867 uchar speed_value;
11869 AscSetBank(iop_base, 1);
11870 speed_value = AscReadChipDmaSpeed(iop_base);
11871 speed_value &= 0x07;
11872 AscSetBank(iop_base, 0);
11873 return (speed_value);
11875 #endif /* CONFIG_ISA */
11877 STATIC ushort __init
11878 AscReadPCIConfigWord(
11879 ASC_DVC_VAR *asc_dvc,
11880 ushort pci_config_offset)
11882 uchar lsb, msb;
11884 lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
11885 msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
11886 return ((ushort) ((msb << 8) | lsb));
11889 STATIC ushort __init
11890 AscInitGetConfig(
11891 ASC_DVC_VAR *asc_dvc
11894 ushort warn_code;
11895 PortAddr iop_base;
11896 ushort PCIDeviceID;
11897 ushort PCIVendorID;
11898 uchar PCIRevisionID;
11899 uchar prevCmdRegBits;
11901 warn_code = 0;
11902 iop_base = asc_dvc->iop_base;
11903 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
11904 if (asc_dvc->err_code != 0) {
11905 return (UW_ERR);
11907 if (asc_dvc->bus_type == ASC_IS_PCI) {
11908 PCIVendorID = AscReadPCIConfigWord(asc_dvc,
11909 AscPCIConfigVendorIDRegister);
11911 PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
11912 AscPCIConfigDeviceIDRegister);
11914 PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
11915 AscPCIConfigRevisionIDRegister);
11917 if (PCIVendorID != PCI_VENDOR_ID_ASP) {
11918 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
11920 prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
11921 AscPCIConfigCommandRegister);
11923 if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
11924 AscPCICmdRegBits_IOMemBusMaster) {
11925 DvcWritePCIConfigByte(asc_dvc,
11926 AscPCIConfigCommandRegister,
11927 (prevCmdRegBits |
11928 AscPCICmdRegBits_IOMemBusMaster));
11930 if ((DvcReadPCIConfigByte(asc_dvc,
11931 AscPCIConfigCommandRegister)
11932 & AscPCICmdRegBits_IOMemBusMaster)
11933 != AscPCICmdRegBits_IOMemBusMaster) {
11934 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
11937 if ((PCIDeviceID == PCI_DEVICE_ID_ASP_1200A) ||
11938 (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940)) {
11939 DvcWritePCIConfigByte(asc_dvc,
11940 AscPCIConfigLatencyTimer, 0x00);
11941 if (DvcReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer)
11942 != 0x00) {
11943 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
11945 } else if (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940U) {
11946 if (DvcReadPCIConfigByte(asc_dvc,
11947 AscPCIConfigLatencyTimer) < 0x20) {
11948 DvcWritePCIConfigByte(asc_dvc,
11949 AscPCIConfigLatencyTimer, 0x20);
11951 if (DvcReadPCIConfigByte(asc_dvc,
11952 AscPCIConfigLatencyTimer) < 0x20) {
11953 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
11959 if (AscFindSignature(iop_base)) {
11960 warn_code |= AscInitAscDvcVar(asc_dvc);
11961 warn_code |= AscInitFromEEP(asc_dvc);
11962 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
11963 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
11964 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
11966 } else {
11967 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11969 return(warn_code);
11972 STATIC ushort __init
11973 AscInitSetConfig(
11974 ASC_DVC_VAR *asc_dvc
11977 ushort warn_code = 0;
11979 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
11980 if (asc_dvc->err_code != 0)
11981 return (UW_ERR);
11982 if (AscFindSignature(asc_dvc->iop_base)) {
11983 warn_code |= AscInitFromAscDvcVar(asc_dvc);
11984 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
11985 } else {
11986 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11988 return (warn_code);
11991 STATIC ushort __init
11992 AscInitFromAscDvcVar(
11993 ASC_DVC_VAR *asc_dvc
11996 PortAddr iop_base;
11997 ushort cfg_msw;
11998 ushort warn_code;
11999 ushort pci_device_id = 0;
12001 iop_base = asc_dvc->iop_base;
12002 #ifdef CONFIG_PCI
12003 if (asc_dvc->cfg->dev)
12004 pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device;
12005 #endif
12006 warn_code = 0;
12007 cfg_msw = AscGetChipCfgMsw(iop_base);
12008 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12009 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
12010 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12011 AscSetChipCfgMsw(iop_base, cfg_msw);
12013 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
12014 asc_dvc->cfg->cmd_qng_enabled) {
12015 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
12016 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12018 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12019 warn_code |= ASC_WARN_AUTO_CONFIG;
12021 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
12022 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
12023 != asc_dvc->irq_no) {
12024 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
12027 if (asc_dvc->bus_type & ASC_IS_PCI) {
12028 cfg_msw &= 0xFFC0;
12029 AscSetChipCfgMsw(iop_base, cfg_msw);
12030 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
12031 } else {
12032 if ((pci_device_id == PCI_DEVICE_ID_ASP_1200A) ||
12033 (pci_device_id == PCI_DEVICE_ID_ASP_ABP940)) {
12034 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
12035 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
12038 } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
12039 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
12040 == ASC_CHIP_VER_ASYN_BUG) {
12041 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
12044 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
12045 asc_dvc->cfg->chip_scsi_id) {
12046 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
12048 #ifdef CONFIG_ISA
12049 if (asc_dvc->bus_type & ASC_IS_ISA) {
12050 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
12051 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
12053 #endif /* CONFIG_ISA */
12054 return (warn_code);
12057 STATIC ushort
12058 AscInitAsc1000Driver(
12059 ASC_DVC_VAR *asc_dvc
12062 ushort warn_code;
12063 PortAddr iop_base;
12065 iop_base = asc_dvc->iop_base;
12066 warn_code = 0;
12067 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
12068 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
12069 AscResetChipAndScsiBus(asc_dvc);
12070 DvcSleepMilliSecond((ASC_DCNT)
12071 ((ushort) asc_dvc->scsi_reset_wait * 1000));
12073 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
12074 if (asc_dvc->err_code != 0)
12075 return (UW_ERR);
12076 if (!AscFindSignature(asc_dvc->iop_base)) {
12077 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12078 return (warn_code);
12080 AscDisableInterrupt(iop_base);
12081 warn_code |= AscInitLram(asc_dvc);
12082 if (asc_dvc->err_code != 0)
12083 return (UW_ERR);
12084 ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
12085 (ulong) _asc_mcode_chksum);
12086 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
12087 _asc_mcode_size) != _asc_mcode_chksum) {
12088 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
12089 return (warn_code);
12091 warn_code |= AscInitMicroCodeVar(asc_dvc);
12092 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
12093 AscEnableInterrupt(iop_base);
12094 return (warn_code);
12097 STATIC ushort __init
12098 AscInitAscDvcVar(
12099 ASC_DVC_VAR *asc_dvc)
12101 int i;
12102 PortAddr iop_base;
12103 ushort warn_code;
12104 uchar chip_version;
12106 iop_base = asc_dvc->iop_base;
12107 warn_code = 0;
12108 asc_dvc->err_code = 0;
12109 if ((asc_dvc->bus_type &
12110 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
12111 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
12113 AscSetChipControl(iop_base, CC_HALT);
12114 AscSetChipStatus(iop_base, 0);
12115 asc_dvc->bug_fix_cntl = 0;
12116 asc_dvc->pci_fix_asyn_xfer = 0;
12117 asc_dvc->pci_fix_asyn_xfer_always = 0;
12118 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
12119 asc_dvc->sdtr_done = 0;
12120 asc_dvc->cur_total_qng = 0;
12121 asc_dvc->is_in_int = 0;
12122 asc_dvc->in_critical_cnt = 0;
12123 asc_dvc->last_q_shortage = 0;
12124 asc_dvc->use_tagged_qng = 0;
12125 asc_dvc->no_scam = 0;
12126 asc_dvc->unit_not_ready = 0;
12127 asc_dvc->queue_full_or_busy = 0;
12128 asc_dvc->redo_scam = 0;
12129 asc_dvc->res2 = 0;
12130 asc_dvc->host_init_sdtr_index = 0;
12131 asc_dvc->cfg->can_tagged_qng = 0;
12132 asc_dvc->cfg->cmd_qng_enabled = 0;
12133 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
12134 asc_dvc->init_sdtr = 0;
12135 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
12136 asc_dvc->scsi_reset_wait = 3;
12137 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
12138 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
12139 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
12140 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
12141 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
12142 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
12143 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
12144 ASC_LIB_VERSION_MINOR;
12145 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
12146 asc_dvc->cfg->chip_version = chip_version;
12147 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
12148 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
12149 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
12150 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
12151 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
12152 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
12153 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
12154 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
12155 asc_dvc->max_sdtr_index = 7;
12156 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
12157 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
12158 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
12159 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
12160 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
12161 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
12162 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
12163 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
12164 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
12165 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
12166 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
12167 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
12168 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
12169 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
12170 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
12171 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
12172 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
12173 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
12174 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
12175 asc_dvc->max_sdtr_index = 15;
12176 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150)
12178 AscSetExtraControl(iop_base,
12179 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
12180 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
12181 AscSetExtraControl(iop_base,
12182 (SEC_ACTIVE_NEGATE | SEC_ENABLE_FILTER));
12185 if (asc_dvc->bus_type == ASC_IS_PCI) {
12186 AscSetExtraControl(iop_base, (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
12189 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
12190 if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
12191 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
12192 asc_dvc->bus_type = ASC_IS_ISAPNP;
12194 #ifdef CONFIG_ISA
12195 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
12196 asc_dvc->cfg->isa_dma_channel = (uchar) AscGetIsaDmaChannel(iop_base);
12198 #endif /* CONFIG_ISA */
12199 for (i = 0; i <= ASC_MAX_TID; i++) {
12200 asc_dvc->cur_dvc_qng[i] = 0;
12201 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
12202 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *) 0L;
12203 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *) 0L;
12204 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
12206 return (warn_code);
12209 STATIC ushort __init
12210 AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
12212 ASCEEP_CONFIG eep_config_buf;
12213 ASCEEP_CONFIG *eep_config;
12214 PortAddr iop_base;
12215 ushort chksum;
12216 ushort warn_code;
12217 ushort cfg_msw, cfg_lsw;
12218 int i;
12219 int write_eep = 0;
12221 iop_base = asc_dvc->iop_base;
12222 warn_code = 0;
12223 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
12224 AscStopQueueExe(iop_base);
12225 if ((AscStopChip(iop_base) == FALSE) ||
12226 (AscGetChipScsiCtrl(iop_base) != 0)) {
12227 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
12228 AscResetChipAndScsiBus(asc_dvc);
12229 DvcSleepMilliSecond((ASC_DCNT)
12230 ((ushort) asc_dvc->scsi_reset_wait * 1000));
12232 if (AscIsChipHalted(iop_base) == FALSE) {
12233 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
12234 return (warn_code);
12236 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
12237 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
12238 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
12239 return (warn_code);
12241 eep_config = (ASCEEP_CONFIG *) &eep_config_buf;
12242 cfg_msw = AscGetChipCfgMsw(iop_base);
12243 cfg_lsw = AscGetChipCfgLsw(iop_base);
12244 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12245 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
12246 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12247 AscSetChipCfgMsw(iop_base, cfg_msw);
12249 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
12250 ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
12251 if (chksum == 0) {
12252 chksum = 0xaa55;
12254 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12255 warn_code |= ASC_WARN_AUTO_CONFIG;
12256 if (asc_dvc->cfg->chip_version == 3) {
12257 if (eep_config->cfg_lsw != cfg_lsw) {
12258 warn_code |= ASC_WARN_EEPROM_RECOVER;
12259 eep_config->cfg_lsw = AscGetChipCfgLsw(iop_base);
12261 if (eep_config->cfg_msw != cfg_msw) {
12262 warn_code |= ASC_WARN_EEPROM_RECOVER;
12263 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
12267 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
12268 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
12269 ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
12270 eep_config->chksum);
12271 if (chksum != eep_config->chksum) {
12272 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
12273 ASC_CHIP_VER_PCI_ULTRA_3050 )
12275 ASC_DBG(1,
12276 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
12277 eep_config->init_sdtr = 0xFF;
12278 eep_config->disc_enable = 0xFF;
12279 eep_config->start_motor = 0xFF;
12280 eep_config->use_cmd_qng = 0;
12281 eep_config->max_total_qng = 0xF0;
12282 eep_config->max_tag_qng = 0x20;
12283 eep_config->cntl = 0xBFFF;
12284 ASC_EEP_SET_CHIP_ID(eep_config, 7);
12285 eep_config->no_scam = 0;
12286 eep_config->adapter_info[0] = 0;
12287 eep_config->adapter_info[1] = 0;
12288 eep_config->adapter_info[2] = 0;
12289 eep_config->adapter_info[3] = 0;
12290 eep_config->adapter_info[4] = 0;
12291 /* Indicate EEPROM-less board. */
12292 eep_config->adapter_info[5] = 0xBB;
12293 } else {
12294 ASC_PRINT(
12295 "AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
12296 write_eep = 1;
12297 warn_code |= ASC_WARN_EEPROM_CHKSUM;
12300 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
12301 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
12302 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
12303 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
12304 asc_dvc->start_motor = eep_config->start_motor;
12305 asc_dvc->dvc_cntl = eep_config->cntl;
12306 asc_dvc->no_scam = eep_config->no_scam;
12307 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
12308 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
12309 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
12310 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
12311 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
12312 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
12313 if (!AscTestExternalLram(asc_dvc)) {
12314 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA)) {
12315 eep_config->max_total_qng = ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
12316 eep_config->max_tag_qng = ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
12317 } else {
12318 eep_config->cfg_msw |= 0x0800;
12319 cfg_msw |= 0x0800;
12320 AscSetChipCfgMsw(iop_base, cfg_msw);
12321 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
12322 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
12324 } else {
12326 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
12327 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
12329 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
12330 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
12332 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
12333 eep_config->max_tag_qng = eep_config->max_total_qng;
12335 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
12336 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
12338 asc_dvc->max_total_qng = eep_config->max_total_qng;
12339 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
12340 eep_config->use_cmd_qng) {
12341 eep_config->disc_enable = eep_config->use_cmd_qng;
12342 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12344 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
12345 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
12347 ASC_EEP_SET_CHIP_ID(eep_config, ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
12348 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
12349 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
12350 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
12351 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
12354 for (i = 0; i <= ASC_MAX_TID; i++) {
12355 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
12356 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
12357 asc_dvc->cfg->sdtr_period_offset[i] =
12358 (uchar) (ASC_DEF_SDTR_OFFSET |
12359 (asc_dvc->host_init_sdtr_index << 4));
12361 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
12362 if (write_eep) {
12363 if ((i = AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type)) !=
12364 0) {
12365 ASC_PRINT1(
12366 "AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n", i);
12367 } else {
12368 ASC_PRINT("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
12371 return (warn_code);
12374 STATIC ushort
12375 AscInitMicroCodeVar(
12376 ASC_DVC_VAR *asc_dvc
12379 int i;
12380 ushort warn_code;
12381 PortAddr iop_base;
12382 ASC_PADDR phy_addr;
12383 ASC_DCNT phy_size;
12385 iop_base = asc_dvc->iop_base;
12386 warn_code = 0;
12387 for (i = 0; i <= ASC_MAX_TID; i++) {
12388 AscPutMCodeInitSDTRAtID(iop_base, i,
12389 asc_dvc->cfg->sdtr_period_offset[i]
12393 AscInitQLinkVar(asc_dvc);
12394 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
12395 asc_dvc->cfg->disc_enable);
12396 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
12397 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
12399 /* Align overrun buffer on an 8 byte boundary. */
12400 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
12401 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
12402 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
12403 (uchar *) &phy_addr, 1);
12404 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
12405 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
12406 (uchar *) &phy_size, 1);
12408 asc_dvc->cfg->mcode_date =
12409 AscReadLramWord(iop_base, (ushort) ASCV_MC_DATE_W);
12410 asc_dvc->cfg->mcode_version =
12411 AscReadLramWord(iop_base, (ushort) ASCV_MC_VER_W);
12413 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
12414 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
12415 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
12416 return (warn_code);
12418 if (AscStartChip(iop_base) != 1) {
12419 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
12420 return (warn_code);
12423 return (warn_code);
12426 STATIC int __init
12427 AscTestExternalLram(
12428 ASC_DVC_VAR *asc_dvc)
12430 PortAddr iop_base;
12431 ushort q_addr;
12432 ushort saved_word;
12433 int sta;
12435 iop_base = asc_dvc->iop_base;
12436 sta = 0;
12437 q_addr = ASC_QNO_TO_QADDR(241);
12438 saved_word = AscReadLramWord(iop_base, q_addr);
12439 AscSetChipLramAddr(iop_base, q_addr);
12440 AscSetChipLramData(iop_base, 0x55AA);
12441 DvcSleepMilliSecond(10);
12442 AscSetChipLramAddr(iop_base, q_addr);
12443 if (AscGetChipLramData(iop_base) == 0x55AA) {
12444 sta = 1;
12445 AscWriteLramWord(iop_base, q_addr, saved_word);
12447 return (sta);
12450 STATIC int __init
12451 AscWriteEEPCmdReg(
12452 PortAddr iop_base,
12453 uchar cmd_reg
12456 uchar read_back;
12457 int retry;
12459 retry = 0;
12460 while (TRUE) {
12461 AscSetChipEEPCmd(iop_base, cmd_reg);
12462 DvcSleepMilliSecond(1);
12463 read_back = AscGetChipEEPCmd(iop_base);
12464 if (read_back == cmd_reg) {
12465 return (1);
12467 if (retry++ > ASC_EEP_MAX_RETRY) {
12468 return (0);
12473 STATIC int __init
12474 AscWriteEEPDataReg(
12475 PortAddr iop_base,
12476 ushort data_reg
12479 ushort read_back;
12480 int retry;
12482 retry = 0;
12483 while (TRUE) {
12484 AscSetChipEEPData(iop_base, data_reg);
12485 DvcSleepMilliSecond(1);
12486 read_back = AscGetChipEEPData(iop_base);
12487 if (read_back == data_reg) {
12488 return (1);
12490 if (retry++ > ASC_EEP_MAX_RETRY) {
12491 return (0);
12496 STATIC void __init
12497 AscWaitEEPRead(void)
12499 DvcSleepMilliSecond(1);
12500 return;
12503 STATIC void __init
12504 AscWaitEEPWrite(void)
12506 DvcSleepMilliSecond(20);
12507 return;
12510 STATIC ushort __init
12511 AscReadEEPWord(
12512 PortAddr iop_base,
12513 uchar addr)
12515 ushort read_wval;
12516 uchar cmd_reg;
12518 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
12519 AscWaitEEPRead();
12520 cmd_reg = addr | ASC_EEP_CMD_READ;
12521 AscWriteEEPCmdReg(iop_base, cmd_reg);
12522 AscWaitEEPRead();
12523 read_wval = AscGetChipEEPData(iop_base);
12524 AscWaitEEPRead();
12525 return (read_wval);
12528 STATIC ushort __init
12529 AscWriteEEPWord(
12530 PortAddr iop_base,
12531 uchar addr,
12532 ushort word_val)
12534 ushort read_wval;
12536 read_wval = AscReadEEPWord(iop_base, addr);
12537 if (read_wval != word_val) {
12538 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
12539 AscWaitEEPRead();
12540 AscWriteEEPDataReg(iop_base, word_val);
12541 AscWaitEEPRead();
12542 AscWriteEEPCmdReg(iop_base,
12543 (uchar) ((uchar) ASC_EEP_CMD_WRITE | addr));
12544 AscWaitEEPWrite();
12545 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
12546 AscWaitEEPRead();
12547 return (AscReadEEPWord(iop_base, addr));
12549 return (read_wval);
12552 STATIC ushort __init
12553 AscGetEEPConfig(
12554 PortAddr iop_base,
12555 ASCEEP_CONFIG * cfg_buf, ushort bus_type)
12557 ushort wval;
12558 ushort sum;
12559 ushort *wbuf;
12560 int cfg_beg;
12561 int cfg_end;
12562 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
12563 int s_addr;
12565 wbuf = (ushort *) cfg_buf;
12566 sum = 0;
12567 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
12568 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12569 *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
12570 sum += *wbuf;
12572 if (bus_type & ASC_IS_VL) {
12573 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
12574 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
12575 } else {
12576 cfg_beg = ASC_EEP_DVC_CFG_BEG;
12577 cfg_end = ASC_EEP_MAX_DVC_ADDR;
12579 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
12580 wval = AscReadEEPWord( iop_base, ( uchar )s_addr ) ;
12581 if (s_addr <= uchar_end_in_config) {
12583 * Swap all char fields - must unswap bytes already swapped
12584 * by AscReadEEPWord().
12586 *wbuf = le16_to_cpu(wval);
12587 } else {
12588 /* Don't swap word field at the end - cntl field. */
12589 *wbuf = wval;
12591 sum += wval; /* Checksum treats all EEPROM data as words. */
12594 * Read the checksum word which will be compared against 'sum'
12595 * by the caller. Word field already swapped.
12597 *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
12598 return (sum);
12601 STATIC int __init
12602 AscSetEEPConfigOnce(
12603 PortAddr iop_base,
12604 ASCEEP_CONFIG * cfg_buf, ushort bus_type)
12606 int n_error;
12607 ushort *wbuf;
12608 ushort word;
12609 ushort sum;
12610 int s_addr;
12611 int cfg_beg;
12612 int cfg_end;
12613 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
12616 wbuf = (ushort *) cfg_buf;
12617 n_error = 0;
12618 sum = 0;
12619 /* Write two config words; AscWriteEEPWord() will swap bytes. */
12620 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12621 sum += *wbuf;
12622 if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
12623 n_error++;
12626 if (bus_type & ASC_IS_VL) {
12627 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
12628 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
12629 } else {
12630 cfg_beg = ASC_EEP_DVC_CFG_BEG;
12631 cfg_end = ASC_EEP_MAX_DVC_ADDR;
12633 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
12634 if (s_addr <= uchar_end_in_config) {
12636 * This is a char field. Swap char fields before they are
12637 * swapped again by AscWriteEEPWord().
12639 word = cpu_to_le16(*wbuf);
12640 if (word != AscWriteEEPWord( iop_base, (uchar) s_addr, word)) {
12641 n_error++;
12643 } else {
12644 /* Don't swap word field at the end - cntl field. */
12645 if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
12646 n_error++;
12649 sum += *wbuf; /* Checksum calculated from word values. */
12651 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
12652 *wbuf = sum;
12653 if (sum != AscWriteEEPWord(iop_base, (uchar) s_addr, sum)) {
12654 n_error++;
12657 /* Read EEPROM back again. */
12658 wbuf = (ushort *) cfg_buf;
12660 * Read two config words; Byte-swapping done by AscReadEEPWord().
12662 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12663 if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
12664 n_error++;
12667 if (bus_type & ASC_IS_VL) {
12668 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
12669 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
12670 } else {
12671 cfg_beg = ASC_EEP_DVC_CFG_BEG;
12672 cfg_end = ASC_EEP_MAX_DVC_ADDR;
12674 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
12675 if (s_addr <= uchar_end_in_config) {
12677 * Swap all char fields. Must unswap bytes already swapped
12678 * by AscReadEEPWord().
12680 word = le16_to_cpu(AscReadEEPWord(iop_base, (uchar) s_addr));
12681 } else {
12682 /* Don't swap word field at the end - cntl field. */
12683 word = AscReadEEPWord(iop_base, (uchar) s_addr);
12685 if (*wbuf != word) {
12686 n_error++;
12689 /* Read checksum; Byte swapping not needed. */
12690 if (AscReadEEPWord(iop_base, (uchar) s_addr) != sum) {
12691 n_error++;
12693 return (n_error);
12696 STATIC int __init
12697 AscSetEEPConfig(
12698 PortAddr iop_base,
12699 ASCEEP_CONFIG * cfg_buf, ushort bus_type
12702 int retry;
12703 int n_error;
12705 retry = 0;
12706 while (TRUE) {
12707 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
12708 bus_type)) == 0) {
12709 break;
12711 if (++retry > ASC_EEP_MAX_RETRY) {
12712 break;
12715 return (n_error);
12718 STATIC void
12719 AscAsyncFix(
12720 ASC_DVC_VAR *asc_dvc,
12721 uchar tid_no,
12722 ASC_SCSI_INQUIRY *inq)
12724 uchar dvc_type;
12725 ASC_SCSI_BIT_ID_TYPE tid_bits;
12727 dvc_type = ASC_INQ_DVC_TYPE(inq);
12728 tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
12730 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN)
12732 if (!(asc_dvc->init_sdtr & tid_bits))
12734 if ((dvc_type == TYPE_ROM) &&
12735 (AscCompareString((uchar *) inq->vendor_id,
12736 (uchar *) "HP ", 3) == 0))
12738 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
12740 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
12741 if ((dvc_type == TYPE_PROCESSOR) ||
12742 (dvc_type == TYPE_SCANNER) ||
12743 (dvc_type == TYPE_ROM) ||
12744 (dvc_type == TYPE_TAPE))
12746 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
12749 if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
12751 AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no,
12752 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
12756 return;
12759 STATIC int
12760 AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
12762 if ((inq->add_len >= 32) &&
12763 (AscCompareString((uchar *) inq->vendor_id,
12764 (uchar *) "QUANTUM XP34301", 15) == 0) &&
12765 (AscCompareString((uchar *) inq->product_rev_level,
12766 (uchar *) "1071", 4) == 0))
12768 return 0;
12770 return 1;
12773 STATIC void
12774 AscInquiryHandling(ASC_DVC_VAR *asc_dvc,
12775 uchar tid_no, ASC_SCSI_INQUIRY *inq)
12777 ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
12778 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
12780 orig_init_sdtr = asc_dvc->init_sdtr;
12781 orig_use_tagged_qng = asc_dvc->use_tagged_qng;
12783 asc_dvc->init_sdtr &= ~tid_bit;
12784 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
12785 asc_dvc->use_tagged_qng &= ~tid_bit;
12787 if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) {
12788 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) {
12789 asc_dvc->init_sdtr |= tid_bit;
12791 if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) &&
12792 ASC_INQ_CMD_QUEUE(inq)) {
12793 if (AscTagQueuingSafe(inq)) {
12794 asc_dvc->use_tagged_qng |= tid_bit;
12795 asc_dvc->cfg->can_tagged_qng |= tid_bit;
12799 if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
12800 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
12801 asc_dvc->cfg->disc_enable);
12802 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
12803 asc_dvc->use_tagged_qng);
12804 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
12805 asc_dvc->cfg->can_tagged_qng);
12807 asc_dvc->max_dvc_qng[tid_no] =
12808 asc_dvc->cfg->max_tag_qng[tid_no];
12809 AscWriteLramByte(asc_dvc->iop_base,
12810 (ushort) (ASCV_MAX_DVC_QNG_BEG + tid_no),
12811 asc_dvc->max_dvc_qng[tid_no]);
12813 if (orig_init_sdtr != asc_dvc->init_sdtr) {
12814 AscAsyncFix(asc_dvc, tid_no, inq);
12816 return;
12819 STATIC int
12820 AscCompareString(
12821 uchar *str1,
12822 uchar *str2,
12823 int len
12826 int i;
12827 int diff;
12829 for (i = 0; i < len; i++) {
12830 diff = (int) (str1[i] - str2[i]);
12831 if (diff != 0)
12832 return (diff);
12834 return (0);
12837 STATIC uchar
12838 AscReadLramByte(
12839 PortAddr iop_base,
12840 ushort addr
12843 uchar byte_data;
12844 ushort word_data;
12846 if (isodd_word(addr)) {
12847 AscSetChipLramAddr(iop_base, addr - 1);
12848 word_data = AscGetChipLramData(iop_base);
12849 byte_data = (uchar) ((word_data >> 8) & 0xFF);
12850 } else {
12851 AscSetChipLramAddr(iop_base, addr);
12852 word_data = AscGetChipLramData(iop_base);
12853 byte_data = (uchar) (word_data & 0xFF);
12855 return (byte_data);
12857 STATIC ushort
12858 AscReadLramWord(
12859 PortAddr iop_base,
12860 ushort addr
12863 ushort word_data;
12865 AscSetChipLramAddr(iop_base, addr);
12866 word_data = AscGetChipLramData(iop_base);
12867 return (word_data);
12870 #if CC_VERY_LONG_SG_LIST
12871 STATIC ASC_DCNT
12872 AscReadLramDWord(
12873 PortAddr iop_base,
12874 ushort addr
12877 ushort val_low, val_high;
12878 ASC_DCNT dword_data;
12880 AscSetChipLramAddr(iop_base, addr);
12881 val_low = AscGetChipLramData(iop_base);
12882 val_high = AscGetChipLramData(iop_base);
12883 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
12884 return (dword_data);
12886 #endif /* CC_VERY_LONG_SG_LIST */
12888 STATIC void
12889 AscWriteLramWord(
12890 PortAddr iop_base,
12891 ushort addr,
12892 ushort word_val
12895 AscSetChipLramAddr(iop_base, addr);
12896 AscSetChipLramData(iop_base, word_val);
12897 return;
12900 STATIC void
12901 AscWriteLramByte(
12902 PortAddr iop_base,
12903 ushort addr,
12904 uchar byte_val
12907 ushort word_data;
12909 if (isodd_word(addr)) {
12910 addr--;
12911 word_data = AscReadLramWord(iop_base, addr);
12912 word_data &= 0x00FF;
12913 word_data |= (((ushort) byte_val << 8) & 0xFF00);
12914 } else {
12915 word_data = AscReadLramWord(iop_base, addr);
12916 word_data &= 0xFF00;
12917 word_data |= ((ushort) byte_val & 0x00FF);
12919 AscWriteLramWord(iop_base, addr, word_data);
12920 return;
12924 * Copy 2 bytes to LRAM.
12926 * The source data is assumed to be in little-endian order in memory
12927 * and is maintained in little-endian order when written to LRAM.
12929 STATIC void
12930 AscMemWordCopyPtrToLram(
12931 PortAddr iop_base,
12932 ushort s_addr,
12933 uchar *s_buffer,
12934 int words
12937 int i;
12939 AscSetChipLramAddr(iop_base, s_addr);
12940 for (i = 0; i < 2 * words; i += 2) {
12942 * On a little-endian system the second argument below
12943 * produces a little-endian ushort which is written to
12944 * LRAM in little-endian order. On a big-endian system
12945 * the second argument produces a big-endian ushort which
12946 * is "transparently" byte-swapped by outpw() and written
12947 * in little-endian order to LRAM.
12949 outpw(iop_base + IOP_RAM_DATA,
12950 ((ushort) s_buffer[i + 1] << 8) | s_buffer[i]);
12952 return;
12956 * Copy 4 bytes to LRAM.
12958 * The source data is assumed to be in little-endian order in memory
12959 * and is maintained in little-endian order when writen to LRAM.
12961 STATIC void
12962 AscMemDWordCopyPtrToLram(
12963 PortAddr iop_base,
12964 ushort s_addr,
12965 uchar *s_buffer,
12966 int dwords
12969 int i;
12971 AscSetChipLramAddr(iop_base, s_addr);
12972 for (i = 0; i < 4 * dwords; i += 4) {
12973 outpw(iop_base + IOP_RAM_DATA,
12974 ((ushort) s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
12975 outpw(iop_base + IOP_RAM_DATA,
12976 ((ushort) s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
12978 return;
12982 * Copy 2 bytes from LRAM.
12984 * The source data is assumed to be in little-endian order in LRAM
12985 * and is maintained in little-endian order when written to memory.
12987 STATIC void
12988 AscMemWordCopyPtrFromLram(
12989 PortAddr iop_base,
12990 ushort s_addr,
12991 uchar *d_buffer,
12992 int words
12995 int i;
12996 ushort word;
12998 AscSetChipLramAddr(iop_base, s_addr);
12999 for (i = 0; i < 2 * words; i += 2) {
13000 word = inpw(iop_base + IOP_RAM_DATA);
13001 d_buffer[i] = word & 0xff;
13002 d_buffer[i + 1] = (word >> 8) & 0xff;
13004 return;
13007 STATIC ASC_DCNT
13008 AscMemSumLramWord(
13009 PortAddr iop_base,
13010 ushort s_addr,
13011 int words
13014 ASC_DCNT sum;
13015 int i;
13017 sum = 0L;
13018 for (i = 0; i < words; i++, s_addr += 2) {
13019 sum += AscReadLramWord(iop_base, s_addr);
13021 return (sum);
13024 STATIC void
13025 AscMemWordSetLram(
13026 PortAddr iop_base,
13027 ushort s_addr,
13028 ushort set_wval,
13029 int words
13032 int i;
13034 AscSetChipLramAddr(iop_base, s_addr);
13035 for (i = 0; i < words; i++) {
13036 AscSetChipLramData(iop_base, set_wval);
13038 return;
13043 * --- Adv Library Functions
13046 /* a_mcode.h */
13048 /* Microcode buffer is kept after initialization for error recovery. */
13049 STATIC unsigned char _adv_asc3550_buf[] = {
13050 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc, 0x01, 0x00, 0x48, 0xe4,
13051 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7,
13052 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6,
13053 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00, 0x00, 0xec, 0x85, 0xf0,
13054 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00,
13055 0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80,
13056 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea,
13057 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00,
13058 0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54,
13059 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00, 0x3e, 0x00, 0x80, 0x00,
13060 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01,
13061 0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55,
13062 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
13063 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15,
13064 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0,
13065 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01,
13066 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c,
13067 0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0,
13068 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00,
13069 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10,
13070 0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15,
13071 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45,
13072 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6,
13073 0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa,
13074 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00, 0x9e, 0x00, 0xa8, 0x00,
13075 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01,
13076 0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08,
13077 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x06, 0x12,
13078 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17,
13079 0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47,
13080 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55, 0x14, 0x56, 0x77, 0x57,
13081 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe,
13082 0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff,
13083 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, 0x00, 0xfe, 0x57, 0x24,
13084 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08,
13085 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f,
13086 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xcf,
13087 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe,
13088 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe,
13089 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b, 0x02, 0xfe, 0xd4, 0x0c,
13090 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6,
13091 0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02,
13092 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02, 0xfe, 0x46, 0xf0, 0xfe,
13093 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44,
13094 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18,
13095 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9,
13096 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e,
13097 0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd,
13098 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, 0x1c, 0x17, 0x06,
13099 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe,
13100 0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f,
13101 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe, 0x69, 0x10, 0x17, 0x06,
13102 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe,
13103 0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40,
13104 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0x99, 0x01,
13105 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02,
13106 0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b,
13107 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0, 0xfe, 0x56, 0x03, 0xfe,
13108 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe,
13109 0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04,
13110 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40, 0x01, 0x0e, 0xac, 0x75,
13111 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe,
13112 0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4,
13113 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe, 0x0a, 0xf0, 0xfe, 0x7a,
13114 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe,
13115 0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c,
13116 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3, 0x0a, 0xca, 0x01, 0x0e,
13117 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f,
13118 0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f,
13119 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2b, 0xff, 0x02,
13120 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5,
13121 0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
13122 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d, 0xfe, 0x2a, 0x13, 0x2f,
13123 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86,
13124 0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12,
13125 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22,
13126 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29,
13127 0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4,
13128 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a, 0xfe, 0x70, 0x12, 0x49,
13129 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31,
13130 0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12,
13131 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05, 0x11, 0xfe, 0xe3, 0x00,
13132 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24,
13133 0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08,
13134 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01, 0x86, 0x24, 0x06, 0x12,
13135 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92,
13136 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe,
13137 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13, 0x47, 0x01, 0xa7, 0x26,
13138 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14,
13139 0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c,
13140 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x14,
13141 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57,
13142 0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04,
13143 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68, 0x06, 0x11, 0x9a, 0x01,
13144 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72,
13145 0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe,
13146 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07, 0x8d, 0x81, 0x02, 0x22,
13147 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00,
13148 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32,
13149 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15, 0xfe, 0x1b, 0x00, 0x01,
13150 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01,
13151 0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d,
13152 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12,
13153 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d,
13154 0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02,
13155 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x77, 0xfe, 0xca,
13156 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12,
13157 0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1,
13158 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f, 0x40, 0x12, 0x58, 0x01,
13159 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe,
13160 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe,
13161 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a, 0xfe, 0x2a, 0x12, 0xfe,
13162 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe,
13163 0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe,
13164 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x39, 0x18, 0x3a,
13165 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48,
13166 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80,
13167 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x7a, 0x08, 0x8d,
13168 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06,
13169 0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c,
13170 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe, 0x52, 0x12, 0xfe, 0x2c,
13171 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10,
13172 0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe,
13173 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xb5, 0xfe,
13174 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d,
13175 0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33,
13176 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a, 0xfe, 0x74, 0x18, 0x1c,
13177 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27,
13178 0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe,
13179 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc, 0xfe, 0x83, 0x80, 0xfe,
13180 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59,
13181 0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf,
13182 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e, 0x79, 0x56, 0x68, 0x57,
13183 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b,
13184 0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39,
13185 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x10, 0x58, 0xfe,
13186 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09,
13187 0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe,
13188 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08, 0x11, 0x9b, 0x09, 0x04,
13189 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe,
13190 0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12,
13191 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9, 0x14, 0x7a, 0x01, 0x33,
13192 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf,
13193 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10,
13194 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x84, 0x05, 0xcb, 0x1c,
13195 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a,
13196 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca,
13197 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe, 0x22, 0x00, 0x02, 0x5a,
13198 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe,
13199 0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10,
13200 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00, 0x2a, 0x13, 0xfe, 0x4e,
13201 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73,
13202 0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48,
13203 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xdb, 0x10, 0x11, 0xfe,
13204 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8,
13205 0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42,
13206 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c, 0x09, 0x04, 0x0b, 0xfe,
13207 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6,
13208 0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01,
13209 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x02, 0x29,
13210 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b,
13211 0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe,
13212 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01, 0xe8, 0x59, 0x11, 0x2d,
13213 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e,
13214 0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe,
13215 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d,
13216 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe,
13217 0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00,
13218 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa, 0xab, 0x70, 0x05, 0x6b,
13219 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01,
13220 0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01,
13221 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e, 0x1d, 0xfe, 0xce, 0x45,
13222 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe,
13223 0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d,
13224 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe,
13225 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee,
13226 0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e,
13227 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12, 0xce, 0x1e, 0x2d, 0x47,
13228 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe,
13229 0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02,
13230 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
13231 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea,
13232 0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01,
13233 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01,
13234 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e,
13235 0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24,
13236 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57,
13237 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe,
13238 0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04,
13239 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xe1,
13240 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c,
13241 0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d,
13242 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01, 0xe8, 0x11, 0xfe, 0xe9,
13243 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14,
13244 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe,
13245 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80, 0x40, 0x12, 0x20, 0x63,
13246 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac,
13247 0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe,
13248 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x24, 0x69, 0x12, 0xc9,
13249 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91,
13250 0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe,
13251 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c, 0x46, 0x1e, 0x20, 0xed,
13252 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c,
13253 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d,
13254 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46, 0xfa, 0xef, 0xfe, 0x42,
13255 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0,
13256 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10,
13257 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e, 0x10, 0x07, 0x7e, 0x45,
13258 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97,
13259 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe,
13260 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b, 0xfe, 0x48, 0x12, 0x07,
13261 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07,
13262 0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe,
13263 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b, 0x01, 0x08, 0x8c, 0x43,
13264 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b,
13265 0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04,
13266 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe, 0xc6, 0x10, 0x1e, 0x58,
13267 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23,
13268 0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1,
13269 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0xfe,
13270 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57,
13271 0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
13272 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e, 0x58, 0xfe, 0x1f, 0x40,
13273 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44,
13274 0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39,
13275 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06, 0x12, 0xcd, 0x02, 0x5b,
13276 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21,
13277 0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe,
13278 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51,
13279 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32,
13280 0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01,
13281 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44, 0x01, 0x08, 0x1f, 0xa2,
13282 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49,
13283 0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda,
13284 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1, 0x05, 0xc6, 0x28, 0x84,
13285 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
13286 0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02,
13287 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06, 0x21, 0x44, 0x01, 0xfe,
13288 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b,
13289 0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05,
13290 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xd8, 0x14, 0x02, 0x5c,
13291 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72,
13292 0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01,
13293 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0xfe, 0xff, 0x7f,
13294 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c,
13295 0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
13296 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58, 0x03, 0x0a, 0x50, 0x01,
13297 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4,
13298 0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27,
13299 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe,
13300 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60,
13301 0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14,
13302 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe, 0xcc, 0x12, 0x49, 0x04,
13303 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13,
13304 0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83,
13305 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c, 0x13, 0x06, 0xfe, 0x56,
13306 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93,
13307 0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4,
13308 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90, 0x01, 0xba, 0xfe, 0x4e,
13309 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe,
13310 0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c,
13311 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba, 0xfe, 0x9c, 0x14, 0xb7,
13312 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7,
13313 0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe,
13314 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x0b, 0x01,
13315 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03,
13316 0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08,
13317 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89, 0x4a, 0x01, 0x08, 0x03,
13318 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00,
13319 0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe,
13320 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd, 0x01, 0x43, 0x1e, 0xcd,
13321 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10,
13322 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88,
13323 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3, 0x88, 0x03, 0x0a, 0x42,
13324 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2,
13325 0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17,
13326 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe,
13327 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe,
13328 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10,
13329 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58, 0x05, 0xfe, 0x66, 0x01,
13330 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66,
13331 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6,
13332 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17, 0x10, 0x71, 0xfe, 0x83,
13333 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe,
13334 0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
13335 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71, 0xfe, 0x30, 0xbc, 0xfe,
13336 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a,
13337 0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02,
13338 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc, 0xfe, 0x1d, 0xf7, 0x4f,
13339 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58,
13340 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63,
13341 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14, 0x06, 0x37, 0x95, 0xa9,
13342 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d,
13343 0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c,
13344 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x3c, 0x8a, 0x0a,
13345 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc,
13346 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f,
13347 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xf6, 0xfe, 0xd6, 0xf0,
13348 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76,
13349 0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f,
13350 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68, 0xc8, 0xfe, 0x48, 0x55,
13351 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0,
13352 0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42,
13353 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01, 0x0e, 0x73, 0x75, 0x03,
13354 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b,
13355 0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b,
13356 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05, 0xfe, 0x94, 0x00, 0xfe,
13357 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e,
13358 0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe,
13359 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1b, 0xfe, 0x5a,
13360 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07,
13361 0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14,
13362 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9, 0x03, 0x25, 0xfe, 0xca,
13363 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00,
13366 STATIC unsigned short _adv_asc3550_size =
13367 sizeof(_adv_asc3550_buf); /* 0x13AD */
13368 STATIC ADV_DCNT _adv_asc3550_chksum =
13369 0x04D52DDDUL; /* Expanded little-endian checksum. */
13371 /* Microcode buffer is kept after initialization for error recovery. */
13372 STATIC unsigned char _adv_asc38C0800_buf[] = {
13373 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4, 0x01, 0x00, 0x48, 0xe4,
13374 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6,
13375 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0,
13376 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0, 0x18, 0xf4, 0x08, 0x00,
13377 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0,
13378 0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00,
13379 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13, 0xba, 0x13, 0x18, 0x40,
13380 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01,
13381 0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
13382 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12, 0x08, 0x12, 0x02, 0x4a,
13383 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa,
13384 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
13385 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d, 0x06, 0x13, 0x4c, 0x1c,
13386 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00,
13387 0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44,
13388 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa, 0x05, 0x00, 0x34, 0x00,
13389 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f,
13390 0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54,
13391 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0,
13392 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00,
13393 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03,
13394 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13, 0x12, 0x13, 0x24, 0x14,
13395 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44,
13396 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55,
13397 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0, 0x04, 0xf8,
13398 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00,
13399 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01,
13400 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08, 0x68, 0x08, 0x69, 0x08,
13401 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10,
13402 0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14,
13403 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18, 0xca, 0x18, 0xe6, 0x19,
13404 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe,
13405 0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff,
13406 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, 0x00, 0xfe, 0x57, 0x24,
13407 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08,
13408 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11,
13409 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xd6,
13410 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe,
13411 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe,
13412 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d, 0x02, 0xfe, 0xc8, 0x0d,
13413 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6,
13414 0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02,
13415 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02, 0xfe, 0x46, 0xf0, 0xfe,
13416 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44,
13417 0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14,
13418 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9,
13419 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8,
13420 0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd,
13421 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, 0x1c, 0x18, 0x06,
13422 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe,
13423 0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10,
13424 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe, 0x69, 0x10, 0x18, 0x06,
13425 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe,
13426 0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
13427 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x09,
13428 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
13429 0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe,
13430 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x40, 0x1c, 0x1c,
13431 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0,
13432 0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02,
13433 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13, 0x21, 0x22, 0xa3, 0xb7,
13434 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9,
13435 0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27,
13436 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe, 0x06, 0xf0, 0xfe, 0xc8,
13437 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe,
13438 0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19,
13439 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x74, 0x01, 0xaf, 0x8c,
13440 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79,
13441 0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02,
13442 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d, 0xfe, 0x3c, 0x04, 0x3b,
13443 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b,
13444 0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe,
13445 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0x4f, 0x79, 0x2a,
13446 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32,
13447 0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe,
13448 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x08, 0x13, 0x32, 0x07,
13449 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d,
13450 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6,
13451 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36, 0x02, 0x2b, 0xfe, 0x42,
13452 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe,
13453 0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c,
13454 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28, 0x17, 0xfe, 0x90, 0x05,
13455 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe,
13456 0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48,
13457 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0x12, 0xfe, 0xe3, 0x00,
13458 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25,
13459 0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02,
13460 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2, 0x08, 0x53, 0x05, 0xcb,
13461 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22,
13462 0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36,
13463 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb, 0x03, 0x5c, 0x28, 0xfe,
13464 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02,
13465 0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe,
13466 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62, 0x12, 0x03, 0x45, 0x28,
13467 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc,
13468 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2,
13469 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01, 0xfe, 0xcc, 0x15, 0x1d,
13470 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45,
13471 0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb,
13472 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07, 0xfe, 0x06, 0xf0, 0xfe,
13473 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b,
13474 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01,
13475 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38, 0x12, 0x08, 0x05, 0x1a,
13476 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
13477 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe,
13478 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b, 0xfe, 0x09, 0x6f, 0xba,
13479 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c,
13480 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01,
13481 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
13482 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07,
13483 0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe,
13484 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b, 0x37, 0x01, 0xb3, 0xb8,
13485 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51,
13486 0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c,
13487 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d, 0x14, 0x3e, 0xfe, 0x4a,
13488 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14,
13489 0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe,
13490 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f,
13491 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c,
13492 0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e,
13493 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe, 0x9a, 0x08, 0xc6, 0xfe,
13494 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24,
13495 0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12,
13496 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e, 0x1c, 0x02, 0xfe, 0x18,
13497 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa,
13498 0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7,
13499 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18, 0xfe, 0xf1, 0x18, 0xfe,
13500 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95,
13501 0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5,
13502 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18, 0x0b, 0xb6, 0xfe, 0xbf,
13503 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2,
13504 0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5,
13505 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15, 0x9d, 0x01, 0x36, 0x10,
13506 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19,
13507 0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe,
13508 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0x08, 0x05,
13509 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c,
13510 0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49,
13511 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18, 0x8f, 0xfe, 0xe3, 0x54,
13512 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b,
13513 0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b,
13514 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00, 0xad, 0xfe, 0x01, 0x59,
13515 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3,
13516 0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b,
13517 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63, 0x02, 0x4a, 0x08, 0x05,
13518 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1,
13519 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a,
13520 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29, 0x61, 0x0c, 0x7f, 0x14,
13521 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c,
13522 0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef,
13523 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40, 0xe4, 0x08, 0x05, 0x1f,
13524 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f,
13525 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05,
13526 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19, 0x81, 0x50, 0xfe, 0x10,
13527 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6,
13528 0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c,
13529 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7, 0x08, 0x05, 0x0a, 0xfe,
13530 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e,
13531 0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed,
13532 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe, 0x00, 0xff, 0x35, 0xfe,
13533 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03,
13534 0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe,
13535 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0,
13536 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00,
13537 0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0,
13538 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea, 0x0b, 0x10, 0x58, 0xfe,
13539 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f,
13540 0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34,
13541 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20, 0x0c, 0x1c, 0x34, 0x94,
13542 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10,
13543 0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33,
13544 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24, 0x33, 0x31, 0xdf, 0xbc,
13545 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d,
13546 0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28,
13547 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x44, 0xfe, 0x28, 0x00,
13548 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f,
13549 0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10,
13550 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xac,
13551 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01,
13552 0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08,
13553 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05, 0x1a, 0xfe, 0x58, 0x12,
13554 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe,
13555 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10,
13556 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10, 0xfe, 0x13, 0x00, 0xfe,
13557 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5,
13558 0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe,
13559 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0, 0xb4, 0x15, 0xfe, 0x31,
13560 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44,
13561 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75,
13562 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x44, 0x48,
13563 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09,
13564 0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d,
13565 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0xce, 0x47, 0xfe, 0xad,
13566 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13,
13567 0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06,
13568 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe, 0x3a, 0x01, 0x56, 0xfe,
13569 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05,
13570 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe,
13571 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13, 0x15, 0x1a, 0x39, 0xa0,
13572 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01,
13573 0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12,
13574 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12, 0x22, 0x9f, 0xb7, 0x13,
13575 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9,
13576 0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc,
13577 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21, 0xfe, 0x00, 0xcc, 0x04,
13578 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07,
13579 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe,
13580 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x0a, 0xfe, 0x3c, 0x50,
13581 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b,
13582 0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01,
13583 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01,
13584 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01,
13585 0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79,
13586 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00,
13588 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09,
13589 0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52,
13590 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc, 0x0f, 0x44, 0x11, 0x0f,
13591 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20,
13592 0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
13593 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x04, 0x42,
13594 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01,
13595 0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f,
13596 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45,
13597 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09,
13598 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14,
13599 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d, 0xfe, 0x01, 0xec, 0xa2,
13600 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe,
13601 0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07,
13602 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17, 0xfe, 0x32, 0x12, 0x07,
13603 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12,
13604 0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d,
13605 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d, 0x32, 0x07, 0xa6, 0xfe,
13606 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12,
13607 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03,
13608 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21, 0x0c, 0x7f, 0x0c, 0x80,
13609 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55,
13610 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f,
13611 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40, 0x88, 0x9b, 0x2e, 0x9c,
13612 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14,
13613 0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61,
13614 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50,
13615 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40,
13616 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d,
13617 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23, 0x72, 0x01, 0xaf, 0x1e,
13618 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe,
13619 0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19,
13620 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31,
13621 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d,
13622 0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8,
13623 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53, 0x05, 0x1f, 0x35, 0xa9,
13624 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c,
13625 0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35,
13626 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x03, 0x5c, 0xc1, 0x0c,
13627 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c,
13628 0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1,
13629 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a, 0xf4, 0x06, 0xea, 0x32,
13630 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89,
13631 0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13,
13632 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0, 0x13, 0x1c, 0xfe, 0xd0,
13633 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02,
13634 0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f,
13635 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04,
13636 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52,
13637 0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03,
13638 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52, 0xfe, 0x00, 0x7d, 0xfe,
13639 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f,
13640 0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01,
13641 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33,
13642 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59,
13643 0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee,
13644 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c, 0x30, 0xfe, 0x78, 0x10,
13645 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00,
13646 0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00,
13647 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28, 0x10, 0x69, 0x06, 0xfe,
13648 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06,
13649 0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe,
13650 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4, 0x9e, 0xfe, 0xf3, 0x10,
13651 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
13652 0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
13653 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d, 0xf4, 0x00, 0xe9, 0x91,
13654 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01,
13655 0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76,
13656 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x19, 0x01, 0x0b,
13657 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76,
13658 0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8,
13659 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01,
13660 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00,
13661 0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06,
13662 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e, 0x07, 0x11, 0xae, 0x09,
13663 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80,
13664 0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e,
13665 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x4c,
13666 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87,
13667 0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24,
13668 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4, 0x17, 0xad, 0x9a, 0x1b,
13669 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10,
13670 0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe,
13671 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c,
13672 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17,
13673 0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75,
13674 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x2e, 0x97, 0xfe, 0x5a,
13675 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
13676 0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe,
13677 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0xcb, 0x97, 0xfe, 0x92,
13678 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02,
13679 0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d,
13680 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x9a, 0x5b, 0x41, 0xfe,
13681 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd,
13682 0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39,
13683 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04, 0xfe, 0x7e, 0x18, 0x1e,
13684 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10,
13685 0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09,
13686 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc,
13687 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c,
13688 0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14,
13689 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c, 0xe7, 0x0a, 0x10, 0xfe,
13690 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37,
13691 0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b,
13692 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77, 0x13, 0xa3, 0x04, 0x09,
13693 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8,
13694 0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09,
13695 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe, 0x1c, 0x19, 0x03, 0xfe,
13696 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19,
13697 0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b,
13698 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe, 0x08, 0x10, 0x03, 0xfe,
13699 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7,
13700 0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00,
13701 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19, 0x04, 0x07, 0x7e, 0xfe,
13702 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a,
13703 0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07,
13704 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59, 0xa9, 0xb8, 0x04, 0x15,
13705 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c,
13706 0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0,
13707 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
13710 STATIC unsigned short _adv_asc38C0800_size =
13711 sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
13712 STATIC ADV_DCNT _adv_asc38C0800_chksum =
13713 0x050D3FD8UL; /* Expanded little-endian checksum. */
13715 /* Microcode buffer is kept after initialization for error recovery. */
13716 STATIC unsigned char _adv_asc38C1600_buf[] = {
13717 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0, 0x18, 0xe4, 0x01, 0x00,
13718 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f,
13719 0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0,
13720 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00, 0x98, 0x57, 0x01, 0xe6,
13721 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0,
13722 0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0,
13723 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01, 0x06, 0x13, 0x0c, 0x1c,
13724 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80,
13725 0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea,
13726 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x04, 0x13, 0xbb, 0x55,
13727 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00,
13728 0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c,
13729 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01,
13730 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01,
13731 0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48,
13732 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x06, 0x00,
13733 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c,
13734 0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0,
13735 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00,
13736 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09,
13737 0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16,
13738 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
13739 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00,
13740 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c,
13741 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x42, 0x1d, 0x08, 0x44,
13742 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59,
13743 0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8,
13744 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0xa8, 0x00, 0xaa, 0x00,
13745 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01,
13746 0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d,
13747 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10, 0xf3, 0x10, 0x06, 0x12,
13748 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe,
13749 0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff,
13750 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, 0x00, 0xfe, 0x57, 0x24,
13751 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08,
13752 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13,
13753 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xe8,
13754 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe,
13755 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe,
13756 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d, 0x05, 0xfe, 0x08, 0x0f,
13757 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe,
13758 0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90,
13759 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8, 0x02, 0xfe, 0x46, 0xf0,
13760 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe,
13761 0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07,
13762 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02, 0x1c, 0xf5, 0xfe, 0x1e,
13763 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01,
13764 0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe,
13765 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, 0x1c, 0x1c,
13766 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02,
13767 0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01,
13768 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09, 0x1a, 0x31, 0xfe, 0x69,
13769 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c,
13770 0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51,
13771 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00,
13772 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54,
13773 0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30,
13774 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0, 0xfe, 0xe4, 0x01, 0xfe,
13775 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66,
13776 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f,
13777 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05, 0x70, 0x37, 0xfe, 0x48,
13778 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20,
13779 0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe,
13780 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32, 0x15, 0xfe, 0xe4, 0x00,
13781 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe,
13782 0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b,
13783 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xfe, 0x46, 0x1c,
13784 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75,
13785 0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77,
13786 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02,
13787 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04,
13788 0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01,
13789 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25, 0xee, 0xfe, 0x4c, 0x44,
13790 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d,
13791 0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe,
13792 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10, 0x13, 0x34, 0xfe, 0x4c,
13793 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06,
13794 0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f,
13795 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f, 0xfe, 0xa4, 0x0e, 0x05,
13796 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b,
13797 0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46,
13798 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04, 0xfe, 0x87, 0x83, 0xfe,
13799 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20,
13800 0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06,
13801 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda, 0x05, 0xd0, 0x54, 0x01,
13802 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff,
13803 0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe,
13804 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01, 0x38, 0xfe, 0x4a, 0xf0,
13805 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e,
13806 0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0,
13807 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe, 0x1c, 0x00, 0x4d, 0x01,
13808 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12,
13809 0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42,
13810 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13, 0x03, 0xb6, 0x1e, 0xfe,
13811 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a,
13812 0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68,
13813 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x03, 0x9a, 0x1e, 0xfe,
13814 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06,
13815 0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00,
13816 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17, 0xfe, 0xea, 0x06, 0x01,
13817 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15,
13818 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae,
13819 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a, 0x1e, 0xfe, 0x1a, 0x12,
13820 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80,
13821 0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6,
13822 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x17, 0xfe,
13823 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01,
13824 0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05,
13825 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0x9c, 0x32, 0x5f,
13826 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe,
13827 0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29,
13828 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14,
13829 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe,
13830 0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13,
13831 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
13832 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe,
13833 0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c,
13834 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x53, 0x63, 0x4e,
13835 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0,
13836 0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c,
13837 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe, 0x1e, 0xfe, 0x99, 0x58,
13838 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c,
13839 0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a,
13840 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40, 0x01, 0x0c, 0x61, 0x65,
13841 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50,
13842 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e,
13843 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e, 0x01, 0xfe, 0xfe, 0x1e,
13844 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06,
13845 0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b,
13846 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04, 0xfe, 0x9f, 0x83, 0x33,
13847 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6,
13848 0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e,
13849 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90, 0x04, 0xfe, 0xc0, 0x93,
13850 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c,
13851 0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
13852 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
13853 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a,
13854 0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41,
13855 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07, 0xfe, 0x14, 0x12, 0x01,
13856 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe,
13857 0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe,
13858 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe, 0x92, 0x10, 0xc4, 0xf6,
13859 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b,
13860 0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0,
13861 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07, 0x1b, 0xbf, 0xd4, 0x5b,
13862 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f,
13863 0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74,
13864 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78, 0x0f, 0x4d, 0x01, 0xfe,
13865 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2,
13866 0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21,
13867 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe, 0x83, 0x83, 0xfe, 0xc9,
13868 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84,
13869 0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b,
13870 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0x10,
13871 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64,
13872 0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64,
13873 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97, 0x10, 0x98, 0x91, 0x6c,
13874 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01,
13875 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58,
13876 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x01, 0x0c,
13877 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04,
13878 0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe,
13879 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb, 0x01, 0x0c, 0x06, 0x0d,
13880 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d,
13881 0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e,
13882 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41,
13883 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00,
13884 0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51,
13885 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe, 0x76, 0x10, 0xac, 0xfe,
13886 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe,
13887 0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92,
13888 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2, 0x0c, 0xfe, 0x3e, 0x10,
13889 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe,
13890 0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94,
13891 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3, 0xfe, 0xcc, 0xf0, 0xef,
13892 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
13893 0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
13894 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32, 0x2f, 0xfe, 0x3e, 0x0d,
13895 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f,
13896 0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99,
13897 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8, 0x9c, 0x2f, 0xfe, 0x8c,
13898 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70,
13899 0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13,
13900 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b, 0xfe, 0xda, 0x0e, 0x0a,
13901 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4,
13902 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85,
13903 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe, 0xcc, 0x10, 0x01, 0xa7,
13904 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe,
13905 0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2,
13906 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x40, 0x15,
13907 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01,
13908 0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe,
13909 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe,
13910 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44,
13911 0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19,
13912 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19, 0xfe, 0x41, 0x00, 0xa2,
13913 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04,
13914 0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c,
13915 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01, 0xfe, 0xd4, 0x11, 0x05,
13916 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51,
13917 0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56,
13918 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01, 0x0c, 0x06, 0x28, 0xfe,
13919 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe,
13920 0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe,
13921 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x05,
13922 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c,
13923 0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b,
13924 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe, 0xf0, 0x1a, 0x03, 0xfe,
13925 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00,
13926 0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b,
13927 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02, 0xea, 0xe7, 0x53, 0x92,
13928 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23,
13929 0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e,
13930 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02, 0x26, 0x02, 0x21, 0x96,
13931 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10,
13932 0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe,
13933 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe, 0x00, 0xcc, 0x02, 0xfe,
13934 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80,
13935 0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80,
13936 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe, 0x1d, 0x80, 0x04, 0xfe,
13937 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14,
13938 0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4,
13939 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09, 0x56, 0xfb, 0x01, 0xfe,
13940 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15,
13941 0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e,
13942 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe, 0x96, 0x90, 0x04, 0xfe,
13943 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06,
13944 0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01,
13945 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40, 0x21, 0x2c, 0xfe, 0x00,
13946 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe,
13947 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00,
13948 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10, 0x66, 0x10, 0x55, 0x10,
13949 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88,
13950 0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe,
13951 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c,
13952 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe,
13953 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47,
13954 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01, 0xa7, 0x90, 0x34, 0x60,
13955 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34,
13956 0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
13957 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a,
13958 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe,
13959 0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e,
13960 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01, 0xf4, 0xfe, 0xdd, 0x10,
13961 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe,
13962 0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23,
13963 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09, 0x24, 0xfe, 0x12, 0x12,
13964 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32,
13965 0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43,
13966 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80, 0x13, 0x01, 0x0c, 0x06,
13967 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe,
13968 0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10,
13969 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49, 0x88, 0x20, 0x6e, 0x01,
13970 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa,
13971 0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe,
13972 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe, 0xe5,
13973 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01,
13974 0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50,
13975 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50, 0x03, 0x68, 0x3b,
13976 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2,
13977 0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25,
13978 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01, 0xa6, 0x23, 0x3f, 0x1b,
13979 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31,
13980 0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01,
13981 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0,
13982 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05,
13983 0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08,
13984 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03, 0xb6, 0x1e, 0x83, 0x01,
13985 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01,
13986 0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82,
13987 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e, 0x05, 0x72, 0xfe, 0xc0,
13988 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17,
13989 0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd,
13990 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe, 0xe8, 0x14, 0x01, 0xa6,
13991 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43,
13992 0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73,
13993 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd, 0x09,
13994 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8,
13995 0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72,
13996 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0xc0, 0x19, 0x05,
13997 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26,
13998 0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32,
13999 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0xfe, 0xff,
14000 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad,
14001 0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
14002 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e, 0x02, 0x13, 0x58, 0xff,
14003 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01,
14004 0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54,
14005 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07, 0x7c, 0x3a, 0x0b, 0x0e,
14006 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00,
14007 0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe,
14008 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77, 0x02, 0x01, 0xc6, 0xfe,
14009 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08,
14010 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe,
14011 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12, 0x48, 0xfe, 0x08, 0x17,
14012 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07,
14013 0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55,
14014 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x1c, 0x63, 0x13,
14015 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80,
14016 0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60,
14017 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8, 0x00, 0x1c, 0x95, 0x13,
14018 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96,
14019 0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b,
14020 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x49,
14021 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe,
14022 0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13,
14023 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xbe, 0xfe, 0x03,
14024 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16,
14025 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9,
14026 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27,
14027 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24,
14028 0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e,
14029 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10, 0xfe, 0x40, 0x5a, 0x23,
14030 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa,
14031 0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
14032 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe, 0x43, 0x48, 0x2d, 0x93,
14033 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4,
14034 0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0,
14035 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa, 0x18, 0x45, 0xfe, 0x1c,
14036 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4,
14037 0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01,
14038 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe, 0x7e, 0x01, 0xfe, 0xc8,
14039 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01,
14040 0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14,
14041 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14,
14042 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07,
14043 0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
14044 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01, 0x08, 0x02, 0x50, 0x02,
14045 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08,
14046 0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe,
14047 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17, 0x74, 0x5f, 0xcc, 0x01,
14048 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00,
14049 0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f,
14050 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13, 0x16, 0xfe, 0x64, 0x1a,
14051 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02,
14052 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01,
14053 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa, 0xfe, 0x80, 0xe7, 0x1a,
14054 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18,
14055 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80,
14056 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x0a,
14057 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
14058 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3,
14059 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe, 0xf4, 0x1a, 0xfe, 0xfa,
14060 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03,
14061 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07,
14062 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x24, 0xb1, 0xfe,
14063 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c,
14064 0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1,
14065 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe, 0xaf, 0x19, 0xfe, 0x98,
14066 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f,
14067 0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04,
14068 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a, 0x7c, 0x12, 0xfe, 0x0f,
14069 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b,
14070 0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe,
14071 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee, 0x1b, 0xfe, 0x36, 0x14,
14072 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a,
14073 0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45,
14074 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe, 0x39, 0xf0, 0x75, 0x26,
14075 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe,
14076 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13,
14077 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe,
14078 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb,
14079 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01,
14080 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14, 0x56,
14081 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15,
14082 0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80,
14083 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90,
14084 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20,
14085 0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44,
14086 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09, 0x1a, 0xa4, 0x0a, 0x67,
14087 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52,
14088 0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b,
14089 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10, 0xfe, 0x4e, 0xe4, 0xfe,
14090 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03,
14091 0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1,
14092 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe,
14093 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a,
14094 0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8,
14095 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe, 0x1a, 0x10, 0x09, 0x0d,
14096 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42,
14097 0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08,
14098 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e, 0xfe, 0x82, 0xf0, 0xfe,
14099 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18,
14100 0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82,
14101 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86, 0x83, 0x33, 0x0b, 0x0e,
14102 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04,
14103 0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80,
14104 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04, 0xfe, 0x99, 0x83, 0xfe,
14105 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47,
14106 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
14107 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x08, 0x90, 0x04,
14108 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79,
14109 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
14110 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x3c, 0x90, 0x04,
14111 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83,
14112 0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
14115 STATIC unsigned short _adv_asc38C1600_size =
14116 sizeof(_adv_asc38C1600_buf); /* 0x1673 */
14117 STATIC ADV_DCNT _adv_asc38C1600_chksum =
14118 0x0604EF77UL; /* Expanded little-endian checksum. */
14120 /* a_init.c */
14122 * EEPROM Configuration.
14124 * All drivers should use this structure to set the default EEPROM
14125 * configuration. The BIOS now uses this structure when it is built.
14126 * Additional structure information can be found in a_condor.h where
14127 * the structure is defined.
14129 * The *_Field_IsChar structs are needed to correct for endianness.
14130 * These values are read from the board 16 bits at a time directly
14131 * into the structs. Because some fields are char, the values will be
14132 * in the wrong order. The *_Field_IsChar tells when to flip the
14133 * bytes. Data read and written to PCI memory is automatically swapped
14134 * on big-endian platforms so char fields read as words are actually being
14135 * unswapped on big-endian platforms.
14137 STATIC ADVEEP_3550_CONFIG
14138 Default_3550_EEPROM_Config __initdata = {
14139 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
14140 0x0000, /* cfg_msw */
14141 0xFFFF, /* disc_enable */
14142 0xFFFF, /* wdtr_able */
14143 0xFFFF, /* sdtr_able */
14144 0xFFFF, /* start_motor */
14145 0xFFFF, /* tagqng_able */
14146 0xFFFF, /* bios_scan */
14147 0, /* scam_tolerant */
14148 7, /* adapter_scsi_id */
14149 0, /* bios_boot_delay */
14150 3, /* scsi_reset_delay */
14151 0, /* bios_id_lun */
14152 0, /* termination */
14153 0, /* reserved1 */
14154 0xFFE7, /* bios_ctrl */
14155 0xFFFF, /* ultra_able */
14156 0, /* reserved2 */
14157 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
14158 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
14159 0, /* dvc_cntl */
14160 0, /* bug_fix */
14161 0, /* serial_number_word1 */
14162 0, /* serial_number_word2 */
14163 0, /* serial_number_word3 */
14164 0, /* check_sum */
14165 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* oem_name[16] */
14166 0, /* dvc_err_code */
14167 0, /* adv_err_code */
14168 0, /* adv_err_addr */
14169 0, /* saved_dvc_err_code */
14170 0, /* saved_adv_err_code */
14171 0, /* saved_adv_err_addr */
14172 0 /* num_of_err */
14175 STATIC ADVEEP_3550_CONFIG
14176 ADVEEP_3550_Config_Field_IsChar __initdata = {
14177 0, /* cfg_lsw */
14178 0, /* cfg_msw */
14179 0, /* -disc_enable */
14180 0, /* wdtr_able */
14181 0, /* sdtr_able */
14182 0, /* start_motor */
14183 0, /* tagqng_able */
14184 0, /* bios_scan */
14185 0, /* scam_tolerant */
14186 1, /* adapter_scsi_id */
14187 1, /* bios_boot_delay */
14188 1, /* scsi_reset_delay */
14189 1, /* bios_id_lun */
14190 1, /* termination */
14191 1, /* reserved1 */
14192 0, /* bios_ctrl */
14193 0, /* ultra_able */
14194 0, /* reserved2 */
14195 1, /* max_host_qng */
14196 1, /* max_dvc_qng */
14197 0, /* dvc_cntl */
14198 0, /* bug_fix */
14199 0, /* serial_number_word1 */
14200 0, /* serial_number_word2 */
14201 0, /* serial_number_word3 */
14202 0, /* check_sum */
14203 { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* oem_name[16] */
14204 0, /* dvc_err_code */
14205 0, /* adv_err_code */
14206 0, /* adv_err_addr */
14207 0, /* saved_dvc_err_code */
14208 0, /* saved_adv_err_code */
14209 0, /* saved_adv_err_addr */
14210 0 /* num_of_err */
14213 STATIC ADVEEP_38C0800_CONFIG
14214 Default_38C0800_EEPROM_Config __initdata = {
14215 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
14216 0x0000, /* 01 cfg_msw */
14217 0xFFFF, /* 02 disc_enable */
14218 0xFFFF, /* 03 wdtr_able */
14219 0x4444, /* 04 sdtr_speed1 */
14220 0xFFFF, /* 05 start_motor */
14221 0xFFFF, /* 06 tagqng_able */
14222 0xFFFF, /* 07 bios_scan */
14223 0, /* 08 scam_tolerant */
14224 7, /* 09 adapter_scsi_id */
14225 0, /* bios_boot_delay */
14226 3, /* 10 scsi_reset_delay */
14227 0, /* bios_id_lun */
14228 0, /* 11 termination_se */
14229 0, /* termination_lvd */
14230 0xFFE7, /* 12 bios_ctrl */
14231 0x4444, /* 13 sdtr_speed2 */
14232 0x4444, /* 14 sdtr_speed3 */
14233 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
14234 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
14235 0, /* 16 dvc_cntl */
14236 0x4444, /* 17 sdtr_speed4 */
14237 0, /* 18 serial_number_word1 */
14238 0, /* 19 serial_number_word2 */
14239 0, /* 20 serial_number_word3 */
14240 0, /* 21 check_sum */
14241 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */
14242 0, /* 30 dvc_err_code */
14243 0, /* 31 adv_err_code */
14244 0, /* 32 adv_err_addr */
14245 0, /* 33 saved_dvc_err_code */
14246 0, /* 34 saved_adv_err_code */
14247 0, /* 35 saved_adv_err_addr */
14248 0, /* 36 reserved */
14249 0, /* 37 reserved */
14250 0, /* 38 reserved */
14251 0, /* 39 reserved */
14252 0, /* 40 reserved */
14253 0, /* 41 reserved */
14254 0, /* 42 reserved */
14255 0, /* 43 reserved */
14256 0, /* 44 reserved */
14257 0, /* 45 reserved */
14258 0, /* 46 reserved */
14259 0, /* 47 reserved */
14260 0, /* 48 reserved */
14261 0, /* 49 reserved */
14262 0, /* 50 reserved */
14263 0, /* 51 reserved */
14264 0, /* 52 reserved */
14265 0, /* 53 reserved */
14266 0, /* 54 reserved */
14267 0, /* 55 reserved */
14268 0, /* 56 cisptr_lsw */
14269 0, /* 57 cisprt_msw */
14270 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
14271 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
14272 0, /* 60 reserved */
14273 0, /* 61 reserved */
14274 0, /* 62 reserved */
14275 0 /* 63 reserved */
14278 STATIC ADVEEP_38C0800_CONFIG
14279 ADVEEP_38C0800_Config_Field_IsChar __initdata = {
14280 0, /* 00 cfg_lsw */
14281 0, /* 01 cfg_msw */
14282 0, /* 02 disc_enable */
14283 0, /* 03 wdtr_able */
14284 0, /* 04 sdtr_speed1 */
14285 0, /* 05 start_motor */
14286 0, /* 06 tagqng_able */
14287 0, /* 07 bios_scan */
14288 0, /* 08 scam_tolerant */
14289 1, /* 09 adapter_scsi_id */
14290 1, /* bios_boot_delay */
14291 1, /* 10 scsi_reset_delay */
14292 1, /* bios_id_lun */
14293 1, /* 11 termination_se */
14294 1, /* termination_lvd */
14295 0, /* 12 bios_ctrl */
14296 0, /* 13 sdtr_speed2 */
14297 0, /* 14 sdtr_speed3 */
14298 1, /* 15 max_host_qng */
14299 1, /* max_dvc_qng */
14300 0, /* 16 dvc_cntl */
14301 0, /* 17 sdtr_speed4 */
14302 0, /* 18 serial_number_word1 */
14303 0, /* 19 serial_number_word2 */
14304 0, /* 20 serial_number_word3 */
14305 0, /* 21 check_sum */
14306 { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* 22-29 oem_name[16] */
14307 0, /* 30 dvc_err_code */
14308 0, /* 31 adv_err_code */
14309 0, /* 32 adv_err_addr */
14310 0, /* 33 saved_dvc_err_code */
14311 0, /* 34 saved_adv_err_code */
14312 0, /* 35 saved_adv_err_addr */
14313 0, /* 36 reserved */
14314 0, /* 37 reserved */
14315 0, /* 38 reserved */
14316 0, /* 39 reserved */
14317 0, /* 40 reserved */
14318 0, /* 41 reserved */
14319 0, /* 42 reserved */
14320 0, /* 43 reserved */
14321 0, /* 44 reserved */
14322 0, /* 45 reserved */
14323 0, /* 46 reserved */
14324 0, /* 47 reserved */
14325 0, /* 48 reserved */
14326 0, /* 49 reserved */
14327 0, /* 50 reserved */
14328 0, /* 51 reserved */
14329 0, /* 52 reserved */
14330 0, /* 53 reserved */
14331 0, /* 54 reserved */
14332 0, /* 55 reserved */
14333 0, /* 56 cisptr_lsw */
14334 0, /* 57 cisprt_msw */
14335 0, /* 58 subsysvid */
14336 0, /* 59 subsysid */
14337 0, /* 60 reserved */
14338 0, /* 61 reserved */
14339 0, /* 62 reserved */
14340 0 /* 63 reserved */
14343 STATIC ADVEEP_38C1600_CONFIG
14344 Default_38C1600_EEPROM_Config __initdata = {
14345 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
14346 0x0000, /* 01 cfg_msw */
14347 0xFFFF, /* 02 disc_enable */
14348 0xFFFF, /* 03 wdtr_able */
14349 0x5555, /* 04 sdtr_speed1 */
14350 0xFFFF, /* 05 start_motor */
14351 0xFFFF, /* 06 tagqng_able */
14352 0xFFFF, /* 07 bios_scan */
14353 0, /* 08 scam_tolerant */
14354 7, /* 09 adapter_scsi_id */
14355 0, /* bios_boot_delay */
14356 3, /* 10 scsi_reset_delay */
14357 0, /* bios_id_lun */
14358 0, /* 11 termination_se */
14359 0, /* termination_lvd */
14360 0xFFE7, /* 12 bios_ctrl */
14361 0x5555, /* 13 sdtr_speed2 */
14362 0x5555, /* 14 sdtr_speed3 */
14363 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
14364 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
14365 0, /* 16 dvc_cntl */
14366 0x5555, /* 17 sdtr_speed4 */
14367 0, /* 18 serial_number_word1 */
14368 0, /* 19 serial_number_word2 */
14369 0, /* 20 serial_number_word3 */
14370 0, /* 21 check_sum */
14371 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */
14372 0, /* 30 dvc_err_code */
14373 0, /* 31 adv_err_code */
14374 0, /* 32 adv_err_addr */
14375 0, /* 33 saved_dvc_err_code */
14376 0, /* 34 saved_adv_err_code */
14377 0, /* 35 saved_adv_err_addr */
14378 0, /* 36 reserved */
14379 0, /* 37 reserved */
14380 0, /* 38 reserved */
14381 0, /* 39 reserved */
14382 0, /* 40 reserved */
14383 0, /* 41 reserved */
14384 0, /* 42 reserved */
14385 0, /* 43 reserved */
14386 0, /* 44 reserved */
14387 0, /* 45 reserved */
14388 0, /* 46 reserved */
14389 0, /* 47 reserved */
14390 0, /* 48 reserved */
14391 0, /* 49 reserved */
14392 0, /* 50 reserved */
14393 0, /* 51 reserved */
14394 0, /* 52 reserved */
14395 0, /* 53 reserved */
14396 0, /* 54 reserved */
14397 0, /* 55 reserved */
14398 0, /* 56 cisptr_lsw */
14399 0, /* 57 cisprt_msw */
14400 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
14401 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
14402 0, /* 60 reserved */
14403 0, /* 61 reserved */
14404 0, /* 62 reserved */
14405 0 /* 63 reserved */
14408 STATIC ADVEEP_38C1600_CONFIG
14409 ADVEEP_38C1600_Config_Field_IsChar __initdata = {
14410 0, /* 00 cfg_lsw */
14411 0, /* 01 cfg_msw */
14412 0, /* 02 disc_enable */
14413 0, /* 03 wdtr_able */
14414 0, /* 04 sdtr_speed1 */
14415 0, /* 05 start_motor */
14416 0, /* 06 tagqng_able */
14417 0, /* 07 bios_scan */
14418 0, /* 08 scam_tolerant */
14419 1, /* 09 adapter_scsi_id */
14420 1, /* bios_boot_delay */
14421 1, /* 10 scsi_reset_delay */
14422 1, /* bios_id_lun */
14423 1, /* 11 termination_se */
14424 1, /* termination_lvd */
14425 0, /* 12 bios_ctrl */
14426 0, /* 13 sdtr_speed2 */
14427 0, /* 14 sdtr_speed3 */
14428 1, /* 15 max_host_qng */
14429 1, /* max_dvc_qng */
14430 0, /* 16 dvc_cntl */
14431 0, /* 17 sdtr_speed4 */
14432 0, /* 18 serial_number_word1 */
14433 0, /* 19 serial_number_word2 */
14434 0, /* 20 serial_number_word3 */
14435 0, /* 21 check_sum */
14436 { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* 22-29 oem_name[16] */
14437 0, /* 30 dvc_err_code */
14438 0, /* 31 adv_err_code */
14439 0, /* 32 adv_err_addr */
14440 0, /* 33 saved_dvc_err_code */
14441 0, /* 34 saved_adv_err_code */
14442 0, /* 35 saved_adv_err_addr */
14443 0, /* 36 reserved */
14444 0, /* 37 reserved */
14445 0, /* 38 reserved */
14446 0, /* 39 reserved */
14447 0, /* 40 reserved */
14448 0, /* 41 reserved */
14449 0, /* 42 reserved */
14450 0, /* 43 reserved */
14451 0, /* 44 reserved */
14452 0, /* 45 reserved */
14453 0, /* 46 reserved */
14454 0, /* 47 reserved */
14455 0, /* 48 reserved */
14456 0, /* 49 reserved */
14457 0, /* 50 reserved */
14458 0, /* 51 reserved */
14459 0, /* 52 reserved */
14460 0, /* 53 reserved */
14461 0, /* 54 reserved */
14462 0, /* 55 reserved */
14463 0, /* 56 cisptr_lsw */
14464 0, /* 57 cisprt_msw */
14465 0, /* 58 subsysvid */
14466 0, /* 59 subsysid */
14467 0, /* 60 reserved */
14468 0, /* 61 reserved */
14469 0, /* 62 reserved */
14470 0 /* 63 reserved */
14474 * Initialize the ADV_DVC_VAR structure.
14476 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14478 * For a non-fatal error return a warning code. If there are no warnings
14479 * then 0 is returned.
14481 STATIC int __init
14482 AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
14484 ushort warn_code;
14485 AdvPortAddr iop_base;
14486 uchar pci_cmd_reg;
14487 int status;
14489 warn_code = 0;
14490 asc_dvc->err_code = 0;
14491 iop_base = asc_dvc->iop_base;
14494 * PCI Command Register
14496 * Note: AscPCICmdRegBits_BusMastering definition (0x0007) includes
14497 * I/O Space Control, Memory Space Control and Bus Master Control bits.
14500 if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
14501 AscPCIConfigCommandRegister))
14502 & AscPCICmdRegBits_BusMastering)
14503 != AscPCICmdRegBits_BusMastering)
14505 pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
14507 DvcAdvWritePCIConfigByte(asc_dvc,
14508 AscPCIConfigCommandRegister, pci_cmd_reg);
14510 if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister))
14511 & AscPCICmdRegBits_BusMastering)
14512 != AscPCICmdRegBits_BusMastering)
14514 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14519 * PCI Latency Timer
14521 * If the "latency timer" register is 0x20 or above, then we don't need
14522 * to change it. Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
14523 * comes up less than 0x20).
14525 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
14526 DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer, 0x20);
14527 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20)
14529 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14534 * Save the state of the PCI Configuration Command Register
14535 * "Parity Error Response Control" Bit. If the bit is clear (0),
14536 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
14537 * DMA parity errors.
14539 asc_dvc->cfg->control_flag = 0;
14540 if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
14541 & AscPCICmdRegBits_ParErrRespCtrl)) == 0)
14543 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
14546 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
14547 ADV_LIB_VERSION_MINOR;
14548 asc_dvc->cfg->chip_version =
14549 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
14551 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
14552 (ushort) AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
14553 (ushort) ADV_CHIP_ID_BYTE);
14555 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
14556 (ushort) AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
14557 (ushort) ADV_CHIP_ID_WORD);
14560 * Reset the chip to start and allow register writes.
14562 if (AdvFindSignature(iop_base) == 0)
14564 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
14565 return ADV_ERROR;
14567 else {
14569 * The caller must set 'chip_type' to a valid setting.
14571 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
14572 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
14573 asc_dvc->chip_type != ADV_CHIP_ASC38C1600)
14575 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14576 return ADV_ERROR;
14580 * Reset Chip.
14582 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14583 ADV_CTRL_REG_CMD_RESET);
14584 DvcSleepMilliSecond(100);
14585 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14586 ADV_CTRL_REG_CMD_WR_IO_REG);
14588 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
14590 if ((status = AdvInitFrom38C1600EEP(asc_dvc)) == ADV_ERROR)
14592 return ADV_ERROR;
14594 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
14596 if ((status = AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR)
14598 return ADV_ERROR;
14600 } else
14602 if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR)
14604 return ADV_ERROR;
14607 warn_code |= status;
14610 return warn_code;
14614 * Initialize the ASC-3550.
14616 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14618 * For a non-fatal error return a warning code. If there are no warnings
14619 * then 0 is returned.
14621 * Needed after initialization for error recovery.
14623 STATIC int
14624 AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
14626 AdvPortAddr iop_base;
14627 ushort warn_code;
14628 ADV_DCNT sum;
14629 int begin_addr;
14630 int end_addr;
14631 ushort code_sum;
14632 int word;
14633 int j;
14634 int adv_asc3550_expanded_size;
14635 ADV_CARR_T *carrp;
14636 ADV_DCNT contig_len;
14637 ADV_SDCNT buf_size;
14638 ADV_PADDR carr_paddr;
14639 int i;
14640 ushort scsi_cfg1;
14641 uchar tid;
14642 ushort bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
14643 ushort wdtr_able = 0, sdtr_able, tagqng_able;
14644 uchar max_cmd[ADV_MAX_TID + 1];
14646 /* If there is already an error, don't continue. */
14647 if (asc_dvc->err_code != 0)
14649 return ADV_ERROR;
14653 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
14655 if (asc_dvc->chip_type != ADV_CHIP_ASC3550)
14657 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14658 return ADV_ERROR;
14661 warn_code = 0;
14662 iop_base = asc_dvc->iop_base;
14665 * Save the RISC memory BIOS region before writing the microcode.
14666 * The BIOS may already be loaded and using its RISC LRAM region
14667 * so its region must be saved and restored.
14669 * Note: This code makes the assumption, which is currently true,
14670 * that a chip reset does not clear RISC LRAM.
14672 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
14674 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
14678 * Save current per TID negotiated values.
14680 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
14682 ushort bios_version, major, minor;
14684 bios_version = bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM)/2];
14685 major = (bios_version >> 12) & 0xF;
14686 minor = (bios_version >> 8) & 0xF;
14687 if (major < 3 || (major == 3 && minor == 1))
14689 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
14690 AdvReadWordLram(iop_base, 0x120, wdtr_able);
14691 } else
14693 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14696 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14697 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14698 for (tid = 0; tid <= ADV_MAX_TID; tid++)
14700 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14701 max_cmd[tid]);
14705 * Load the Microcode
14707 * Write the microcode image to RISC memory starting at address 0.
14709 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14710 /* Assume the following compressed format of the microcode buffer:
14712 * 254 word (508 byte) table indexed by byte code followed
14713 * by the following byte codes:
14715 * 1-Byte Code:
14716 * 00: Emit word 0 in table.
14717 * 01: Emit word 1 in table.
14719 * FD: Emit word 253 in table.
14721 * Multi-Byte Code:
14722 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14723 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14725 word = 0;
14726 for (i = 253 * 2; i < _adv_asc3550_size; i++)
14728 if (_adv_asc3550_buf[i] == 0xff)
14730 for (j = 0; j < _adv_asc3550_buf[i + 1]; j++)
14732 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14733 _adv_asc3550_buf[i + 3] << 8) |
14734 _adv_asc3550_buf[i + 2]));
14735 word++;
14737 i += 3;
14738 } else if (_adv_asc3550_buf[i] == 0xfe)
14740 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14741 _adv_asc3550_buf[i + 2] << 8) |
14742 _adv_asc3550_buf[i + 1]));
14743 i += 2;
14744 word++;
14745 } else
14747 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14748 _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) |
14749 _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
14750 word++;
14755 * Set 'word' for later use to clear the rest of memory and save
14756 * the expanded mcode size.
14758 word *= 2;
14759 adv_asc3550_expanded_size = word;
14762 * Clear the rest of ASC-3550 Internal RAM (8KB).
14764 for (; word < ADV_3550_MEMSIZE; word += 2)
14766 AdvWriteWordAutoIncLram(iop_base, 0);
14770 * Verify the microcode checksum.
14772 sum = 0;
14773 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14775 for (word = 0; word < adv_asc3550_expanded_size; word += 2)
14777 sum += AdvReadWordAutoIncLram(iop_base);
14780 if (sum != _adv_asc3550_chksum)
14782 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14783 return ADV_ERROR;
14787 * Restore the RISC memory BIOS region.
14789 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
14791 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
14795 * Calculate and write the microcode code checksum to the microcode
14796 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14798 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14799 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14800 code_sum = 0;
14801 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14802 for (word = begin_addr; word < end_addr; word += 2)
14804 code_sum += AdvReadWordAutoIncLram(iop_base);
14806 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14809 * Read and save microcode version and date.
14811 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
14812 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
14815 * Set the chip type to indicate the ASC3550.
14817 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
14820 * If the PCI Configuration Command Register "Parity Error Response
14821 * Control" Bit was clear (0), then set the microcode variable
14822 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14823 * to ignore DMA parity errors.
14825 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
14827 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14828 word |= CONTROL_FLAG_IGNORE_PERR;
14829 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14833 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
14834 * threshold of 128 bytes. This register is only accessible to the host.
14836 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14837 START_CTL_EMFU | READ_CMD_MRM);
14840 * Microcode operating variables for WDTR, SDTR, and command tag
14841 * queuing will be set in AdvInquiryHandling() based on what a
14842 * device reports it is capable of in Inquiry byte 7.
14844 * If SCSI Bus Resets have been disabled, then directly set
14845 * SDTR and WDTR from the EEPROM configuration. This will allow
14846 * the BIOS and warm boot to work without a SCSI bus hang on
14847 * the Inquiry caused by host and target mismatched DTR values.
14848 * Without the SCSI Bus Reset, before an Inquiry a device can't
14849 * be assumed to be in Asynchronous, Narrow mode.
14851 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
14853 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
14854 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
14858 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
14859 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
14860 * bitmask. These values determine the maximum SDTR speed negotiated
14861 * with a device.
14863 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14864 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14865 * without determining here whether the device supports SDTR.
14867 * 4-bit speed SDTR speed name
14868 * =========== ===============
14869 * 0000b (0x0) SDTR disabled
14870 * 0001b (0x1) 5 Mhz
14871 * 0010b (0x2) 10 Mhz
14872 * 0011b (0x3) 20 Mhz (Ultra)
14873 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
14874 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
14875 * 0110b (0x6) Undefined
14877 * 1111b (0xF) Undefined
14879 word = 0;
14880 for (tid = 0; tid <= ADV_MAX_TID; tid++)
14882 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able)
14884 /* Set Ultra speed for TID 'tid'. */
14885 word |= (0x3 << (4 * (tid % 4)));
14886 } else
14888 /* Set Fast speed for TID 'tid'. */
14889 word |= (0x2 << (4 * (tid % 4)));
14891 if (tid == 3) /* Check if done with sdtr_speed1. */
14893 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
14894 word = 0;
14895 } else if (tid == 7) /* Check if done with sdtr_speed2. */
14897 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
14898 word = 0;
14899 } else if (tid == 11) /* Check if done with sdtr_speed3. */
14901 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
14902 word = 0;
14903 } else if (tid == 15) /* Check if done with sdtr_speed4. */
14905 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
14906 /* End of loop. */
14911 * Set microcode operating variable for the disconnect per TID bitmask.
14913 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
14916 * Set SCSI_CFG0 Microcode Default Value.
14918 * The microcode will set the SCSI_CFG0 register using this value
14919 * after it is started below.
14921 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14922 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14923 asc_dvc->chip_scsi_id);
14926 * Determine SCSI_CFG1 Microcode Default Value.
14928 * The microcode will set the SCSI_CFG1 register using this value
14929 * after it is started below.
14932 /* Read current SCSI_CFG1 Register value. */
14933 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14936 * If all three connectors are in use, return an error.
14938 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
14939 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0)
14941 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
14942 return ADV_ERROR;
14946 * If the internal narrow cable is reversed all of the SCSI_CTRL
14947 * register signals will be set. Check for and return an error if
14948 * this condition is found.
14950 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
14952 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14953 return ADV_ERROR;
14957 * If this is a differential board and a single-ended device
14958 * is attached to one of the connectors, return an error.
14960 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0)
14962 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
14963 return ADV_ERROR;
14967 * If automatic termination control is enabled, then set the
14968 * termination value based on a table listed in a_condor.h.
14970 * If manual termination was specified with an EEPROM setting
14971 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
14972 * is ready to be 'ored' into SCSI_CFG1.
14974 if (asc_dvc->cfg->termination == 0)
14977 * The software always controls termination by setting TERM_CTL_SEL.
14978 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
14980 asc_dvc->cfg->termination |= TERM_CTL_SEL;
14982 switch(scsi_cfg1 & CABLE_DETECT)
14984 /* TERM_CTL_H: on, TERM_CTL_L: on */
14985 case 0x3: case 0x7: case 0xB: case 0xD: case 0xE: case 0xF:
14986 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
14987 break;
14989 /* TERM_CTL_H: on, TERM_CTL_L: off */
14990 case 0x1: case 0x5: case 0x9: case 0xA: case 0xC:
14991 asc_dvc->cfg->termination |= TERM_CTL_H;
14992 break;
14994 /* TERM_CTL_H: off, TERM_CTL_L: off */
14995 case 0x2: case 0x6:
14996 break;
15001 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
15003 scsi_cfg1 &= ~TERM_CTL;
15006 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
15007 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
15008 * referenced, because the hardware internally inverts
15009 * the Termination High and Low bits if TERM_POL is set.
15011 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
15014 * Set SCSI_CFG1 Microcode Default Value
15016 * Set filter value and possibly modified termination control
15017 * bits in the Microcode SCSI_CFG1 Register Value.
15019 * The microcode will set the SCSI_CFG1 register using this value
15020 * after it is started below.
15022 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
15023 FLTR_DISABLE | scsi_cfg1);
15026 * Set MEM_CFG Microcode Default Value
15028 * The microcode will set the MEM_CFG register using this value
15029 * after it is started below.
15031 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15032 * are defined.
15034 * ASC-3550 has 8KB internal memory.
15036 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15037 BIOS_EN | RAM_SZ_8KB);
15040 * Set SEL_MASK Microcode Default Value
15042 * The microcode will set the SEL_MASK register using this value
15043 * after it is started below.
15045 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15046 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15049 * Build carrier freelist.
15051 * Driver must have already allocated memory and set 'carrier_buf'.
15053 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15055 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15056 asc_dvc->carr_freelist = NULL;
15057 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
15059 buf_size = ADV_CARRIER_BUFSIZE;
15060 } else
15062 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15065 do {
15067 * Get physical address of the carrier 'carrp'.
15069 contig_len = sizeof(ADV_CARR_T);
15070 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
15071 (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
15073 buf_size -= sizeof(ADV_CARR_T);
15076 * If the current carrier is not physically contiguous, then
15077 * maybe there was a page crossing. Try the next carrier aligned
15078 * start address.
15080 if (contig_len < sizeof(ADV_CARR_T))
15082 carrp++;
15083 continue;
15086 carrp->carr_pa = carr_paddr;
15087 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15090 * Insert the carrier at the beginning of the freelist.
15092 carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15093 asc_dvc->carr_freelist = carrp;
15095 carrp++;
15097 while (buf_size > 0);
15100 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15103 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
15105 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15106 return ADV_ERROR;
15108 asc_dvc->carr_freelist = (ADV_CARR_T *)
15109 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15112 * The first command issued will be placed in the stopper carrier.
15114 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15117 * Set RISC ICQ physical address start value.
15119 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15122 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15124 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
15126 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15127 return ADV_ERROR;
15129 asc_dvc->carr_freelist = (ADV_CARR_T *)
15130 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15133 * The first command completed by the RISC will be placed in
15134 * the stopper.
15136 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15137 * completed the RISC will set the ASC_RQ_STOPPER bit.
15139 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15142 * Set RISC IRQ physical address start value.
15144 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15145 asc_dvc->carr_pending_cnt = 0;
15147 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15148 (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
15150 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15151 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15153 /* finally, finally, gentlemen, start your engine */
15154 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15157 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15158 * Resets should be performed. The RISC has to be running
15159 * to issue a SCSI Bus Reset.
15161 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
15164 * If the BIOS Signature is present in memory, restore the
15165 * BIOS Handshake Configuration Table and do not perform
15166 * a SCSI Bus Reset.
15168 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
15171 * Restore per TID negotiated values.
15173 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15174 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15175 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15176 for (tid = 0; tid <= ADV_MAX_TID; tid++)
15178 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15179 max_cmd[tid]);
15181 } else
15183 if (AdvResetSB(asc_dvc) != ADV_TRUE)
15185 warn_code = ASC_WARN_BUSRESET_ERROR;
15190 return warn_code;
15194 * Initialize the ASC-38C0800.
15196 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15198 * For a non-fatal error return a warning code. If there are no warnings
15199 * then 0 is returned.
15201 * Needed after initialization for error recovery.
15203 STATIC int
15204 AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
15206 AdvPortAddr iop_base;
15207 ushort warn_code;
15208 ADV_DCNT sum;
15209 int begin_addr;
15210 int end_addr;
15211 ushort code_sum;
15212 int word;
15213 int j;
15214 int adv_asc38C0800_expanded_size;
15215 ADV_CARR_T *carrp;
15216 ADV_DCNT contig_len;
15217 ADV_SDCNT buf_size;
15218 ADV_PADDR carr_paddr;
15219 int i;
15220 ushort scsi_cfg1;
15221 uchar byte;
15222 uchar tid;
15223 ushort bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
15224 ushort wdtr_able, sdtr_able, tagqng_able;
15225 uchar max_cmd[ADV_MAX_TID + 1];
15227 /* If there is already an error, don't continue. */
15228 if (asc_dvc->err_code != 0)
15230 return ADV_ERROR;
15234 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
15236 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800)
15238 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
15239 return ADV_ERROR;
15242 warn_code = 0;
15243 iop_base = asc_dvc->iop_base;
15246 * Save the RISC memory BIOS region before writing the microcode.
15247 * The BIOS may already be loaded and using its RISC LRAM region
15248 * so its region must be saved and restored.
15250 * Note: This code makes the assumption, which is currently true,
15251 * that a chip reset does not clear RISC LRAM.
15253 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15255 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15259 * Save current per TID negotiated values.
15261 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15262 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15263 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15264 for (tid = 0; tid <= ADV_MAX_TID; tid++)
15266 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15267 max_cmd[tid]);
15271 * RAM BIST (RAM Built-In Self Test)
15273 * Address : I/O base + offset 0x38h register (byte).
15274 * Function: Bit 7-6(RW) : RAM mode
15275 * Normal Mode : 0x00
15276 * Pre-test Mode : 0x40
15277 * RAM Test Mode : 0x80
15278 * Bit 5 : unused
15279 * Bit 4(RO) : Done bit
15280 * Bit 3-0(RO) : Status
15281 * Host Error : 0x08
15282 * Int_RAM Error : 0x04
15283 * RISC Error : 0x02
15284 * SCSI Error : 0x01
15285 * No Error : 0x00
15287 * Note: RAM BIST code should be put right here, before loading the
15288 * microcode and after saving the RISC memory BIOS region.
15292 * LRAM Pre-test
15294 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15295 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15296 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15297 * to NORMAL_MODE, return an error too.
15299 for (i = 0; i < 2; i++)
15301 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15302 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15303 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15304 if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE)
15306 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15307 return ADV_ERROR;
15310 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15311 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15312 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15313 != NORMAL_VALUE)
15315 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15316 return ADV_ERROR;
15321 * LRAM Test - It takes about 1.5 ms to run through the test.
15323 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15324 * If Done bit not set or Status not 0, save register byte, set the
15325 * err_code, and return an error.
15327 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15328 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
15330 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15331 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0)
15333 /* Get here if Done bit not set or Status not 0. */
15334 asc_dvc->bist_err_code = byte; /* for BIOS display message */
15335 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15336 return ADV_ERROR;
15339 /* We need to reset back to normal mode after LRAM test passes. */
15340 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15343 * Load the Microcode
15345 * Write the microcode image to RISC memory starting at address 0.
15348 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15350 /* Assume the following compressed format of the microcode buffer:
15352 * 254 word (508 byte) table indexed by byte code followed
15353 * by the following byte codes:
15355 * 1-Byte Code:
15356 * 00: Emit word 0 in table.
15357 * 01: Emit word 1 in table.
15359 * FD: Emit word 253 in table.
15361 * Multi-Byte Code:
15362 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15363 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15365 word = 0;
15366 for (i = 253 * 2; i < _adv_asc38C0800_size; i++)
15368 if (_adv_asc38C0800_buf[i] == 0xff)
15370 for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++)
15372 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15373 _adv_asc38C0800_buf[i + 3] << 8) |
15374 _adv_asc38C0800_buf[i + 2]));
15375 word++;
15377 i += 3;
15378 } else if (_adv_asc38C0800_buf[i] == 0xfe)
15380 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15381 _adv_asc38C0800_buf[i + 2] << 8) |
15382 _adv_asc38C0800_buf[i + 1]));
15383 i += 2;
15384 word++;
15385 } else
15387 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15388 _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) |
15389 _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
15390 word++;
15395 * Set 'word' for later use to clear the rest of memory and save
15396 * the expanded mcode size.
15398 word *= 2;
15399 adv_asc38C0800_expanded_size = word;
15402 * Clear the rest of ASC-38C0800 Internal RAM (16KB).
15404 for (; word < ADV_38C0800_MEMSIZE; word += 2)
15406 AdvWriteWordAutoIncLram(iop_base, 0);
15410 * Verify the microcode checksum.
15412 sum = 0;
15413 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15415 for (word = 0; word < adv_asc38C0800_expanded_size; word += 2)
15417 sum += AdvReadWordAutoIncLram(iop_base);
15419 ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
15421 ASC_DBG2(1,
15422 "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
15423 (ulong) sum, (ulong) _adv_asc38C0800_chksum);
15425 if (sum != _adv_asc38C0800_chksum)
15427 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15428 return ADV_ERROR;
15432 * Restore the RISC memory BIOS region.
15434 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15436 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15440 * Calculate and write the microcode code checksum to the microcode
15441 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15443 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15444 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15445 code_sum = 0;
15446 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15447 for (word = begin_addr; word < end_addr; word += 2)
15449 code_sum += AdvReadWordAutoIncLram(iop_base);
15451 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15454 * Read microcode version and date.
15456 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
15457 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
15460 * Set the chip type to indicate the ASC38C0800.
15462 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
15465 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15466 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15467 * cable detection and then we are able to read C_DET[3:0].
15469 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15470 * Microcode Default Value' section below.
15472 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15473 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV);
15476 * If the PCI Configuration Command Register "Parity Error Response
15477 * Control" Bit was clear (0), then set the microcode variable
15478 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15479 * to ignore DMA parity errors.
15481 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
15483 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15484 word |= CONTROL_FLAG_IGNORE_PERR;
15485 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15489 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
15490 * bits for the default FIFO threshold.
15492 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
15494 * For DMA Errata #4 set the BC_THRESH_ENB bit.
15496 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15497 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
15500 * Microcode operating variables for WDTR, SDTR, and command tag
15501 * queuing will be set in AdvInquiryHandling() based on what a
15502 * device reports it is capable of in Inquiry byte 7.
15504 * If SCSI Bus Resets have been disabled, then directly set
15505 * SDTR and WDTR from the EEPROM configuration. This will allow
15506 * the BIOS and warm boot to work without a SCSI bus hang on
15507 * the Inquiry caused by host and target mismatched DTR values.
15508 * Without the SCSI Bus Reset, before an Inquiry a device can't
15509 * be assumed to be in Asynchronous, Narrow mode.
15511 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
15513 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
15514 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
15518 * Set microcode operating variables for DISC and SDTR_SPEED1,
15519 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15520 * configuration values.
15522 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15523 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15524 * without determining here whether the device supports SDTR.
15526 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
15527 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15528 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15529 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15530 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15533 * Set SCSI_CFG0 Microcode Default Value.
15535 * The microcode will set the SCSI_CFG0 register using this value
15536 * after it is started below.
15538 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15539 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15540 asc_dvc->chip_scsi_id);
15543 * Determine SCSI_CFG1 Microcode Default Value.
15545 * The microcode will set the SCSI_CFG1 register using this value
15546 * after it is started below.
15549 /* Read current SCSI_CFG1 Register value. */
15550 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15553 * If the internal narrow cable is reversed all of the SCSI_CTRL
15554 * register signals will be set. Check for and return an error if
15555 * this condition is found.
15557 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
15559 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15560 return ADV_ERROR;
15564 * All kind of combinations of devices attached to one of four connectors
15565 * are acceptable except HVD device attached. For example, LVD device can
15566 * be attached to SE connector while SE device attached to LVD connector.
15567 * If LVD device attached to SE connector, it only runs up to Ultra speed.
15569 * If an HVD device is attached to one of LVD connectors, return an error.
15570 * However, there is no way to detect HVD device attached to SE connectors.
15572 if (scsi_cfg1 & HVD)
15574 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15575 return ADV_ERROR;
15579 * If either SE or LVD automatic termination control is enabled, then
15580 * set the termination value based on a table listed in a_condor.h.
15582 * If manual termination was specified with an EEPROM setting then
15583 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
15584 * be 'ored' into SCSI_CFG1.
15586 if ((asc_dvc->cfg->termination & TERM_SE) == 0)
15588 /* SE automatic termination control is enabled. */
15589 switch(scsi_cfg1 & C_DET_SE)
15591 /* TERM_SE_HI: on, TERM_SE_LO: on */
15592 case 0x1: case 0x2: case 0x3:
15593 asc_dvc->cfg->termination |= TERM_SE;
15594 break;
15596 /* TERM_SE_HI: on, TERM_SE_LO: off */
15597 case 0x0:
15598 asc_dvc->cfg->termination |= TERM_SE_HI;
15599 break;
15603 if ((asc_dvc->cfg->termination & TERM_LVD) == 0)
15605 /* LVD automatic termination control is enabled. */
15606 switch(scsi_cfg1 & C_DET_LVD)
15608 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
15609 case 0x4: case 0x8: case 0xC:
15610 asc_dvc->cfg->termination |= TERM_LVD;
15611 break;
15613 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
15614 case 0x0:
15615 break;
15620 * Clear any set TERM_SE and TERM_LVD bits.
15622 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
15625 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
15627 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
15630 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
15631 * and set possibly modified termination control bits in the Microcode
15632 * SCSI_CFG1 Register Value.
15634 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
15637 * Set SCSI_CFG1 Microcode Default Value
15639 * Set possibly modified termination control and reset DIS_TERM_DRV
15640 * bits in the Microcode SCSI_CFG1 Register Value.
15642 * The microcode will set the SCSI_CFG1 register using this value
15643 * after it is started below.
15645 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15648 * Set MEM_CFG Microcode Default Value
15650 * The microcode will set the MEM_CFG register using this value
15651 * after it is started below.
15653 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15654 * are defined.
15656 * ASC-38C0800 has 16KB internal memory.
15658 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15659 BIOS_EN | RAM_SZ_16KB);
15662 * Set SEL_MASK Microcode Default Value
15664 * The microcode will set the SEL_MASK register using this value
15665 * after it is started below.
15667 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15668 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15671 * Build the carrier freelist.
15673 * Driver must have already allocated memory and set 'carrier_buf'.
15675 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15677 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15678 asc_dvc->carr_freelist = NULL;
15679 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
15681 buf_size = ADV_CARRIER_BUFSIZE;
15682 } else
15684 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15687 do {
15689 * Get physical address for the carrier 'carrp'.
15691 contig_len = sizeof(ADV_CARR_T);
15692 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
15693 (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
15695 buf_size -= sizeof(ADV_CARR_T);
15698 * If the current carrier is not physically contiguous, then
15699 * maybe there was a page crossing. Try the next carrier aligned
15700 * start address.
15702 if (contig_len < sizeof(ADV_CARR_T))
15704 carrp++;
15705 continue;
15708 carrp->carr_pa = carr_paddr;
15709 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15712 * Insert the carrier at the beginning of the freelist.
15714 carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15715 asc_dvc->carr_freelist = carrp;
15717 carrp++;
15719 while (buf_size > 0);
15722 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15725 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
15727 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15728 return ADV_ERROR;
15730 asc_dvc->carr_freelist = (ADV_CARR_T *)
15731 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15734 * The first command issued will be placed in the stopper carrier.
15736 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15739 * Set RISC ICQ physical address start value.
15740 * carr_pa is LE, must be native before write
15742 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15745 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15747 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
15749 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15750 return ADV_ERROR;
15752 asc_dvc->carr_freelist = (ADV_CARR_T *)
15753 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15756 * The first command completed by the RISC will be placed in
15757 * the stopper.
15759 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15760 * completed the RISC will set the ASC_RQ_STOPPER bit.
15762 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15765 * Set RISC IRQ physical address start value.
15767 * carr_pa is LE, must be native before write *
15769 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15770 asc_dvc->carr_pending_cnt = 0;
15772 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15773 (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
15775 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15776 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15778 /* finally, finally, gentlemen, start your engine */
15779 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15782 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15783 * Resets should be performed. The RISC has to be running
15784 * to issue a SCSI Bus Reset.
15786 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
15789 * If the BIOS Signature is present in memory, restore the
15790 * BIOS Handshake Configuration Table and do not perform
15791 * a SCSI Bus Reset.
15793 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
15796 * Restore per TID negotiated values.
15798 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15799 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15800 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15801 for (tid = 0; tid <= ADV_MAX_TID; tid++)
15803 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15804 max_cmd[tid]);
15806 } else
15808 if (AdvResetSB(asc_dvc) != ADV_TRUE)
15810 warn_code = ASC_WARN_BUSRESET_ERROR;
15815 return warn_code;
15819 * Initialize the ASC-38C1600.
15821 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
15823 * For a non-fatal error return a warning code. If there are no warnings
15824 * then 0 is returned.
15826 * Needed after initialization for error recovery.
15828 STATIC int
15829 AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
15831 AdvPortAddr iop_base;
15832 ushort warn_code;
15833 ADV_DCNT sum;
15834 int begin_addr;
15835 int end_addr;
15836 ushort code_sum;
15837 long word;
15838 int j;
15839 int adv_asc38C1600_expanded_size;
15840 ADV_CARR_T *carrp;
15841 ADV_DCNT contig_len;
15842 ADV_SDCNT buf_size;
15843 ADV_PADDR carr_paddr;
15844 int i;
15845 ushort scsi_cfg1;
15846 uchar byte;
15847 uchar tid;
15848 ushort bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
15849 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
15850 uchar max_cmd[ASC_MAX_TID + 1];
15852 /* If there is already an error, don't continue. */
15853 if (asc_dvc->err_code != 0)
15855 return ADV_ERROR;
15859 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
15861 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600)
15863 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
15864 return ADV_ERROR;
15867 warn_code = 0;
15868 iop_base = asc_dvc->iop_base;
15871 * Save the RISC memory BIOS region before writing the microcode.
15872 * The BIOS may already be loaded and using its RISC LRAM region
15873 * so its region must be saved and restored.
15875 * Note: This code makes the assumption, which is currently true,
15876 * that a chip reset does not clear RISC LRAM.
15878 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15880 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15884 * Save current per TID negotiated values.
15886 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15887 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15888 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15889 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15890 for (tid = 0; tid <= ASC_MAX_TID; tid++)
15892 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15893 max_cmd[tid]);
15897 * RAM BIST (Built-In Self Test)
15899 * Address : I/O base + offset 0x38h register (byte).
15900 * Function: Bit 7-6(RW) : RAM mode
15901 * Normal Mode : 0x00
15902 * Pre-test Mode : 0x40
15903 * RAM Test Mode : 0x80
15904 * Bit 5 : unused
15905 * Bit 4(RO) : Done bit
15906 * Bit 3-0(RO) : Status
15907 * Host Error : 0x08
15908 * Int_RAM Error : 0x04
15909 * RISC Error : 0x02
15910 * SCSI Error : 0x01
15911 * No Error : 0x00
15913 * Note: RAM BIST code should be put right here, before loading the
15914 * microcode and after saving the RISC memory BIOS region.
15918 * LRAM Pre-test
15920 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15921 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15922 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15923 * to NORMAL_MODE, return an error too.
15925 for (i = 0; i < 2; i++)
15927 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15928 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15929 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15930 if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE)
15932 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15933 return ADV_ERROR;
15936 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15937 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15938 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15939 != NORMAL_VALUE)
15941 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15942 return ADV_ERROR;
15947 * LRAM Test - It takes about 1.5 ms to run through the test.
15949 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15950 * If Done bit not set or Status not 0, save register byte, set the
15951 * err_code, and return an error.
15953 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15954 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
15956 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15957 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0)
15959 /* Get here if Done bit not set or Status not 0. */
15960 asc_dvc->bist_err_code = byte; /* for BIOS display message */
15961 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15962 return ADV_ERROR;
15965 /* We need to reset back to normal mode after LRAM test passes. */
15966 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15969 * Load the Microcode
15971 * Write the microcode image to RISC memory starting at address 0.
15974 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15977 * Assume the following compressed format of the microcode buffer:
15979 * 254 word (508 byte) table indexed by byte code followed
15980 * by the following byte codes:
15982 * 1-Byte Code:
15983 * 00: Emit word 0 in table.
15984 * 01: Emit word 1 in table.
15986 * FD: Emit word 253 in table.
15988 * Multi-Byte Code:
15989 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15990 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15992 word = 0;
15993 for (i = 253 * 2; i < _adv_asc38C1600_size; i++)
15995 if (_adv_asc38C1600_buf[i] == 0xff)
15997 for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++)
15999 AdvWriteWordAutoIncLram(iop_base, (((ushort)
16000 _adv_asc38C1600_buf[i + 3] << 8) |
16001 _adv_asc38C1600_buf[i + 2]));
16002 word++;
16004 i += 3;
16005 } else if (_adv_asc38C1600_buf[i] == 0xfe)
16007 AdvWriteWordAutoIncLram(iop_base, (((ushort)
16008 _adv_asc38C1600_buf[i + 2] << 8) |
16009 _adv_asc38C1600_buf[i + 1]));
16010 i += 2;
16011 word++;
16012 } else
16014 AdvWriteWordAutoIncLram(iop_base, (((ushort)
16015 _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) |
16016 _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
16017 word++;
16022 * Set 'word' for later use to clear the rest of memory and save
16023 * the expanded mcode size.
16025 word *= 2;
16026 adv_asc38C1600_expanded_size = word;
16029 * Clear the rest of ASC-38C1600 Internal RAM (32KB).
16031 for (; word < ADV_38C1600_MEMSIZE; word += 2)
16033 AdvWriteWordAutoIncLram(iop_base, 0);
16037 * Verify the microcode checksum.
16039 sum = 0;
16040 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
16042 for (word = 0; word < adv_asc38C1600_expanded_size; word += 2)
16044 sum += AdvReadWordAutoIncLram(iop_base);
16047 if (sum != _adv_asc38C1600_chksum)
16049 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
16050 return ADV_ERROR;
16054 * Restore the RISC memory BIOS region.
16056 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
16058 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
16062 * Calculate and write the microcode code checksum to the microcode
16063 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
16065 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
16066 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
16067 code_sum = 0;
16068 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
16069 for (word = begin_addr; word < end_addr; word += 2)
16071 code_sum += AdvReadWordAutoIncLram(iop_base);
16073 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
16076 * Read microcode version and date.
16078 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
16079 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
16082 * Set the chip type to indicate the ASC38C1600.
16084 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
16087 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
16088 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
16089 * cable detection and then we are able to read C_DET[3:0].
16091 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
16092 * Microcode Default Value' section below.
16094 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
16095 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV);
16098 * If the PCI Configuration Command Register "Parity Error Response
16099 * Control" Bit was clear (0), then set the microcode variable
16100 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
16101 * to ignore DMA parity errors.
16103 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
16105 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16106 word |= CONTROL_FLAG_IGNORE_PERR;
16107 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16111 * If the BIOS control flag AIPP (Asynchronous Information
16112 * Phase Protection) disable bit is not set, then set the firmware
16113 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
16114 * AIPP checking and encoding.
16116 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0)
16118 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16119 word |= CONTROL_FLAG_ENABLE_AIPP;
16120 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16124 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
16125 * and START_CTL_TH [3:2].
16127 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
16128 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
16131 * Microcode operating variables for WDTR, SDTR, and command tag
16132 * queuing will be set in AdvInquiryHandling() based on what a
16133 * device reports it is capable of in Inquiry byte 7.
16135 * If SCSI Bus Resets have been disabled, then directly set
16136 * SDTR and WDTR from the EEPROM configuration. This will allow
16137 * the BIOS and warm boot to work without a SCSI bus hang on
16138 * the Inquiry caused by host and target mismatched DTR values.
16139 * Without the SCSI Bus Reset, before an Inquiry a device can't
16140 * be assumed to be in Asynchronous, Narrow mode.
16142 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
16144 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
16145 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
16149 * Set microcode operating variables for DISC and SDTR_SPEED1,
16150 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
16151 * configuration values.
16153 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
16154 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
16155 * without determining here whether the device supports SDTR.
16157 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
16158 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
16159 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
16160 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
16161 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
16164 * Set SCSI_CFG0 Microcode Default Value.
16166 * The microcode will set the SCSI_CFG0 register using this value
16167 * after it is started below.
16169 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
16170 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
16171 asc_dvc->chip_scsi_id);
16174 * Calculate SCSI_CFG1 Microcode Default Value.
16176 * The microcode will set the SCSI_CFG1 register using this value
16177 * after it is started below.
16179 * Each ASC-38C1600 function has only two cable detect bits.
16180 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
16182 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
16185 * If the cable is reversed all of the SCSI_CTRL register signals
16186 * will be set. Check for and return an error if this condition is
16187 * found.
16189 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
16191 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
16192 return ADV_ERROR;
16196 * Each ASC-38C1600 function has two connectors. Only an HVD device
16197 * can not be connected to either connector. An LVD device or SE device
16198 * may be connected to either connecor. If an SE device is connected,
16199 * then at most Ultra speed (20 Mhz) can be used on both connectors.
16201 * If an HVD device is attached, return an error.
16203 if (scsi_cfg1 & HVD)
16205 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
16206 return ADV_ERROR;
16210 * Each function in the ASC-38C1600 uses only the SE cable detect and
16211 * termination because there are two connectors for each function. Each
16212 * function may use either LVD or SE mode. Corresponding the SE automatic
16213 * termination control EEPROM bits are used for each function. Each
16214 * function has its own EEPROM. If SE automatic control is enabled for
16215 * the function, then set the termination value based on a table listed
16216 * in a_condor.h.
16218 * If manual termination is specified in the EEPROM for the function,
16219 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
16220 * ready to be 'ored' into SCSI_CFG1.
16222 if ((asc_dvc->cfg->termination & TERM_SE) == 0)
16224 /* SE automatic termination control is enabled. */
16225 switch(scsi_cfg1 & C_DET_SE)
16227 /* TERM_SE_HI: on, TERM_SE_LO: on */
16228 case 0x1: case 0x2: case 0x3:
16229 asc_dvc->cfg->termination |= TERM_SE;
16230 break;
16232 case 0x0:
16233 if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0)
16235 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
16237 else
16239 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
16240 asc_dvc->cfg->termination |= TERM_SE_HI;
16242 break;
16247 * Clear any set TERM_SE bits.
16249 scsi_cfg1 &= ~TERM_SE;
16252 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
16254 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
16257 * Clear Big Endian and Terminator Polarity bits and set possibly
16258 * modified termination control bits in the Microcode SCSI_CFG1
16259 * Register Value.
16261 * Big Endian bit is not used even on big endian machines.
16263 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
16266 * Set SCSI_CFG1 Microcode Default Value
16268 * Set possibly modified termination control bits in the Microcode
16269 * SCSI_CFG1 Register Value.
16271 * The microcode will set the SCSI_CFG1 register using this value
16272 * after it is started below.
16274 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
16277 * Set MEM_CFG Microcode Default Value
16279 * The microcode will set the MEM_CFG register using this value
16280 * after it is started below.
16282 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
16283 * are defined.
16285 * ASC-38C1600 has 32KB internal memory.
16287 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
16288 * out a special 16K Adv Library and Microcode version. After the issue
16289 * resolved, we should turn back to the 32K support. Both a_condor.h and
16290 * mcode.sas files also need to be updated.
16292 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
16293 * BIOS_EN | RAM_SZ_32KB);
16295 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, BIOS_EN | RAM_SZ_16KB);
16298 * Set SEL_MASK Microcode Default Value
16300 * The microcode will set the SEL_MASK register using this value
16301 * after it is started below.
16303 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
16304 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
16307 * Build the carrier freelist.
16309 * Driver must have already allocated memory and set 'carrier_buf'.
16312 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
16314 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
16315 asc_dvc->carr_freelist = NULL;
16316 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
16318 buf_size = ADV_CARRIER_BUFSIZE;
16319 } else
16321 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
16324 do {
16326 * Get physical address for the carrier 'carrp'.
16328 contig_len = sizeof(ADV_CARR_T);
16329 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
16330 (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
16332 buf_size -= sizeof(ADV_CARR_T);
16335 * If the current carrier is not physically contiguous, then
16336 * maybe there was a page crossing. Try the next carrier aligned
16337 * start address.
16339 if (contig_len < sizeof(ADV_CARR_T))
16341 carrp++;
16342 continue;
16345 carrp->carr_pa = carr_paddr;
16346 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
16349 * Insert the carrier at the beginning of the freelist.
16351 carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
16352 asc_dvc->carr_freelist = carrp;
16354 carrp++;
16356 while (buf_size > 0);
16359 * Set-up the Host->RISC Initiator Command Queue (ICQ).
16361 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
16363 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16364 return ADV_ERROR;
16366 asc_dvc->carr_freelist = (ADV_CARR_T *)
16367 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
16370 * The first command issued will be placed in the stopper carrier.
16372 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16375 * Set RISC ICQ physical address start value. Initialize the
16376 * COMMA register to the same value otherwise the RISC will
16377 * prematurely detect a command is available.
16379 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
16380 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
16381 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
16384 * Set-up the RISC->Host Initiator Response Queue (IRQ).
16386 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
16388 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16389 return ADV_ERROR;
16391 asc_dvc->carr_freelist = (ADV_CARR_T *)
16392 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
16395 * The first command completed by the RISC will be placed in
16396 * the stopper.
16398 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
16399 * completed the RISC will set the ASC_RQ_STOPPER bit.
16401 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16404 * Set RISC IRQ physical address start value.
16406 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
16407 asc_dvc->carr_pending_cnt = 0;
16409 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
16410 (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
16411 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
16412 AdvWriteWordRegister(iop_base, IOPW_PC, word);
16414 /* finally, finally, gentlemen, start your engine */
16415 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
16418 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
16419 * Resets should be performed. The RISC has to be running
16420 * to issue a SCSI Bus Reset.
16422 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
16425 * If the BIOS Signature is present in memory, restore the
16426 * per TID microcode operating variables.
16428 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
16431 * Restore per TID negotiated values.
16433 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16434 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16435 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16436 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16437 for (tid = 0; tid <= ASC_MAX_TID; tid++)
16439 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16440 max_cmd[tid]);
16442 } else
16444 if (AdvResetSB(asc_dvc) != ADV_TRUE)
16446 warn_code = ASC_WARN_BUSRESET_ERROR;
16451 return warn_code;
16455 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16456 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16457 * all of this is done.
16459 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16461 * For a non-fatal error return a warning code. If there are no warnings
16462 * then 0 is returned.
16464 * Note: Chip is stopped on entry.
16466 STATIC int __init
16467 AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
16469 AdvPortAddr iop_base;
16470 ushort warn_code;
16471 ADVEEP_3550_CONFIG eep_config;
16472 int i;
16474 iop_base = asc_dvc->iop_base;
16476 warn_code = 0;
16479 * Read the board's EEPROM configuration.
16481 * Set default values if a bad checksum is found.
16483 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16485 warn_code |= ASC_WARN_EEPROM_CHKSUM;
16488 * Set EEPROM default values.
16490 for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++)
16492 *((uchar *) &eep_config + i) =
16493 *((uchar *) &Default_3550_EEPROM_Config + i);
16497 * Assume the 6 byte board serial number that was read
16498 * from EEPROM is correct even if the EEPROM checksum
16499 * failed.
16501 eep_config.serial_number_word3 =
16502 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16504 eep_config.serial_number_word2 =
16505 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16507 eep_config.serial_number_word1 =
16508 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16510 AdvSet3550EEPConfig(iop_base, &eep_config);
16513 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16514 * EEPROM configuration that was read.
16516 * This is the mapping of EEPROM fields to Adv Library fields.
16518 asc_dvc->wdtr_able = eep_config.wdtr_able;
16519 asc_dvc->sdtr_able = eep_config.sdtr_able;
16520 asc_dvc->ultra_able = eep_config.ultra_able;
16521 asc_dvc->tagqng_able = eep_config.tagqng_able;
16522 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16523 asc_dvc->max_host_qng = eep_config.max_host_qng;
16524 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16525 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16526 asc_dvc->start_motor = eep_config.start_motor;
16527 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16528 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16529 asc_dvc->no_scam = eep_config.scam_tolerant;
16530 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16531 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16532 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16535 * Set the host maximum queuing (max. 253, min. 16) and the per device
16536 * maximum queuing (max. 63, min. 4).
16538 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
16540 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16541 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
16543 /* If the value is zero, assume it is uninitialized. */
16544 if (eep_config.max_host_qng == 0)
16546 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16547 } else
16549 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16553 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
16555 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16556 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
16558 /* If the value is zero, assume it is uninitialized. */
16559 if (eep_config.max_dvc_qng == 0)
16561 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16562 } else
16564 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16569 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16570 * set 'max_dvc_qng' to 'max_host_qng'.
16572 if (eep_config.max_dvc_qng > eep_config.max_host_qng)
16574 eep_config.max_dvc_qng = eep_config.max_host_qng;
16578 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16579 * values based on possibly adjusted EEPROM values.
16581 asc_dvc->max_host_qng = eep_config.max_host_qng;
16582 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16586 * If the EEPROM 'termination' field is set to automatic (0), then set
16587 * the ADV_DVC_CFG 'termination' field to automatic also.
16589 * If the termination is specified with a non-zero 'termination'
16590 * value check that a legal value is set and set the ADV_DVC_CFG
16591 * 'termination' field appropriately.
16593 if (eep_config.termination == 0)
16595 asc_dvc->cfg->termination = 0; /* auto termination */
16596 } else
16598 /* Enable manual control with low off / high off. */
16599 if (eep_config.termination == 1)
16601 asc_dvc->cfg->termination = TERM_CTL_SEL;
16603 /* Enable manual control with low off / high on. */
16604 } else if (eep_config.termination == 2)
16606 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
16608 /* Enable manual control with low on / high on. */
16609 } else if (eep_config.termination == 3)
16611 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
16612 } else
16615 * The EEPROM 'termination' field contains a bad value. Use
16616 * automatic termination instead.
16618 asc_dvc->cfg->termination = 0;
16619 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16623 return warn_code;
16627 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16628 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16629 * all of this is done.
16631 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16633 * For a non-fatal error return a warning code. If there are no warnings
16634 * then 0 is returned.
16636 * Note: Chip is stopped on entry.
16638 STATIC int __init
16639 AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
16641 AdvPortAddr iop_base;
16642 ushort warn_code;
16643 ADVEEP_38C0800_CONFIG eep_config;
16644 int i;
16645 uchar tid, termination;
16646 ushort sdtr_speed = 0;
16648 iop_base = asc_dvc->iop_base;
16650 warn_code = 0;
16653 * Read the board's EEPROM configuration.
16655 * Set default values if a bad checksum is found.
16657 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16659 warn_code |= ASC_WARN_EEPROM_CHKSUM;
16662 * Set EEPROM default values.
16664 for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++)
16666 *((uchar *) &eep_config + i) =
16667 *((uchar *) &Default_38C0800_EEPROM_Config + i);
16671 * Assume the 6 byte board serial number that was read
16672 * from EEPROM is correct even if the EEPROM checksum
16673 * failed.
16675 eep_config.serial_number_word3 =
16676 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16678 eep_config.serial_number_word2 =
16679 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16681 eep_config.serial_number_word1 =
16682 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16684 AdvSet38C0800EEPConfig(iop_base, &eep_config);
16687 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
16688 * EEPROM configuration that was read.
16690 * This is the mapping of EEPROM fields to Adv Library fields.
16692 asc_dvc->wdtr_able = eep_config.wdtr_able;
16693 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16694 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16695 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16696 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16697 asc_dvc->tagqng_able = eep_config.tagqng_able;
16698 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16699 asc_dvc->max_host_qng = eep_config.max_host_qng;
16700 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16701 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16702 asc_dvc->start_motor = eep_config.start_motor;
16703 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16704 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16705 asc_dvc->no_scam = eep_config.scam_tolerant;
16706 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16707 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16708 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16711 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16712 * are set, then set an 'sdtr_able' bit for it.
16714 asc_dvc->sdtr_able = 0;
16715 for (tid = 0; tid <= ADV_MAX_TID; tid++)
16717 if (tid == 0)
16719 sdtr_speed = asc_dvc->sdtr_speed1;
16720 } else if (tid == 4)
16722 sdtr_speed = asc_dvc->sdtr_speed2;
16723 } else if (tid == 8)
16725 sdtr_speed = asc_dvc->sdtr_speed3;
16726 } else if (tid == 12)
16728 sdtr_speed = asc_dvc->sdtr_speed4;
16730 if (sdtr_speed & ADV_MAX_TID)
16732 asc_dvc->sdtr_able |= (1 << tid);
16734 sdtr_speed >>= 4;
16738 * Set the host maximum queuing (max. 253, min. 16) and the per device
16739 * maximum queuing (max. 63, min. 4).
16741 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
16743 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16744 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
16746 /* If the value is zero, assume it is uninitialized. */
16747 if (eep_config.max_host_qng == 0)
16749 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16750 } else
16752 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16756 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
16758 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16759 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
16761 /* If the value is zero, assume it is uninitialized. */
16762 if (eep_config.max_dvc_qng == 0)
16764 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16765 } else
16767 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16772 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16773 * set 'max_dvc_qng' to 'max_host_qng'.
16775 if (eep_config.max_dvc_qng > eep_config.max_host_qng)
16777 eep_config.max_dvc_qng = eep_config.max_host_qng;
16781 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16782 * values based on possibly adjusted EEPROM values.
16784 asc_dvc->max_host_qng = eep_config.max_host_qng;
16785 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16788 * If the EEPROM 'termination' field is set to automatic (0), then set
16789 * the ADV_DVC_CFG 'termination' field to automatic also.
16791 * If the termination is specified with a non-zero 'termination'
16792 * value check that a legal value is set and set the ADV_DVC_CFG
16793 * 'termination' field appropriately.
16795 if (eep_config.termination_se == 0)
16797 termination = 0; /* auto termination for SE */
16798 } else
16800 /* Enable manual control with low off / high off. */
16801 if (eep_config.termination_se == 1)
16803 termination = 0;
16805 /* Enable manual control with low off / high on. */
16806 } else if (eep_config.termination_se == 2)
16808 termination = TERM_SE_HI;
16810 /* Enable manual control with low on / high on. */
16811 } else if (eep_config.termination_se == 3)
16813 termination = TERM_SE;
16814 } else
16817 * The EEPROM 'termination_se' field contains a bad value.
16818 * Use automatic termination instead.
16820 termination = 0;
16821 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16825 if (eep_config.termination_lvd == 0)
16827 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
16828 } else
16830 /* Enable manual control with low off / high off. */
16831 if (eep_config.termination_lvd == 1)
16833 asc_dvc->cfg->termination = termination;
16835 /* Enable manual control with low off / high on. */
16836 } else if (eep_config.termination_lvd == 2)
16838 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16840 /* Enable manual control with low on / high on. */
16841 } else if (eep_config.termination_lvd == 3)
16843 asc_dvc->cfg->termination =
16844 termination | TERM_LVD;
16845 } else
16848 * The EEPROM 'termination_lvd' field contains a bad value.
16849 * Use automatic termination instead.
16851 asc_dvc->cfg->termination = termination;
16852 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16856 return warn_code;
16860 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
16861 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
16862 * all of this is done.
16864 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
16866 * For a non-fatal error return a warning code. If there are no warnings
16867 * then 0 is returned.
16869 * Note: Chip is stopped on entry.
16871 STATIC int __init
16872 AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
16874 AdvPortAddr iop_base;
16875 ushort warn_code;
16876 ADVEEP_38C1600_CONFIG eep_config;
16877 int i;
16878 uchar tid, termination;
16879 ushort sdtr_speed = 0;
16881 iop_base = asc_dvc->iop_base;
16883 warn_code = 0;
16886 * Read the board's EEPROM configuration.
16888 * Set default values if a bad checksum is found.
16890 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16892 warn_code |= ASC_WARN_EEPROM_CHKSUM;
16895 * Set EEPROM default values.
16897 for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++)
16899 if (i == 1 && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) != 0)
16902 * Set Function 1 EEPROM Word 0 MSB
16904 * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11)
16905 * EEPROM bits.
16907 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and
16908 * old Mac system booting problem. The Expansion ROM must
16909 * be disabled in Function 1 for these systems.
16912 *((uchar *) &eep_config + i) =
16913 ((*((uchar *) &Default_38C1600_EEPROM_Config + i)) &
16914 (~(((ADV_EEPROM_BIOS_ENABLE | ADV_EEPROM_INTAB) >> 8) &
16915 0xFF)));
16918 * Set the INTAB (bit 11) if the GPIO 0 input indicates
16919 * the Function 1 interrupt line is wired to INTA.
16921 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
16922 * 1 - Function 1 interrupt line wired to INT A.
16923 * 0 - Function 1 interrupt line wired to INT B.
16925 * Note: Adapter boards always have Function 0 wired to INTA.
16926 * Put all 5 GPIO bits in input mode and then read
16927 * their input values.
16929 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
16930 if (AdvReadByteRegister(iop_base, IOPB_GPIO_DATA) & 0x01)
16932 /* Function 1 interrupt wired to INTA; Set EEPROM bit. */
16933 *((uchar *) &eep_config + i) |=
16934 ((ADV_EEPROM_INTAB >> 8) & 0xFF);
16937 else
16939 *((uchar *) &eep_config + i) =
16940 *((uchar *) &Default_38C1600_EEPROM_Config + i);
16945 * Assume the 6 byte board serial number that was read
16946 * from EEPROM is correct even if the EEPROM checksum
16947 * failed.
16949 eep_config.serial_number_word3 =
16950 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16952 eep_config.serial_number_word2 =
16953 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16955 eep_config.serial_number_word1 =
16956 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16958 AdvSet38C1600EEPConfig(iop_base, &eep_config);
16962 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16963 * EEPROM configuration that was read.
16965 * This is the mapping of EEPROM fields to Adv Library fields.
16967 asc_dvc->wdtr_able = eep_config.wdtr_able;
16968 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16969 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16970 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16971 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16972 asc_dvc->ppr_able = 0;
16973 asc_dvc->tagqng_able = eep_config.tagqng_able;
16974 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16975 asc_dvc->max_host_qng = eep_config.max_host_qng;
16976 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16977 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
16978 asc_dvc->start_motor = eep_config.start_motor;
16979 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16980 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16981 asc_dvc->no_scam = eep_config.scam_tolerant;
16984 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16985 * are set, then set an 'sdtr_able' bit for it.
16987 asc_dvc->sdtr_able = 0;
16988 for (tid = 0; tid <= ASC_MAX_TID; tid++)
16990 if (tid == 0)
16992 sdtr_speed = asc_dvc->sdtr_speed1;
16993 } else if (tid == 4)
16995 sdtr_speed = asc_dvc->sdtr_speed2;
16996 } else if (tid == 8)
16998 sdtr_speed = asc_dvc->sdtr_speed3;
16999 } else if (tid == 12)
17001 sdtr_speed = asc_dvc->sdtr_speed4;
17003 if (sdtr_speed & ASC_MAX_TID)
17005 asc_dvc->sdtr_able |= (1 << tid);
17007 sdtr_speed >>= 4;
17011 * Set the host maximum queuing (max. 253, min. 16) and the per device
17012 * maximum queuing (max. 63, min. 4).
17014 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
17016 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17017 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
17019 /* If the value is zero, assume it is uninitialized. */
17020 if (eep_config.max_host_qng == 0)
17022 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17023 } else
17025 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
17029 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
17031 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17032 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
17034 /* If the value is zero, assume it is uninitialized. */
17035 if (eep_config.max_dvc_qng == 0)
17037 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17038 } else
17040 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
17045 * If 'max_dvc_qng' is greater than 'max_host_qng', then
17046 * set 'max_dvc_qng' to 'max_host_qng'.
17048 if (eep_config.max_dvc_qng > eep_config.max_host_qng)
17050 eep_config.max_dvc_qng = eep_config.max_host_qng;
17054 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
17055 * values based on possibly adjusted EEPROM values.
17057 asc_dvc->max_host_qng = eep_config.max_host_qng;
17058 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
17061 * If the EEPROM 'termination' field is set to automatic (0), then set
17062 * the ASC_DVC_CFG 'termination' field to automatic also.
17064 * If the termination is specified with a non-zero 'termination'
17065 * value check that a legal value is set and set the ASC_DVC_CFG
17066 * 'termination' field appropriately.
17068 if (eep_config.termination_se == 0)
17070 termination = 0; /* auto termination for SE */
17071 } else
17073 /* Enable manual control with low off / high off. */
17074 if (eep_config.termination_se == 1)
17076 termination = 0;
17078 /* Enable manual control with low off / high on. */
17079 } else if (eep_config.termination_se == 2)
17081 termination = TERM_SE_HI;
17083 /* Enable manual control with low on / high on. */
17084 } else if (eep_config.termination_se == 3)
17086 termination = TERM_SE;
17087 } else
17090 * The EEPROM 'termination_se' field contains a bad value.
17091 * Use automatic termination instead.
17093 termination = 0;
17094 warn_code |= ASC_WARN_EEPROM_TERMINATION;
17098 if (eep_config.termination_lvd == 0)
17100 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
17101 } else
17103 /* Enable manual control with low off / high off. */
17104 if (eep_config.termination_lvd == 1)
17106 asc_dvc->cfg->termination = termination;
17108 /* Enable manual control with low off / high on. */
17109 } else if (eep_config.termination_lvd == 2)
17111 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
17113 /* Enable manual control with low on / high on. */
17114 } else if (eep_config.termination_lvd == 3)
17116 asc_dvc->cfg->termination =
17117 termination | TERM_LVD;
17118 } else
17121 * The EEPROM 'termination_lvd' field contains a bad value.
17122 * Use automatic termination instead.
17124 asc_dvc->cfg->termination = termination;
17125 warn_code |= ASC_WARN_EEPROM_TERMINATION;
17129 return warn_code;
17133 * Read EEPROM configuration into the specified buffer.
17135 * Return a checksum based on the EEPROM configuration read.
17137 STATIC ushort __init
17138 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
17140 ushort wval, chksum;
17141 ushort *wbuf;
17142 int eep_addr;
17143 ushort *charfields;
17145 charfields = (ushort *) &ADVEEP_3550_Config_Field_IsChar;
17146 wbuf = (ushort *) cfg_buf;
17147 chksum = 0;
17149 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17150 eep_addr < ADV_EEP_DVC_CFG_END;
17151 eep_addr++, wbuf++)
17153 wval = AdvReadEEPWord(iop_base, eep_addr);
17154 chksum += wval; /* Checksum is calculated from word values. */
17155 if (*charfields++) {
17156 *wbuf = le16_to_cpu(wval);
17157 } else {
17158 *wbuf = wval;
17161 /* Read checksum word. */
17162 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17163 wbuf++; charfields++;
17165 /* Read rest of EEPROM not covered by the checksum. */
17166 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17167 eep_addr < ADV_EEP_MAX_WORD_ADDR;
17168 eep_addr++, wbuf++)
17170 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17171 if (*charfields++) {
17172 *wbuf = le16_to_cpu(*wbuf);
17175 return chksum;
17179 * Read EEPROM configuration into the specified buffer.
17181 * Return a checksum based on the EEPROM configuration read.
17183 STATIC ushort __init
17184 AdvGet38C0800EEPConfig(AdvPortAddr iop_base,
17185 ADVEEP_38C0800_CONFIG *cfg_buf)
17187 ushort wval, chksum;
17188 ushort *wbuf;
17189 int eep_addr;
17190 ushort *charfields;
17192 charfields = (ushort *) &ADVEEP_38C0800_Config_Field_IsChar;
17193 wbuf = (ushort *) cfg_buf;
17194 chksum = 0;
17196 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17197 eep_addr < ADV_EEP_DVC_CFG_END;
17198 eep_addr++, wbuf++)
17200 wval = AdvReadEEPWord(iop_base, eep_addr);
17201 chksum += wval; /* Checksum is calculated from word values. */
17202 if (*charfields++) {
17203 *wbuf = le16_to_cpu(wval);
17204 } else {
17205 *wbuf = wval;
17208 /* Read checksum word. */
17209 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17210 wbuf++; charfields++;
17212 /* Read rest of EEPROM not covered by the checksum. */
17213 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17214 eep_addr < ADV_EEP_MAX_WORD_ADDR;
17215 eep_addr++, wbuf++)
17217 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17218 if (*charfields++) {
17219 *wbuf = le16_to_cpu(*wbuf);
17222 return chksum;
17226 * Read EEPROM configuration into the specified buffer.
17228 * Return a checksum based on the EEPROM configuration read.
17230 STATIC ushort __init
17231 AdvGet38C1600EEPConfig(AdvPortAddr iop_base,
17232 ADVEEP_38C1600_CONFIG *cfg_buf)
17234 ushort wval, chksum;
17235 ushort *wbuf;
17236 int eep_addr;
17237 ushort *charfields;
17239 charfields = (ushort*) &ADVEEP_38C1600_Config_Field_IsChar;
17240 wbuf = (ushort *) cfg_buf;
17241 chksum = 0;
17243 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17244 eep_addr < ADV_EEP_DVC_CFG_END;
17245 eep_addr++, wbuf++)
17247 wval = AdvReadEEPWord(iop_base, eep_addr);
17248 chksum += wval; /* Checksum is calculated from word values. */
17249 if (*charfields++) {
17250 *wbuf = le16_to_cpu(wval);
17251 } else {
17252 *wbuf = wval;
17255 /* Read checksum word. */
17256 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17257 wbuf++; charfields++;
17259 /* Read rest of EEPROM not covered by the checksum. */
17260 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17261 eep_addr < ADV_EEP_MAX_WORD_ADDR;
17262 eep_addr++, wbuf++)
17264 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17265 if (*charfields++) {
17266 *wbuf = le16_to_cpu(*wbuf);
17269 return chksum;
17273 * Read the EEPROM from specified location
17275 STATIC ushort __init
17276 AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
17278 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
17279 ASC_EEP_CMD_READ | eep_word_addr);
17280 AdvWaitEEPCmd(iop_base);
17281 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
17285 * Wait for EEPROM command to complete
17287 STATIC void __init
17288 AdvWaitEEPCmd(AdvPortAddr iop_base)
17290 int eep_delay_ms;
17292 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++)
17294 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE)
17296 break;
17298 DvcSleepMilliSecond(1);
17300 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == 0)
17302 ASC_ASSERT(0);
17304 return;
17308 * Write the EEPROM from 'cfg_buf'.
17310 void __init
17311 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
17313 ushort *wbuf;
17314 ushort addr, chksum;
17315 ushort *charfields;
17317 wbuf = (ushort *) cfg_buf;
17318 charfields = (ushort *) &ADVEEP_3550_Config_Field_IsChar;
17319 chksum = 0;
17321 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17322 AdvWaitEEPCmd(iop_base);
17325 * Write EEPROM from word 0 to word 20.
17327 for (addr = ADV_EEP_DVC_CFG_BEGIN;
17328 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17330 ushort word;
17332 if (*charfields++) {
17333 word = cpu_to_le16(*wbuf);
17334 } else {
17335 word = *wbuf;
17337 chksum += *wbuf; /* Checksum is calculated from word values. */
17338 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17339 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17340 AdvWaitEEPCmd(iop_base);
17341 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17345 * Write EEPROM checksum at word 21.
17347 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17348 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17349 AdvWaitEEPCmd(iop_base);
17350 wbuf++; charfields++;
17353 * Write EEPROM OEM name at words 22 to 29.
17355 for (addr = ADV_EEP_DVC_CTL_BEGIN;
17356 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17358 ushort word;
17360 if (*charfields++) {
17361 word = cpu_to_le16(*wbuf);
17362 } else {
17363 word = *wbuf;
17365 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17366 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17367 AdvWaitEEPCmd(iop_base);
17369 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17370 AdvWaitEEPCmd(iop_base);
17371 return;
17375 * Write the EEPROM from 'cfg_buf'.
17377 void __init
17378 AdvSet38C0800EEPConfig(AdvPortAddr iop_base,
17379 ADVEEP_38C0800_CONFIG *cfg_buf)
17381 ushort *wbuf;
17382 ushort *charfields;
17383 ushort addr, chksum;
17385 wbuf = (ushort *) cfg_buf;
17386 charfields = (ushort *) &ADVEEP_38C0800_Config_Field_IsChar;
17387 chksum = 0;
17389 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17390 AdvWaitEEPCmd(iop_base);
17393 * Write EEPROM from word 0 to word 20.
17395 for (addr = ADV_EEP_DVC_CFG_BEGIN;
17396 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17398 ushort word;
17400 if (*charfields++) {
17401 word = cpu_to_le16(*wbuf);
17402 } else {
17403 word = *wbuf;
17405 chksum += *wbuf; /* Checksum is calculated from word values. */
17406 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17407 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17408 AdvWaitEEPCmd(iop_base);
17409 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17413 * Write EEPROM checksum at word 21.
17415 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17416 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17417 AdvWaitEEPCmd(iop_base);
17418 wbuf++; charfields++;
17421 * Write EEPROM OEM name at words 22 to 29.
17423 for (addr = ADV_EEP_DVC_CTL_BEGIN;
17424 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17426 ushort word;
17428 if (*charfields++) {
17429 word = cpu_to_le16(*wbuf);
17430 } else {
17431 word = *wbuf;
17433 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17434 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17435 AdvWaitEEPCmd(iop_base);
17437 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17438 AdvWaitEEPCmd(iop_base);
17439 return;
17443 * Write the EEPROM from 'cfg_buf'.
17445 void __init
17446 AdvSet38C1600EEPConfig(AdvPortAddr iop_base,
17447 ADVEEP_38C1600_CONFIG *cfg_buf)
17449 ushort *wbuf;
17450 ushort *charfields;
17451 ushort addr, chksum;
17453 wbuf = (ushort *) cfg_buf;
17454 charfields = (ushort *) &ADVEEP_38C1600_Config_Field_IsChar;
17455 chksum = 0;
17457 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17458 AdvWaitEEPCmd(iop_base);
17461 * Write EEPROM from word 0 to word 20.
17463 for (addr = ADV_EEP_DVC_CFG_BEGIN;
17464 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17466 ushort word;
17468 if (*charfields++) {
17469 word = cpu_to_le16(*wbuf);
17470 } else {
17471 word = *wbuf;
17473 chksum += *wbuf; /* Checksum is calculated from word values. */
17474 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17475 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17476 AdvWaitEEPCmd(iop_base);
17477 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17481 * Write EEPROM checksum at word 21.
17483 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17484 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17485 AdvWaitEEPCmd(iop_base);
17486 wbuf++; charfields++;
17489 * Write EEPROM OEM name at words 22 to 29.
17491 for (addr = ADV_EEP_DVC_CTL_BEGIN;
17492 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17494 ushort word;
17496 if (*charfields++) {
17497 word = cpu_to_le16(*wbuf);
17498 } else {
17499 word = *wbuf;
17501 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17502 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17503 AdvWaitEEPCmd(iop_base);
17505 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17506 AdvWaitEEPCmd(iop_base);
17507 return;
17510 /* a_advlib.c */
17512 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
17514 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
17515 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
17516 * RISC to notify it a new command is ready to be executed.
17518 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
17519 * set to SCSI_MAX_RETRY.
17521 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
17522 * for DMA addresses or math operations are byte swapped to little-endian
17523 * order.
17525 * Return:
17526 * ADV_SUCCESS(1) - The request was successfully queued.
17527 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
17528 * request completes.
17529 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
17530 * host IC error.
17532 STATIC int
17533 AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc,
17534 ADV_SCSI_REQ_Q *scsiq)
17536 ulong last_int_level;
17537 AdvPortAddr iop_base;
17538 ADV_DCNT req_size;
17539 ADV_PADDR req_paddr;
17540 ADV_CARR_T *new_carrp;
17542 ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
17545 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
17547 if (scsiq->target_id > ADV_MAX_TID)
17549 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
17550 scsiq->done_status = QD_WITH_ERROR;
17551 return ADV_ERROR;
17554 iop_base = asc_dvc->iop_base;
17556 last_int_level = DvcEnterCritical();
17559 * Allocate a carrier ensuring at least one carrier always
17560 * remains on the freelist and initialize fields.
17562 if ((new_carrp = asc_dvc->carr_freelist) == NULL)
17564 DvcLeaveCritical(last_int_level);
17565 return ADV_BUSY;
17567 asc_dvc->carr_freelist = (ADV_CARR_T *)
17568 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
17569 asc_dvc->carr_pending_cnt++;
17572 * Set the carrier to be a stopper by setting 'next_vpa'
17573 * to the stopper value. The current stopper will be changed
17574 * below to point to the new stopper.
17576 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
17579 * Clear the ADV_SCSI_REQ_Q done flag.
17581 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
17583 req_size = sizeof(ADV_SCSI_REQ_Q);
17584 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *) scsiq,
17585 (ADV_SDCNT *) &req_size, ADV_IS_SCSIQ_FLAG);
17587 ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
17588 ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
17590 /* Wait for assertion before making little-endian */
17591 req_paddr = cpu_to_le32(req_paddr);
17593 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
17594 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
17595 scsiq->scsiq_rptr = req_paddr;
17597 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
17599 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
17600 * order during initialization.
17602 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
17605 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
17606 * the microcode. The newly allocated stopper will become the new
17607 * stopper.
17609 asc_dvc->icq_sp->areq_vpa = req_paddr;
17612 * Set the 'next_vpa' pointer for the old stopper to be the
17613 * physical address of the new stopper. The RISC can only
17614 * follow physical addresses.
17616 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
17619 * Set the host adapter stopper pointer to point to the new carrier.
17621 asc_dvc->icq_sp = new_carrp;
17623 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17624 asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
17627 * Tickle the RISC to tell it to read its Command Queue Head pointer.
17629 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
17630 if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
17633 * Clear the tickle value. In the ASC-3550 the RISC flag
17634 * command 'clr_tickle_a' does not work unless the host
17635 * value is cleared.
17637 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17639 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17642 * Notify the RISC a carrier is ready by writing the physical
17643 * address of the new carrier stopper to the COMMA register.
17645 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
17646 le32_to_cpu(new_carrp->carr_pa));
17649 DvcLeaveCritical(last_int_level);
17651 return ADV_SUCCESS;
17655 * Reset SCSI Bus and purge all outstanding requests.
17657 * Return Value:
17658 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
17659 * ADV_FALSE(0) - Microcode command failed.
17660 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
17661 * may be hung which requires driver recovery.
17663 STATIC int
17664 AdvResetSB(ADV_DVC_VAR *asc_dvc)
17666 int status;
17669 * Send the SCSI Bus Reset idle start idle command which asserts
17670 * the SCSI Bus Reset signal.
17672 status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_START, 0L);
17673 if (status != ADV_TRUE)
17675 return status;
17679 * Delay for the specified SCSI Bus Reset hold time.
17681 * The hold time delay is done on the host because the RISC has no
17682 * microsecond accurate timer.
17684 DvcDelayMicroSecond(asc_dvc, (ushort) ASC_SCSI_RESET_HOLD_TIME_US);
17687 * Send the SCSI Bus Reset end idle command which de-asserts
17688 * the SCSI Bus Reset signal and purges any pending requests.
17690 status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_END, 0L);
17691 if (status != ADV_TRUE)
17693 return status;
17696 DvcSleepMilliSecond((ADV_DCNT) asc_dvc->scsi_reset_wait * 1000);
17698 return status;
17702 * Reset chip and SCSI Bus.
17704 * Return Value:
17705 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
17706 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
17708 STATIC int
17709 AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
17711 int status;
17712 ushort wdtr_able, sdtr_able, tagqng_able;
17713 ushort ppr_able = 0;
17714 uchar tid, max_cmd[ADV_MAX_TID + 1];
17715 AdvPortAddr iop_base;
17716 ushort bios_sig;
17718 iop_base = asc_dvc->iop_base;
17721 * Save current per TID negotiated values.
17723 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17724 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17725 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17727 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17729 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17730 for (tid = 0; tid <= ADV_MAX_TID; tid++)
17732 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17733 max_cmd[tid]);
17737 * Force the AdvInitAsc3550/38C0800Driver() function to
17738 * perform a SCSI Bus Reset by clearing the BIOS signature word.
17739 * The initialization functions assumes a SCSI Bus Reset is not
17740 * needed if the BIOS signature word is present.
17742 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17743 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
17746 * Stop chip and reset it.
17748 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
17749 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
17750 DvcSleepMilliSecond(100);
17751 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG);
17754 * Reset Adv Library error code, if any, and try
17755 * re-initializing the chip.
17757 asc_dvc->err_code = 0;
17758 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17760 status = AdvInitAsc38C1600Driver(asc_dvc);
17762 else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
17764 status = AdvInitAsc38C0800Driver(asc_dvc);
17765 } else
17767 status = AdvInitAsc3550Driver(asc_dvc);
17770 /* Translate initialization return value to status value. */
17771 if (status == 0)
17773 status = ADV_TRUE;
17774 } else
17776 status = ADV_FALSE;
17780 * Restore the BIOS signature word.
17782 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17785 * Restore per TID negotiated values.
17787 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17788 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17789 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17791 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17793 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17794 for (tid = 0; tid <= ADV_MAX_TID; tid++)
17796 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17797 max_cmd[tid]);
17800 return status;
17804 * Adv Library Interrupt Service Routine
17806 * This function is called by a driver's interrupt service routine.
17807 * The function disables and re-enables interrupts.
17809 * When a microcode idle command is completed, the ADV_DVC_VAR
17810 * 'idle_cmd_done' field is set to ADV_TRUE.
17812 * Note: AdvISR() can be called when interrupts are disabled or even
17813 * when there is no hardware interrupt condition present. It will
17814 * always check for completed idle commands and microcode requests.
17815 * This is an important feature that shouldn't be changed because it
17816 * allows commands to be completed from polling mode loops.
17818 * Return:
17819 * ADV_TRUE(1) - interrupt was pending
17820 * ADV_FALSE(0) - no interrupt was pending
17822 STATIC int
17823 AdvISR(ADV_DVC_VAR *asc_dvc)
17825 AdvPortAddr iop_base;
17826 uchar int_stat;
17827 ushort target_bit;
17828 ADV_CARR_T *free_carrp;
17829 ADV_VADDR irq_next_vpa;
17830 int flags;
17831 ADV_SCSI_REQ_Q *scsiq;
17833 flags = DvcEnterCritical();
17835 iop_base = asc_dvc->iop_base;
17837 /* Reading the register clears the interrupt. */
17838 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
17840 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
17841 ADV_INTR_STATUS_INTRC)) == 0)
17843 DvcLeaveCritical(flags);
17844 return ADV_FALSE;
17848 * Notify the driver of an asynchronous microcode condition by
17849 * calling the ADV_DVC_VAR.async_callback function. The function
17850 * is passed the microcode ASC_MC_INTRB_CODE byte value.
17852 if (int_stat & ADV_INTR_STATUS_INTRB)
17854 uchar intrb_code;
17856 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
17858 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17859 asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
17861 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
17862 asc_dvc->carr_pending_cnt != 0)
17864 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
17865 if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
17867 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17872 if (asc_dvc->async_callback != 0)
17874 (*asc_dvc->async_callback)(asc_dvc, intrb_code);
17879 * Check if the IRQ stopper carrier contains a completed request.
17881 while (((irq_next_vpa =
17882 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0)
17885 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
17886 * The RISC will have set 'areq_vpa' to a virtual address.
17888 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
17889 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
17890 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
17891 * in AdvExeScsiQueue().
17893 scsiq = (ADV_SCSI_REQ_Q *)
17894 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
17897 * Request finished with good status and the queue was not
17898 * DMAed to host memory by the firmware. Set all status fields
17899 * to indicate good status.
17901 if ((irq_next_vpa & ASC_RQ_GOOD) != 0)
17903 scsiq->done_status = QD_NO_ERROR;
17904 scsiq->host_status = scsiq->scsi_status = 0;
17905 scsiq->data_cnt = 0L;
17909 * Advance the stopper pointer to the next carrier
17910 * ignoring the lower four bits. Free the previous
17911 * stopper carrier.
17913 free_carrp = asc_dvc->irq_sp;
17914 asc_dvc->irq_sp = (ADV_CARR_T *)
17915 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
17917 free_carrp->next_vpa =
17918 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
17919 asc_dvc->carr_freelist = free_carrp;
17920 asc_dvc->carr_pending_cnt--;
17922 ASC_ASSERT(scsiq != NULL);
17923 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
17926 * Clear request microcode control flag.
17928 scsiq->cntl = 0;
17931 * If the command that completed was a SCSI INQUIRY and
17932 * LUN 0 was sent the command, then process the INQUIRY
17933 * command information for the device.
17935 * Note: If data returned were either VPD or CmdDt data,
17936 * don't process the INQUIRY command information for
17937 * the device, otherwise may erroneously set *_able bits.
17939 if (scsiq->done_status == QD_NO_ERROR &&
17940 scsiq->cdb[0] == INQUIRY &&
17941 scsiq->target_lun == 0 &&
17942 (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
17943 == ADV_INQ_RTN_STD_INQUIRY_DATA)
17945 AdvInquiryHandling(asc_dvc, scsiq);
17949 * Notify the driver of the completed request by passing
17950 * the ADV_SCSI_REQ_Q pointer to its callback function.
17952 scsiq->a_flag |= ADV_SCSIQ_DONE;
17953 (*asc_dvc->isr_callback)(asc_dvc, scsiq);
17955 * Note: After the driver callback function is called, 'scsiq'
17956 * can no longer be referenced.
17958 * Fall through and continue processing other completed
17959 * requests...
17963 * Disable interrupts again in case the driver inadvertently
17964 * enabled interrupts in its callback function.
17966 * The DvcEnterCritical() return value is ignored, because
17967 * the 'flags' saved when AdvISR() was first entered will be
17968 * used to restore the interrupt flag on exit.
17970 (void) DvcEnterCritical();
17972 DvcLeaveCritical(flags);
17973 return ADV_TRUE;
17977 * Send an idle command to the chip and wait for completion.
17979 * Command completion is polled for once per microsecond.
17981 * The function can be called from anywhere including an interrupt handler.
17982 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
17983 * functions to prevent reentrancy.
17985 * Return Values:
17986 * ADV_TRUE - command completed successfully
17987 * ADV_FALSE - command failed
17988 * ADV_ERROR - command timed out
17990 STATIC int
17991 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
17992 ushort idle_cmd,
17993 ADV_DCNT idle_cmd_parameter)
17995 ulong last_int_level;
17996 int result;
17997 ADV_DCNT i, j;
17998 AdvPortAddr iop_base;
18000 last_int_level = DvcEnterCritical();
18002 iop_base = asc_dvc->iop_base;
18005 * Clear the idle command status which is set by the microcode
18006 * to a non-zero value to indicate when the command is completed.
18007 * The non-zero result is one of the IDLE_CMD_STATUS_* values
18008 * defined in a_advlib.h.
18010 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort) 0);
18013 * Write the idle command value after the idle command parameter
18014 * has been written to avoid a race condition. If the order is not
18015 * followed, the microcode may process the idle command before the
18016 * parameters have been written to LRAM.
18018 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
18019 cpu_to_le32(idle_cmd_parameter));
18020 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
18023 * Tickle the RISC to tell it to process the idle command.
18025 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
18026 if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
18029 * Clear the tickle value. In the ASC-3550 the RISC flag
18030 * command 'clr_tickle_b' does not work unless the host
18031 * value is cleared.
18033 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
18036 /* Wait for up to 100 millisecond for the idle command to timeout. */
18037 for (i = 0; i < SCSI_WAIT_100_MSEC; i++)
18039 /* Poll once each microsecond for command completion. */
18040 for (j = 0; j < SCSI_US_PER_MSEC; j++)
18042 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, result);
18043 if (result != 0)
18045 DvcLeaveCritical(last_int_level);
18046 return result;
18048 DvcDelayMicroSecond(asc_dvc, (ushort) 1);
18052 ASC_ASSERT(0); /* The idle command should never timeout. */
18053 DvcLeaveCritical(last_int_level);
18054 return ADV_ERROR;
18058 * Inquiry Information Byte 7 Handling
18060 * Handle SCSI Inquiry Command information for a device by setting
18061 * microcode operating variables that affect WDTR, SDTR, and Tag
18062 * Queuing.
18064 STATIC void
18065 AdvInquiryHandling(
18066 ADV_DVC_VAR *asc_dvc,
18067 ADV_SCSI_REQ_Q *scsiq)
18069 AdvPortAddr iop_base;
18070 uchar tid;
18071 ADV_SCSI_INQUIRY *inq;
18072 ushort tidmask;
18073 ushort cfg_word;
18076 * AdvInquiryHandling() requires up to INQUIRY information Byte 7
18077 * to be available.
18079 * If less than 8 bytes of INQUIRY information were requested or less
18080 * than 8 bytes were transferred, then return. cdb[4] is the request
18081 * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
18082 * microcode to the transfer residual count.
18085 if (scsiq->cdb[4] < 8 ||
18086 (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8)
18088 return;
18091 iop_base = asc_dvc->iop_base;
18092 tid = scsiq->target_id;
18094 inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr;
18097 * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
18099 if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2)
18101 return;
18102 } else
18105 * INQUIRY Byte 7 Handling
18107 * Use a device's INQUIRY byte 7 to determine whether it
18108 * supports WDTR, SDTR, and Tag Queuing. If the feature
18109 * is enabled in the EEPROM and the device supports the
18110 * feature, then enable it in the microcode.
18113 tidmask = ADV_TID_TO_TIDMASK(tid);
18116 * Wide Transfers
18118 * If the EEPROM enabled WDTR for the device and the device
18119 * supports wide bus (16 bit) transfers, then turn on the
18120 * device's 'wdtr_able' bit and write the new value to the
18121 * microcode.
18123 if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq))
18125 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
18126 if ((cfg_word & tidmask) == 0)
18128 cfg_word |= tidmask;
18129 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
18132 * Clear the microcode "SDTR negotiation" and "WDTR
18133 * negotiation" done indicators for the target to cause
18134 * it to negotiate with the new setting set above.
18135 * WDTR when accepted causes the target to enter
18136 * asynchronous mode, so SDTR must be negotiated.
18138 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18139 cfg_word &= ~tidmask;
18140 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18141 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
18142 cfg_word &= ~tidmask;
18143 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
18148 * Synchronous Transfers
18150 * If the EEPROM enabled SDTR for the device and the device
18151 * supports synchronous transfers, then turn on the device's
18152 * 'sdtr_able' bit. Write the new value to the microcode.
18154 if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq))
18156 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
18157 if ((cfg_word & tidmask) == 0)
18159 cfg_word |= tidmask;
18160 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
18163 * Clear the microcode "SDTR negotiation" done indicator
18164 * for the target to cause it to negotiate with the new
18165 * setting set above.
18167 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18168 cfg_word &= ~tidmask;
18169 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18173 * If the Inquiry data included enough space for the SPI-3
18174 * Clocking field, then check if DT mode is supported.
18176 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 &&
18177 (scsiq->cdb[4] >= 57 ||
18178 (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57))
18181 * PPR (Parallel Protocol Request) Capable
18183 * If the device supports DT mode, then it must be PPR capable.
18184 * The PPR message will be used in place of the SDTR and WDTR
18185 * messages to negotiate synchronous speed and offset, transfer
18186 * width, and protocol options.
18188 if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY)
18190 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, asc_dvc->ppr_able);
18191 asc_dvc->ppr_able |= tidmask;
18192 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, asc_dvc->ppr_able);
18197 * If the EEPROM enabled Tag Queuing for the device and the
18198 * device supports Tag Queueing, then turn on the device's
18199 * 'tagqng_enable' bit in the microcode and set the microcode
18200 * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
18201 * value.
18203 * Tag Queuing is disabled for the BIOS which runs in polled
18204 * mode and would see no benefit from Tag Queuing. Also by
18205 * disabling Tag Queuing in the BIOS devices with Tag Queuing
18206 * bugs will at least work with the BIOS.
18208 if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq))
18210 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
18211 cfg_word |= tidmask;
18212 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
18214 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
18215 asc_dvc->max_dvc_qng);
18219 MODULE_LICENSE("Dual BSD/GPL");
18221 #ifdef CONFIG_PCI
18222 /* PCI Devices supported by this driver */
18223 static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
18224 { PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
18225 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18226 { PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
18227 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18228 { PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
18229 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18230 { PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
18231 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18232 { PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
18233 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18234 { PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
18235 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18238 MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);
18239 #endif /* CONFIG_PCI */