[TCP]: Fix oops caused by tcp_v4_md5_do_del
[linux-2.6/zen-sources.git] / drivers / scsi / advansys.c
blob2b344356a29e997cd381c5697a3c82badb6c04a2
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 (check_region(iop, ASC_IOADR_GAP) != 0) {
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 asc_ioport[ioport] = 0;
4417 goto ioport_try_again;
4418 } else {
4420 * If this isn't an ISA board, then it must be
4421 * a VL board. If currently looking an ISA
4422 * board is being looked for then try for
4423 * another ISA board in 'asc_ioport'.
4425 if (asc_bus[bus] == ASC_IS_ISA &&
4426 (AscGetChipVersion(iop, ASC_IS_ISA) &
4427 ASC_CHIP_VER_ISA_BIT) == 0) {
4429 * Don't clear 'asc_ioport[ioport]'. Try
4430 * this board again for VL. Increment
4431 * 'ioport' past this board.
4433 ioport++;
4434 goto ioport_try_again;
4438 * This board appears good, don't try the I/O port
4439 * again by clearing its value. Increment 'ioport'
4440 * for the next iteration.
4442 asc_ioport[ioport++] = 0;
4445 #endif /* CONFIG_ISA */
4446 break;
4448 case ASC_IS_EISA:
4449 #ifdef CONFIG_ISA
4450 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4451 #endif /* CONFIG_ISA */
4452 break;
4454 case ASC_IS_PCI:
4455 #ifdef CONFIG_PCI
4456 if (pci_init_search == 0) {
4457 int i, j;
4459 pci_init_search = 1;
4461 /* Find all PCI cards. */
4462 while (pci_device_id_cnt < ASC_PCI_DEVICE_ID_CNT) {
4463 if ((pci_devp = pci_find_device(PCI_VENDOR_ID_ASP,
4464 pci_device_id[pci_device_id_cnt], pci_devp)) ==
4465 NULL) {
4466 pci_device_id_cnt++;
4467 } else {
4468 if (pci_enable_device(pci_devp) == 0) {
4469 pci_devicep[pci_card_cnt_max++] = pci_devp;
4475 * Sort PCI cards in ascending order by PCI Bus, Slot,
4476 * and Device Number.
4478 for (i = 0; i < pci_card_cnt_max - 1; i++)
4480 for (j = i + 1; j < pci_card_cnt_max; j++) {
4481 if ((pci_devicep[j]->bus->number <
4482 pci_devicep[i]->bus->number) ||
4483 ((pci_devicep[j]->bus->number ==
4484 pci_devicep[i]->bus->number) &&
4485 (pci_devicep[j]->devfn <
4486 pci_devicep[i]->devfn))) {
4487 pci_devp = pci_devicep[i];
4488 pci_devicep[i] = pci_devicep[j];
4489 pci_devicep[j] = pci_devp;
4494 pci_card_cnt = 0;
4495 } else {
4496 pci_card_cnt++;
4499 if (pci_card_cnt == pci_card_cnt_max) {
4500 iop = 0;
4501 } else {
4502 pci_devp = pci_devicep[pci_card_cnt];
4504 ASC_DBG2(2,
4505 "advansys_detect: devfn %d, bus number %d\n",
4506 pci_devp->devfn, pci_devp->bus->number);
4507 iop = pci_resource_start(pci_devp, 0);
4508 ASC_DBG2(1,
4509 "advansys_detect: vendorID %X, deviceID %X\n",
4510 pci_devp->vendor, pci_devp->device);
4511 ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
4512 iop, pci_devp->irq);
4514 if(pci_devp)
4515 dev = &pci_devp->dev;
4517 #endif /* CONFIG_PCI */
4518 break;
4520 default:
4521 ASC_PRINT1("advansys_detect: unknown bus type: %d\n",
4522 asc_bus[bus]);
4523 break;
4525 ASC_DBG1(1, "advansys_detect: iop 0x%x\n", iop);
4528 * Adapter not found, try next bus type.
4530 if (iop == 0) {
4531 break;
4535 * Adapter found.
4537 * Register the adapter, get its configuration, and
4538 * initialize it.
4540 ASC_DBG(2, "advansys_detect: scsi_register()\n");
4541 shp = scsi_register(tpnt, sizeof(asc_board_t));
4543 if (shp == NULL) {
4544 continue;
4547 /* Save a pointer to the Scsi_Host of each board found. */
4548 asc_host[asc_board_count++] = shp;
4550 /* Initialize private per board data */
4551 boardp = ASC_BOARDP(shp);
4552 memset(boardp, 0, sizeof(asc_board_t));
4553 boardp->id = asc_board_count - 1;
4555 /* Initialize spinlock. */
4556 spin_lock_init(&boardp->lock);
4559 * Handle both narrow and wide boards.
4561 * If a Wide board was detected, set the board structure
4562 * wide board flag. Set-up the board structure based on
4563 * the board type.
4565 #ifdef CONFIG_PCI
4566 if (asc_bus[bus] == ASC_IS_PCI &&
4567 (pci_devp->device == PCI_DEVICE_ID_ASP_ABP940UW ||
4568 pci_devp->device == PCI_DEVICE_ID_38C0800_REV1 ||
4569 pci_devp->device == PCI_DEVICE_ID_38C1600_REV1))
4571 boardp->flags |= ASC_IS_WIDE_BOARD;
4573 #endif /* CONFIG_PCI */
4575 if (ASC_NARROW_BOARD(boardp)) {
4576 ASC_DBG(1, "advansys_detect: narrow board\n");
4577 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4578 asc_dvc_varp->bus_type = asc_bus[bus];
4579 asc_dvc_varp->drv_ptr = boardp;
4580 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
4581 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
4582 asc_dvc_varp->iop_base = iop;
4583 asc_dvc_varp->isr_callback = asc_isr_callback;
4584 } else {
4585 ASC_DBG(1, "advansys_detect: wide board\n");
4586 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4587 adv_dvc_varp->drv_ptr = boardp;
4588 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
4589 adv_dvc_varp->isr_callback = adv_isr_callback;
4590 adv_dvc_varp->async_callback = adv_async_callback;
4591 #ifdef CONFIG_PCI
4592 if (pci_devp->device == PCI_DEVICE_ID_ASP_ABP940UW)
4594 ASC_DBG(1, "advansys_detect: ASC-3550\n");
4595 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
4596 } else if (pci_devp->device == PCI_DEVICE_ID_38C0800_REV1)
4598 ASC_DBG(1, "advansys_detect: ASC-38C0800\n");
4599 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
4600 } else
4602 ASC_DBG(1, "advansys_detect: ASC-38C1600\n");
4603 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
4605 #endif /* CONFIG_PCI */
4608 * Map the board's registers into virtual memory for
4609 * PCI slave access. Only memory accesses are used to
4610 * access the board's registers.
4612 * Note: The PCI register base address is not always
4613 * page aligned, but the address passed to ioremap()
4614 * must be page aligned. It is guaranteed that the
4615 * PCI register base address will not cross a page
4616 * boundary.
4618 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
4620 iolen = ADV_3550_IOLEN;
4621 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
4623 iolen = ADV_38C0800_IOLEN;
4624 } else
4626 iolen = ADV_38C1600_IOLEN;
4628 #ifdef CONFIG_PCI
4629 pci_memory_address = pci_resource_start(pci_devp, 1);
4630 ASC_DBG1(1, "advansys_detect: pci_memory_address: 0x%lx\n",
4631 (ulong) pci_memory_address);
4632 if ((boardp->ioremap_addr =
4633 ioremap(pci_memory_address & PAGE_MASK,
4634 PAGE_SIZE)) == 0) {
4635 ASC_PRINT3(
4636 "advansys_detect: board %d: ioremap(%x, %d) returned NULL\n",
4637 boardp->id, pci_memory_address, iolen);
4638 scsi_unregister(shp);
4639 asc_board_count--;
4640 continue;
4642 ASC_DBG1(1, "advansys_detect: ioremap_addr: 0x%lx\n",
4643 (ulong) boardp->ioremap_addr);
4644 adv_dvc_varp->iop_base = (AdvPortAddr)
4645 (boardp->ioremap_addr +
4646 (pci_memory_address - (pci_memory_address & PAGE_MASK)));
4647 ASC_DBG1(1, "advansys_detect: iop_base: 0x%lx\n",
4648 adv_dvc_varp->iop_base);
4649 #endif /* CONFIG_PCI */
4652 * Even though it isn't used to access wide boards, other
4653 * than for the debug line below, save I/O Port address so
4654 * that it can be reported.
4656 boardp->ioport = iop;
4658 ASC_DBG2(1,
4659 "advansys_detect: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
4660 (ushort) inp(iop + 1), (ushort) inpw(iop));
4663 #ifdef CONFIG_PROC_FS
4665 * Allocate buffer for printing information from
4666 * /proc/scsi/advansys/[0...].
4668 if ((boardp->prtbuf =
4669 kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) {
4670 ASC_PRINT3(
4671 "advansys_detect: board %d: kmalloc(%d, %d) returned NULL\n",
4672 boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC);
4673 scsi_unregister(shp);
4674 asc_board_count--;
4675 continue;
4677 #endif /* CONFIG_PROC_FS */
4679 if (ASC_NARROW_BOARD(boardp)) {
4680 asc_dvc_varp->cfg->dev = dev;
4682 * Set the board bus type and PCI IRQ before
4683 * calling AscInitGetConfig().
4685 switch (asc_dvc_varp->bus_type) {
4686 #ifdef CONFIG_ISA
4687 case ASC_IS_ISA:
4688 shp->unchecked_isa_dma = TRUE;
4689 share_irq = FALSE;
4690 break;
4691 case ASC_IS_VL:
4692 shp->unchecked_isa_dma = FALSE;
4693 share_irq = FALSE;
4694 break;
4695 case ASC_IS_EISA:
4696 shp->unchecked_isa_dma = FALSE;
4697 share_irq = TRUE;
4698 break;
4699 #endif /* CONFIG_ISA */
4700 #ifdef CONFIG_PCI
4701 case ASC_IS_PCI:
4702 shp->irq = asc_dvc_varp->irq_no = pci_devp->irq;
4703 asc_dvc_varp->cfg->pci_slot_info =
4704 ASC_PCI_MKID(pci_devp->bus->number,
4705 PCI_SLOT(pci_devp->devfn),
4706 PCI_FUNC(pci_devp->devfn));
4707 shp->unchecked_isa_dma = FALSE;
4708 share_irq = TRUE;
4709 break;
4710 #endif /* CONFIG_PCI */
4711 default:
4712 ASC_PRINT2(
4713 "advansys_detect: board %d: unknown adapter type: %d\n",
4714 boardp->id, asc_dvc_varp->bus_type);
4715 shp->unchecked_isa_dma = TRUE;
4716 share_irq = FALSE;
4717 break;
4719 } else {
4720 adv_dvc_varp->cfg->dev = dev;
4722 * For Wide boards set PCI information before calling
4723 * AdvInitGetConfig().
4725 #ifdef CONFIG_PCI
4726 shp->irq = adv_dvc_varp->irq_no = pci_devp->irq;
4727 adv_dvc_varp->cfg->pci_slot_info =
4728 ASC_PCI_MKID(pci_devp->bus->number,
4729 PCI_SLOT(pci_devp->devfn),
4730 PCI_FUNC(pci_devp->devfn));
4731 shp->unchecked_isa_dma = FALSE;
4732 share_irq = TRUE;
4733 #endif /* CONFIG_PCI */
4737 * Read the board configuration.
4739 if (ASC_NARROW_BOARD(boardp)) {
4741 * NOTE: AscInitGetConfig() may change the board's
4742 * bus_type value. The asc_bus[bus] value should no
4743 * longer be used. If the bus_type field must be
4744 * referenced only use the bit-wise AND operator "&".
4746 ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
4747 switch(ret = AscInitGetConfig(asc_dvc_varp)) {
4748 case 0: /* No error */
4749 break;
4750 case ASC_WARN_IO_PORT_ROTATE:
4751 ASC_PRINT1(
4752 "AscInitGetConfig: board %d: I/O port address modified\n",
4753 boardp->id);
4754 break;
4755 case ASC_WARN_AUTO_CONFIG:
4756 ASC_PRINT1(
4757 "AscInitGetConfig: board %d: I/O port increment switch enabled\n",
4758 boardp->id);
4759 break;
4760 case ASC_WARN_EEPROM_CHKSUM:
4761 ASC_PRINT1(
4762 "AscInitGetConfig: board %d: EEPROM checksum error\n",
4763 boardp->id);
4764 break;
4765 case ASC_WARN_IRQ_MODIFIED:
4766 ASC_PRINT1(
4767 "AscInitGetConfig: board %d: IRQ modified\n",
4768 boardp->id);
4769 break;
4770 case ASC_WARN_CMD_QNG_CONFLICT:
4771 ASC_PRINT1(
4772 "AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
4773 boardp->id);
4774 break;
4775 default:
4776 ASC_PRINT2(
4777 "AscInitGetConfig: board %d: unknown warning: 0x%x\n",
4778 boardp->id, ret);
4779 break;
4781 if ((err_code = asc_dvc_varp->err_code) != 0) {
4782 ASC_PRINT3(
4783 "AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
4784 boardp->id, asc_dvc_varp->init_state,
4785 asc_dvc_varp->err_code);
4787 } else {
4788 ASC_DBG(2, "advansys_detect: AdvInitGetConfig()\n");
4789 if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
4790 ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n",
4791 boardp->id, ret);
4793 if ((err_code = adv_dvc_varp->err_code) != 0) {
4794 ASC_PRINT2(
4795 "AdvInitGetConfig: board %d error: err_code 0x%x\n",
4796 boardp->id, adv_dvc_varp->err_code);
4800 if (err_code != 0) {
4801 #ifdef CONFIG_PROC_FS
4802 kfree(boardp->prtbuf);
4803 #endif /* CONFIG_PROC_FS */
4804 scsi_unregister(shp);
4805 asc_board_count--;
4806 continue;
4810 * Save the EEPROM configuration so that it can be displayed
4811 * from /proc/scsi/advansys/[0...].
4813 if (ASC_NARROW_BOARD(boardp)) {
4815 ASCEEP_CONFIG *ep;
4818 * Set the adapter's target id bit in the 'init_tidmask' field.
4820 boardp->init_tidmask |=
4821 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
4824 * Save EEPROM settings for the board.
4826 ep = &boardp->eep_config.asc_eep;
4828 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
4829 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
4830 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
4831 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
4832 ep->start_motor = asc_dvc_varp->start_motor;
4833 ep->cntl = asc_dvc_varp->dvc_cntl;
4834 ep->no_scam = asc_dvc_varp->no_scam;
4835 ep->max_total_qng = asc_dvc_varp->max_total_qng;
4836 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
4837 /* 'max_tag_qng' is set to the same value for every device. */
4838 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
4839 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
4840 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
4841 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
4842 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
4843 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
4844 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
4847 * Modify board configuration.
4849 ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n");
4850 switch (ret = AscInitSetConfig(asc_dvc_varp)) {
4851 case 0: /* No error. */
4852 break;
4853 case ASC_WARN_IO_PORT_ROTATE:
4854 ASC_PRINT1(
4855 "AscInitSetConfig: board %d: I/O port address modified\n",
4856 boardp->id);
4857 break;
4858 case ASC_WARN_AUTO_CONFIG:
4859 ASC_PRINT1(
4860 "AscInitSetConfig: board %d: I/O port increment switch enabled\n",
4861 boardp->id);
4862 break;
4863 case ASC_WARN_EEPROM_CHKSUM:
4864 ASC_PRINT1(
4865 "AscInitSetConfig: board %d: EEPROM checksum error\n",
4866 boardp->id);
4867 break;
4868 case ASC_WARN_IRQ_MODIFIED:
4869 ASC_PRINT1(
4870 "AscInitSetConfig: board %d: IRQ modified\n",
4871 boardp->id);
4872 break;
4873 case ASC_WARN_CMD_QNG_CONFLICT:
4874 ASC_PRINT1(
4875 "AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
4876 boardp->id);
4877 break;
4878 default:
4879 ASC_PRINT2(
4880 "AscInitSetConfig: board %d: unknown warning: 0x%x\n",
4881 boardp->id, ret);
4882 break;
4884 if (asc_dvc_varp->err_code != 0) {
4885 ASC_PRINT3(
4886 "AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
4887 boardp->id, asc_dvc_varp->init_state,
4888 asc_dvc_varp->err_code);
4889 #ifdef CONFIG_PROC_FS
4890 kfree(boardp->prtbuf);
4891 #endif /* CONFIG_PROC_FS */
4892 scsi_unregister(shp);
4893 asc_board_count--;
4894 continue;
4898 * Finish initializing the 'Scsi_Host' structure.
4900 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
4901 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
4902 shp->irq = asc_dvc_varp->irq_no;
4904 } else {
4905 ADVEEP_3550_CONFIG *ep_3550;
4906 ADVEEP_38C0800_CONFIG *ep_38C0800;
4907 ADVEEP_38C1600_CONFIG *ep_38C1600;
4910 * Save Wide EEP Configuration Information.
4912 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
4914 ep_3550 = &boardp->eep_config.adv_3550_eep;
4916 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
4917 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
4918 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
4919 ep_3550->termination = adv_dvc_varp->cfg->termination;
4920 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
4921 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
4922 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
4923 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
4924 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
4925 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
4926 ep_3550->start_motor = adv_dvc_varp->start_motor;
4927 ep_3550->scsi_reset_delay = adv_dvc_varp->scsi_reset_wait;
4928 ep_3550->serial_number_word1 =
4929 adv_dvc_varp->cfg->serial1;
4930 ep_3550->serial_number_word2 =
4931 adv_dvc_varp->cfg->serial2;
4932 ep_3550->serial_number_word3 =
4933 adv_dvc_varp->cfg->serial3;
4934 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
4936 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
4938 ep_38C0800->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
4939 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
4940 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
4941 ep_38C0800->termination_lvd =
4942 adv_dvc_varp->cfg->termination;
4943 ep_38C0800->disc_enable = adv_dvc_varp->cfg->disc_enable;
4944 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
4945 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
4946 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
4947 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
4948 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
4949 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
4950 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
4951 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
4952 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
4953 ep_38C0800->scsi_reset_delay =
4954 adv_dvc_varp->scsi_reset_wait;
4955 ep_38C0800->serial_number_word1 =
4956 adv_dvc_varp->cfg->serial1;
4957 ep_38C0800->serial_number_word2 =
4958 adv_dvc_varp->cfg->serial2;
4959 ep_38C0800->serial_number_word3 =
4960 adv_dvc_varp->cfg->serial3;
4961 } else
4963 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
4965 ep_38C1600->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
4966 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
4967 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
4968 ep_38C1600->termination_lvd =
4969 adv_dvc_varp->cfg->termination;
4970 ep_38C1600->disc_enable = adv_dvc_varp->cfg->disc_enable;
4971 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
4972 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
4973 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
4974 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
4975 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
4976 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
4977 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
4978 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
4979 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
4980 ep_38C1600->scsi_reset_delay =
4981 adv_dvc_varp->scsi_reset_wait;
4982 ep_38C1600->serial_number_word1 =
4983 adv_dvc_varp->cfg->serial1;
4984 ep_38C1600->serial_number_word2 =
4985 adv_dvc_varp->cfg->serial2;
4986 ep_38C1600->serial_number_word3 =
4987 adv_dvc_varp->cfg->serial3;
4991 * Set the adapter's target id bit in the 'init_tidmask' field.
4993 boardp->init_tidmask |=
4994 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
4997 * Finish initializing the 'Scsi_Host' structure.
4999 shp->irq = adv_dvc_varp->irq_no;
5003 * Channels are numbered beginning with 0. For AdvanSys one host
5004 * structure supports one channel. Multi-channel boards have a
5005 * separate host structure for each channel.
5007 shp->max_channel = 0;
5008 if (ASC_NARROW_BOARD(boardp)) {
5009 shp->max_id = ASC_MAX_TID + 1;
5010 shp->max_lun = ASC_MAX_LUN + 1;
5012 shp->io_port = asc_dvc_varp->iop_base;
5013 boardp->asc_n_io_port = ASC_IOADR_GAP;
5014 shp->this_id = asc_dvc_varp->cfg->chip_scsi_id;
5016 /* Set maximum number of queues the adapter can handle. */
5017 shp->can_queue = asc_dvc_varp->max_total_qng;
5018 } else {
5019 shp->max_id = ADV_MAX_TID + 1;
5020 shp->max_lun = ADV_MAX_LUN + 1;
5023 * Save the I/O Port address and length even though
5024 * I/O ports are not used to access Wide boards.
5025 * Instead the Wide boards are accessed with
5026 * PCI Memory Mapped I/O.
5028 shp->io_port = iop;
5029 boardp->asc_n_io_port = iolen;
5031 shp->this_id = adv_dvc_varp->chip_scsi_id;
5033 /* Set maximum number of queues the adapter can handle. */
5034 shp->can_queue = adv_dvc_varp->max_host_qng;
5038 * 'n_io_port' currently is one byte.
5040 * Set a value to 'n_io_port', but never referenced it because
5041 * it may be truncated.
5043 shp->n_io_port = boardp->asc_n_io_port <= 255 ?
5044 boardp->asc_n_io_port : 255;
5047 * Following v1.3.89, 'cmd_per_lun' is no longer needed
5048 * and should be set to zero.
5050 * But because of a bug introduced in v1.3.89 if the driver is
5051 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
5052 * SCSI function 'allocate_device' will panic. To allow the driver
5053 * to work as a module in these kernels set 'cmd_per_lun' to 1.
5055 * Note: This is wrong. cmd_per_lun should be set to the depth
5056 * you want on untagged devices always.
5057 #ifdef MODULE
5059 shp->cmd_per_lun = 1;
5060 /* #else
5061 shp->cmd_per_lun = 0;
5062 #endif */
5065 * Set the maximum number of scatter-gather elements the
5066 * adapter can handle.
5068 if (ASC_NARROW_BOARD(boardp)) {
5070 * Allow two commands with 'sg_tablesize' scatter-gather
5071 * elements to be executed simultaneously. This value is
5072 * the theoretical hardware limit. It may be decreased
5073 * below.
5075 shp->sg_tablesize =
5076 (((asc_dvc_varp->max_total_qng - 2) / 2) *
5077 ASC_SG_LIST_PER_Q) + 1;
5078 } else {
5079 shp->sg_tablesize = ADV_MAX_SG_LIST;
5083 * The value of 'sg_tablesize' can not exceed the SCSI
5084 * mid-level driver definition of SG_ALL. SG_ALL also
5085 * must not be exceeded, because it is used to define the
5086 * size of the scatter-gather table in 'struct asc_sg_head'.
5088 if (shp->sg_tablesize > SG_ALL) {
5089 shp->sg_tablesize = SG_ALL;
5092 ASC_DBG1(1, "advansys_detect: sg_tablesize: %d\n",
5093 shp->sg_tablesize);
5095 /* BIOS start address. */
5096 if (ASC_NARROW_BOARD(boardp)) {
5097 shp->base =
5098 ((ulong) AscGetChipBiosAddress(
5099 asc_dvc_varp->iop_base,
5100 asc_dvc_varp->bus_type));
5101 } else {
5103 * Fill-in BIOS board variables. The Wide BIOS saves
5104 * information in LRAM that is used by the driver.
5106 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_SIGNATURE,
5107 boardp->bios_signature);
5108 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_VERSION,
5109 boardp->bios_version);
5110 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODESEG,
5111 boardp->bios_codeseg);
5112 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODELEN,
5113 boardp->bios_codelen);
5115 ASC_DBG2(1,
5116 "advansys_detect: bios_signature 0x%x, bios_version 0x%x\n",
5117 boardp->bios_signature, boardp->bios_version);
5119 ASC_DBG2(1,
5120 "advansys_detect: bios_codeseg 0x%x, bios_codelen 0x%x\n",
5121 boardp->bios_codeseg, boardp->bios_codelen);
5124 * If the BIOS saved a valid signature, then fill in
5125 * the BIOS code segment base address.
5127 if (boardp->bios_signature == 0x55AA) {
5129 * Convert x86 realmode code segment to a linear
5130 * address by shifting left 4.
5132 shp->base = ((ulong) boardp->bios_codeseg << 4);
5133 } else {
5134 shp->base = 0;
5139 * Register Board Resources - I/O Port, DMA, IRQ
5143 * Register I/O port range.
5145 * For Wide boards the I/O ports are not used to access
5146 * the board, but request the region anyway.
5148 * 'shp->n_io_port' is not referenced, because it may be truncated.
5150 ASC_DBG2(2,
5151 "advansys_detect: request_region port 0x%lx, len 0x%x\n",
5152 (ulong) shp->io_port, boardp->asc_n_io_port);
5153 if (request_region(shp->io_port, boardp->asc_n_io_port,
5154 "advansys") == NULL) {
5155 ASC_PRINT3(
5156 "advansys_detect: board %d: request_region() failed, port 0x%lx, len 0x%x\n",
5157 boardp->id, (ulong) shp->io_port, boardp->asc_n_io_port);
5158 #ifdef CONFIG_PROC_FS
5159 kfree(boardp->prtbuf);
5160 #endif /* CONFIG_PROC_FS */
5161 scsi_unregister(shp);
5162 asc_board_count--;
5163 continue;
5166 /* Register DMA Channel for Narrow boards. */
5167 shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
5168 #ifdef CONFIG_ISA
5169 if (ASC_NARROW_BOARD(boardp)) {
5170 /* Register DMA channel for ISA bus. */
5171 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5172 shp->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
5173 if ((ret =
5174 request_dma(shp->dma_channel, "advansys")) != 0) {
5175 ASC_PRINT3(
5176 "advansys_detect: board %d: request_dma() %d failed %d\n",
5177 boardp->id, shp->dma_channel, ret);
5178 release_region(shp->io_port, boardp->asc_n_io_port);
5179 #ifdef CONFIG_PROC_FS
5180 kfree(boardp->prtbuf);
5181 #endif /* CONFIG_PROC_FS */
5182 scsi_unregister(shp);
5183 asc_board_count--;
5184 continue;
5186 AscEnableIsaDma(shp->dma_channel);
5189 #endif /* CONFIG_ISA */
5191 /* Register IRQ Number. */
5192 ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
5194 * If request_irq() fails with the IRQF_DISABLED flag set,
5195 * then try again without the IRQF_DISABLED flag set. This
5196 * allows IRQ sharing to work even with other drivers that
5197 * do not set the IRQF_DISABLED flag.
5199 * If IRQF_DISABLED is not set, then interrupts are enabled
5200 * before the driver interrupt function is called.
5202 if (((ret = request_irq(shp->irq, advansys_interrupt,
5203 IRQF_DISABLED | (share_irq == TRUE ? IRQF_SHARED : 0),
5204 "advansys", boardp)) != 0) &&
5205 ((ret = request_irq(shp->irq, advansys_interrupt,
5206 (share_irq == TRUE ? IRQF_SHARED : 0),
5207 "advansys", boardp)) != 0))
5209 if (ret == -EBUSY) {
5210 ASC_PRINT2(
5211 "advansys_detect: board %d: request_irq(): IRQ 0x%x already in use.\n",
5212 boardp->id, shp->irq);
5213 } else if (ret == -EINVAL) {
5214 ASC_PRINT2(
5215 "advansys_detect: board %d: request_irq(): IRQ 0x%x not valid.\n",
5216 boardp->id, shp->irq);
5217 } else {
5218 ASC_PRINT3(
5219 "advansys_detect: board %d: request_irq(): IRQ 0x%x failed with %d\n",
5220 boardp->id, shp->irq, ret);
5222 release_region(shp->io_port, boardp->asc_n_io_port);
5223 iounmap(boardp->ioremap_addr);
5224 if (shp->dma_channel != NO_ISA_DMA) {
5225 free_dma(shp->dma_channel);
5227 #ifdef CONFIG_PROC_FS
5228 kfree(boardp->prtbuf);
5229 #endif /* CONFIG_PROC_FS */
5230 scsi_unregister(shp);
5231 asc_board_count--;
5232 continue;
5236 * Initialize board RISC chip and enable interrupts.
5238 if (ASC_NARROW_BOARD(boardp)) {
5239 ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n");
5240 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
5241 err_code = asc_dvc_varp->err_code;
5243 if (warn_code || err_code) {
5244 ASC_PRINT4(
5245 "advansys_detect: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
5246 boardp->id, asc_dvc_varp->init_state,
5247 warn_code, err_code);
5249 } else {
5250 ADV_CARR_T *carrp;
5251 int req_cnt = 0;
5252 adv_req_t *reqp = NULL;
5253 int sg_cnt = 0;
5256 * Allocate buffer carrier structures. The total size
5257 * is about 4 KB, so allocate all at once.
5259 carrp =
5260 (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC);
5261 ASC_DBG1(1, "advansys_detect: carrp 0x%lx\n", (ulong) carrp);
5263 if (carrp == NULL) {
5264 goto kmalloc_error;
5268 * Allocate up to 'max_host_qng' request structures for
5269 * the Wide board. The total size is about 16 KB, so
5270 * allocate all at once. If the allocation fails decrement
5271 * and try again.
5273 for (req_cnt = adv_dvc_varp->max_host_qng;
5274 req_cnt > 0; req_cnt--) {
5276 reqp = (adv_req_t *)
5277 kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC);
5279 ASC_DBG3(1,
5280 "advansys_detect: reqp 0x%lx, req_cnt %d, bytes %lu\n",
5281 (ulong) reqp, req_cnt,
5282 (ulong) sizeof(adv_req_t) * req_cnt);
5284 if (reqp != NULL) {
5285 break;
5288 if (reqp == NULL)
5290 goto kmalloc_error;
5294 * Allocate up to ADV_TOT_SG_BLOCK request structures for
5295 * the Wide board. Each structure is about 136 bytes.
5297 boardp->adv_sgblkp = NULL;
5298 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
5300 sgp = (adv_sgblk_t *)
5301 kmalloc(sizeof(adv_sgblk_t), GFP_ATOMIC);
5303 if (sgp == NULL) {
5304 break;
5307 sgp->next_sgblkp = boardp->adv_sgblkp;
5308 boardp->adv_sgblkp = sgp;
5311 ASC_DBG3(1,
5312 "advansys_detect: sg_cnt %d * %u = %u bytes\n",
5313 sg_cnt, sizeof(adv_sgblk_t),
5314 (unsigned) (sizeof(adv_sgblk_t) * sg_cnt));
5317 * If no request structures or scatter-gather structures could
5318 * be allocated, then return an error. Otherwise continue with
5319 * initialization.
5321 kmalloc_error:
5322 if (carrp == NULL)
5324 ASC_PRINT1(
5325 "advansys_detect: board %d error: failed to kmalloc() carrier buffer.\n",
5326 boardp->id);
5327 err_code = ADV_ERROR;
5328 } else if (reqp == NULL) {
5329 kfree(carrp);
5330 ASC_PRINT1(
5331 "advansys_detect: board %d error: failed to kmalloc() adv_req_t buffer.\n",
5332 boardp->id);
5333 err_code = ADV_ERROR;
5334 } else if (boardp->adv_sgblkp == NULL) {
5335 kfree(carrp);
5336 kfree(reqp);
5337 ASC_PRINT1(
5338 "advansys_detect: board %d error: failed to kmalloc() adv_sgblk_t buffers.\n",
5339 boardp->id);
5340 err_code = ADV_ERROR;
5341 } else {
5343 /* Save carrier buffer pointer. */
5344 boardp->orig_carrp = carrp;
5347 * Save original pointer for kfree() in case the
5348 * driver is built as a module and can be unloaded.
5350 boardp->orig_reqp = reqp;
5352 adv_dvc_varp->carrier_buf = carrp;
5355 * Point 'adv_reqp' to the request structures and
5356 * link them together.
5358 req_cnt--;
5359 reqp[req_cnt].next_reqp = NULL;
5360 for (; req_cnt > 0; req_cnt--) {
5361 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
5363 boardp->adv_reqp = &reqp[0];
5365 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5367 ASC_DBG(2,
5368 "advansys_detect: AdvInitAsc3550Driver()\n");
5369 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
5370 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5371 ASC_DBG(2,
5372 "advansys_detect: AdvInitAsc38C0800Driver()\n");
5373 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
5374 } else {
5375 ASC_DBG(2,
5376 "advansys_detect: AdvInitAsc38C1600Driver()\n");
5377 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
5379 err_code = adv_dvc_varp->err_code;
5381 if (warn_code || err_code) {
5382 ASC_PRINT3(
5383 "advansys_detect: board %d error: warn 0x%x, error 0x%x\n",
5384 boardp->id, warn_code, err_code);
5389 if (err_code != 0) {
5390 release_region(shp->io_port, boardp->asc_n_io_port);
5391 if (ASC_WIDE_BOARD(boardp)) {
5392 iounmap(boardp->ioremap_addr);
5393 kfree(boardp->orig_carrp);
5394 boardp->orig_carrp = NULL;
5395 if (boardp->orig_reqp) {
5396 kfree(boardp->orig_reqp);
5397 boardp->orig_reqp = boardp->adv_reqp = NULL;
5399 while ((sgp = boardp->adv_sgblkp) != NULL)
5401 boardp->adv_sgblkp = sgp->next_sgblkp;
5402 kfree(sgp);
5405 if (shp->dma_channel != NO_ISA_DMA) {
5406 free_dma(shp->dma_channel);
5408 #ifdef CONFIG_PROC_FS
5409 kfree(boardp->prtbuf);
5410 #endif /* CONFIG_PROC_FS */
5411 free_irq(shp->irq, boardp);
5412 scsi_unregister(shp);
5413 asc_board_count--;
5414 continue;
5416 ASC_DBG_PRT_SCSI_HOST(2, shp);
5420 ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count);
5421 return asc_board_count;
5425 * advansys_release()
5427 * Release resources allocated for a single AdvanSys adapter.
5430 advansys_release(struct Scsi_Host *shp)
5432 asc_board_t *boardp;
5434 ASC_DBG(1, "advansys_release: begin\n");
5435 boardp = ASC_BOARDP(shp);
5436 free_irq(shp->irq, boardp);
5437 if (shp->dma_channel != NO_ISA_DMA) {
5438 ASC_DBG(1, "advansys_release: free_dma()\n");
5439 free_dma(shp->dma_channel);
5441 release_region(shp->io_port, boardp->asc_n_io_port);
5442 if (ASC_WIDE_BOARD(boardp)) {
5443 adv_sgblk_t *sgp = NULL;
5445 iounmap(boardp->ioremap_addr);
5446 kfree(boardp->orig_carrp);
5447 boardp->orig_carrp = NULL;
5448 if (boardp->orig_reqp) {
5449 kfree(boardp->orig_reqp);
5450 boardp->orig_reqp = boardp->adv_reqp = NULL;
5452 while ((sgp = boardp->adv_sgblkp) != NULL)
5454 boardp->adv_sgblkp = sgp->next_sgblkp;
5455 kfree(sgp);
5458 #ifdef CONFIG_PROC_FS
5459 ASC_ASSERT(boardp->prtbuf != NULL);
5460 kfree(boardp->prtbuf);
5461 #endif /* CONFIG_PROC_FS */
5462 scsi_unregister(shp);
5463 ASC_DBG(1, "advansys_release: end\n");
5464 return 0;
5468 * advansys_info()
5470 * Return suitable for printing on the console with the argument
5471 * adapter's configuration information.
5473 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
5474 * otherwise the static 'info' array will be overrun.
5476 const char *
5477 advansys_info(struct Scsi_Host *shp)
5479 static char info[ASC_INFO_SIZE];
5480 asc_board_t *boardp;
5481 ASC_DVC_VAR *asc_dvc_varp;
5482 ADV_DVC_VAR *adv_dvc_varp;
5483 char *busname;
5484 int iolen;
5485 char *widename = NULL;
5487 boardp = ASC_BOARDP(shp);
5488 if (ASC_NARROW_BOARD(boardp)) {
5489 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5490 ASC_DBG(1, "advansys_info: begin\n");
5491 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5492 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == ASC_IS_ISAPNP) {
5493 busname = "ISA PnP";
5494 } else {
5495 busname = "ISA";
5497 /* Don't reference 'shp->n_io_port'; It may be truncated. */
5498 sprintf(info,
5499 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
5500 ASC_VERSION, busname,
5501 (ulong) shp->io_port,
5502 (ulong) shp->io_port + boardp->asc_n_io_port - 1,
5503 shp->irq, shp->dma_channel);
5504 } else {
5505 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
5506 busname = "VL";
5507 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
5508 busname = "EISA";
5509 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
5510 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
5511 == ASC_IS_PCI_ULTRA) {
5512 busname = "PCI Ultra";
5513 } else {
5514 busname = "PCI";
5516 } else {
5517 busname = "?";
5518 ASC_PRINT2( "advansys_info: board %d: unknown bus type %d\n",
5519 boardp->id, asc_dvc_varp->bus_type);
5521 /* Don't reference 'shp->n_io_port'; It may be truncated. */
5522 sprintf(info,
5523 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
5524 ASC_VERSION, busname,
5525 (ulong) shp->io_port,
5526 (ulong) shp->io_port + boardp->asc_n_io_port - 1,
5527 shp->irq);
5529 } else {
5531 * Wide Adapter Information
5533 * Memory-mapped I/O is used instead of I/O space to access
5534 * the adapter, but display the I/O Port range. The Memory
5535 * I/O address is displayed through the driver /proc file.
5537 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5538 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5540 iolen = ADV_3550_IOLEN;
5541 widename = "Ultra-Wide";
5542 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
5544 iolen = ADV_38C0800_IOLEN;
5545 widename = "Ultra2-Wide";
5546 } else
5548 iolen = ADV_38C1600_IOLEN;
5549 widename = "Ultra3-Wide";
5551 sprintf(info, "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
5552 ASC_VERSION,
5553 widename,
5554 (ulong) adv_dvc_varp->iop_base,
5555 (ulong) adv_dvc_varp->iop_base + iolen - 1,
5556 shp->irq);
5558 ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
5559 ASC_DBG(1, "advansys_info: end\n");
5560 return info;
5564 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
5566 * This function always returns 0. Command return status is saved
5567 * in the 'scp' result field.
5570 advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
5572 struct Scsi_Host *shp;
5573 asc_board_t *boardp;
5574 ulong flags;
5575 struct scsi_cmnd *done_scp;
5577 shp = scp->device->host;
5578 boardp = ASC_BOARDP(shp);
5579 ASC_STATS(shp, queuecommand);
5581 /* host_lock taken by mid-level prior to call but need to protect */
5582 /* against own ISR */
5583 spin_lock_irqsave(&boardp->lock, flags);
5586 * Block new commands while handling a reset or abort request.
5588 if (boardp->flags & ASC_HOST_IN_RESET) {
5589 ASC_DBG1(1,
5590 "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
5591 (ulong) scp);
5592 scp->result = HOST_BYTE(DID_RESET);
5595 * Add blocked requests to the board's 'done' queue. The queued
5596 * requests will be completed at the end of the abort or reset
5597 * handling.
5599 asc_enqueue(&boardp->done, scp, ASC_BACK);
5600 spin_unlock_irqrestore(&boardp->lock, flags);
5601 return 0;
5605 * Attempt to execute any waiting commands for the board.
5607 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
5608 ASC_DBG(1,
5609 "advansys_queuecommand: before asc_execute_queue() waiting\n");
5610 asc_execute_queue(&boardp->waiting);
5614 * Save the function pointer to Linux mid-level 'done' function
5615 * and attempt to execute the command.
5617 * If ASC_NOERROR is returned the request has been added to the
5618 * board's 'active' queue and will be completed by the interrupt
5619 * handler.
5621 * If ASC_BUSY is returned add the request to the board's per
5622 * target waiting list. This is the first time the request has
5623 * been tried. Add it to the back of the waiting list. It will be
5624 * retried later.
5626 * If an error occurred, the request will have been placed on the
5627 * board's 'done' queue and must be completed before returning.
5629 scp->scsi_done = done;
5630 switch (asc_execute_scsi_cmnd(scp)) {
5631 case ASC_NOERROR:
5632 break;
5633 case ASC_BUSY:
5634 asc_enqueue(&boardp->waiting, scp, ASC_BACK);
5635 break;
5636 case ASC_ERROR:
5637 default:
5638 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
5639 /* Interrupts could be enabled here. */
5640 asc_scsi_done_list(done_scp);
5641 break;
5643 spin_unlock_irqrestore(&boardp->lock, flags);
5645 return 0;
5649 * advansys_reset()
5651 * Reset the bus associated with the command 'scp'.
5653 * This function runs its own thread. Interrupts must be blocked but
5654 * sleeping is allowed and no locking other than for host structures is
5655 * required. Returns SUCCESS or FAILED.
5658 advansys_reset(struct scsi_cmnd *scp)
5660 struct Scsi_Host *shp;
5661 asc_board_t *boardp;
5662 ASC_DVC_VAR *asc_dvc_varp;
5663 ADV_DVC_VAR *adv_dvc_varp;
5664 ulong flags;
5665 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
5666 struct scsi_cmnd *tscp, *new_last_scp;
5667 int status;
5668 int ret = SUCCESS;
5670 ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong) scp);
5672 #ifdef ADVANSYS_STATS
5673 if (scp->device->host != NULL) {
5674 ASC_STATS(scp->device->host, reset);
5676 #endif /* ADVANSYS_STATS */
5678 if ((shp = scp->device->host) == NULL) {
5679 scp->result = HOST_BYTE(DID_ERROR);
5680 return FAILED;
5683 boardp = ASC_BOARDP(shp);
5685 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
5686 boardp->id);
5688 * Check for re-entrancy.
5690 spin_lock_irqsave(&boardp->lock, flags);
5691 if (boardp->flags & ASC_HOST_IN_RESET) {
5692 spin_unlock_irqrestore(&boardp->lock, flags);
5693 return FAILED;
5695 boardp->flags |= ASC_HOST_IN_RESET;
5696 spin_unlock_irqrestore(&boardp->lock, flags);
5698 if (ASC_NARROW_BOARD(boardp)) {
5700 * Narrow Board
5702 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5705 * Reset the chip and SCSI bus.
5707 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
5708 status = AscInitAsc1000Driver(asc_dvc_varp);
5710 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
5711 if (asc_dvc_varp->err_code) {
5712 ASC_PRINT2(
5713 "advansys_reset: board %d: SCSI bus reset error: 0x%x\n",
5714 boardp->id, asc_dvc_varp->err_code);
5715 ret = FAILED;
5716 } else if (status) {
5717 ASC_PRINT2(
5718 "advansys_reset: board %d: SCSI bus reset warning: 0x%x\n",
5719 boardp->id, status);
5720 } else {
5721 ASC_PRINT1(
5722 "advansys_reset: board %d: SCSI bus reset successful.\n",
5723 boardp->id);
5726 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
5727 spin_lock_irqsave(&boardp->lock, flags);
5729 } else {
5731 * Wide Board
5733 * If the suggest reset bus flags are set, then reset the bus.
5734 * Otherwise only reset the device.
5736 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5739 * Reset the target's SCSI bus.
5741 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
5742 switch (AdvResetChipAndSB(adv_dvc_varp)) {
5743 case ASC_TRUE:
5744 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset successful.\n",
5745 boardp->id);
5746 break;
5747 case ASC_FALSE:
5748 default:
5749 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset error.\n",
5750 boardp->id);
5751 ret = FAILED;
5752 break;
5754 spin_lock_irqsave(&boardp->lock, flags);
5755 (void) AdvISR(adv_dvc_varp);
5757 /* Board lock is held. */
5760 * Dequeue all board 'done' requests. A pointer to the last request
5761 * is returned in 'last_scp'.
5763 done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
5766 * Dequeue all board 'active' requests for all devices and set
5767 * the request status to DID_RESET. A pointer to the last request
5768 * is returned in 'last_scp'.
5770 if (done_scp == NULL) {
5771 done_scp = asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL);
5772 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
5773 tscp->result = HOST_BYTE(DID_RESET);
5775 } else {
5776 /* Append to 'done_scp' at the end with 'last_scp'. */
5777 ASC_ASSERT(last_scp != NULL);
5778 last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
5779 &boardp->active, &new_last_scp, ASC_TID_ALL);
5780 if (new_last_scp != NULL) {
5781 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
5782 for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
5783 tscp->result = HOST_BYTE(DID_RESET);
5785 last_scp = new_last_scp;
5790 * Dequeue all 'waiting' requests and set the request status
5791 * to DID_RESET.
5793 if (done_scp == NULL) {
5794 done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL);
5795 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
5796 tscp->result = HOST_BYTE(DID_RESET);
5798 } else {
5799 /* Append to 'done_scp' at the end with 'last_scp'. */
5800 ASC_ASSERT(last_scp != NULL);
5801 last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
5802 &boardp->waiting, &new_last_scp, ASC_TID_ALL);
5803 if (new_last_scp != NULL) {
5804 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
5805 for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
5806 tscp->result = HOST_BYTE(DID_RESET);
5808 last_scp = new_last_scp;
5812 /* Save the time of the most recently completed reset. */
5813 boardp->last_reset = jiffies;
5815 /* Clear reset flag. */
5816 boardp->flags &= ~ASC_HOST_IN_RESET;
5817 spin_unlock_irqrestore(&boardp->lock, flags);
5820 * Complete all the 'done_scp' requests.
5822 if (done_scp != NULL) {
5823 asc_scsi_done_list(done_scp);
5826 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
5828 return ret;
5832 * advansys_biosparam()
5834 * Translate disk drive geometry if the "BIOS greater than 1 GB"
5835 * support is enabled for a drive.
5837 * ip (information pointer) is an int array with the following definition:
5838 * ip[0]: heads
5839 * ip[1]: sectors
5840 * ip[2]: cylinders
5843 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
5844 sector_t capacity, int ip[])
5846 asc_board_t *boardp;
5848 ASC_DBG(1, "advansys_biosparam: begin\n");
5849 ASC_STATS(sdev->host, biosparam);
5850 boardp = ASC_BOARDP(sdev->host);
5851 if (ASC_NARROW_BOARD(boardp)) {
5852 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
5853 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
5854 ip[0] = 255;
5855 ip[1] = 63;
5856 } else {
5857 ip[0] = 64;
5858 ip[1] = 32;
5860 } else {
5861 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
5862 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
5863 ip[0] = 255;
5864 ip[1] = 63;
5865 } else {
5866 ip[0] = 64;
5867 ip[1] = 32;
5870 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
5871 ASC_DBG(1, "advansys_biosparam: end\n");
5872 return 0;
5876 * advansys_setup()
5878 * This function is called from init/main.c at boot time.
5879 * It it passed LILO parameters that can be set from the
5880 * LILO command line or in /etc/lilo.conf.
5882 * It is used by the AdvanSys driver to either disable I/O
5883 * port scanning or to limit scanning to 1 - 4 I/O ports.
5884 * Regardless of the option setting EISA and PCI boards
5885 * will still be searched for and detected. This option
5886 * only affects searching for ISA and VL boards.
5888 * If ADVANSYS_DEBUG is defined the driver debug level may
5889 * be set using the 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port.
5891 * Examples:
5892 * 1. Eliminate I/O port scanning:
5893 * boot: linux advansys=
5894 * or
5895 * boot: linux advansys=0x0
5896 * 2. Limit I/O port scanning to one I/O port:
5897 * boot: linux advansys=0x110
5898 * 3. Limit I/O port scanning to four I/O ports:
5899 * boot: linux advansys=0x110,0x210,0x230,0x330
5900 * 4. If ADVANSYS_DEBUG, limit I/O port scanning to four I/O ports and
5901 * set the driver debug level to 2.
5902 * boot: linux advansys=0x110,0x210,0x230,0x330,0xdeb2
5904 * ints[0] - number of arguments
5905 * ints[1] - first argument
5906 * ints[2] - second argument
5907 * ...
5909 void __init
5910 advansys_setup(char *str, int *ints)
5912 int i;
5914 if (asc_iopflag == ASC_TRUE) {
5915 printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n");
5916 return;
5919 asc_iopflag = ASC_TRUE;
5921 if (ints[0] > ASC_NUM_IOPORT_PROBE) {
5922 #ifdef ADVANSYS_DEBUG
5923 if ((ints[0] == ASC_NUM_IOPORT_PROBE + 1) &&
5924 (ints[ASC_NUM_IOPORT_PROBE + 1] >> 4 == 0xdeb)) {
5925 asc_dbglvl = ints[ASC_NUM_IOPORT_PROBE + 1] & 0xf;
5926 } else {
5927 #endif /* ADVANSYS_DEBUG */
5928 printk("AdvanSys SCSI: only %d I/O ports accepted\n",
5929 ASC_NUM_IOPORT_PROBE);
5930 #ifdef ADVANSYS_DEBUG
5932 #endif /* ADVANSYS_DEBUG */
5935 #ifdef ADVANSYS_DEBUG
5936 ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]);
5937 for (i = 1; i < ints[0]; i++) {
5938 ASC_DBG2(1, " ints[%d] 0x%x", i, ints[i]);
5940 ASC_DBG(1, "\n");
5941 #endif /* ADVANSYS_DEBUG */
5943 for (i = 1; i <= ints[0] && i <= ASC_NUM_IOPORT_PROBE; i++) {
5944 asc_ioport[i-1] = ints[i];
5945 ASC_DBG2(1, "advansys_setup: asc_ioport[%d] 0x%x\n",
5946 i - 1, asc_ioport[i-1]);
5952 * --- Loadable Driver Support
5955 static struct scsi_host_template driver_template = {
5956 .proc_name = "advansys",
5957 #ifdef CONFIG_PROC_FS
5958 .proc_info = advansys_proc_info,
5959 #endif
5960 .name = "advansys",
5961 .detect = advansys_detect,
5962 .release = advansys_release,
5963 .info = advansys_info,
5964 .queuecommand = advansys_queuecommand,
5965 .eh_bus_reset_handler = advansys_reset,
5966 .bios_param = advansys_biosparam,
5967 .slave_configure = advansys_slave_configure,
5969 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
5970 * must be set. The flag will be cleared in advansys_detect for non-ISA
5971 * adapters. Refer to the comment in scsi_module.c for more information.
5973 .unchecked_isa_dma = 1,
5975 * All adapters controlled by this driver are capable of large
5976 * scatter-gather lists. According to the mid-level SCSI documentation
5977 * this obviates any performance gain provided by setting
5978 * 'use_clustering'. But empirically while CPU utilization is increased
5979 * by enabling clustering, I/O throughput increases as well.
5981 .use_clustering = ENABLE_CLUSTERING,
5983 #include "scsi_module.c"
5987 * --- Miscellaneous Driver Functions
5991 * First-level interrupt handler.
5993 * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
5994 * all boards are currently checked for interrupts on each interrupt, 'dev_id'
5995 * is not referenced. 'dev_id' could be used to identify an interrupt passed
5996 * to the AdvanSys driver which is for a device sharing an interrupt with
5997 * an AdvanSys adapter.
5999 STATIC irqreturn_t
6000 advansys_interrupt(int irq, void *dev_id)
6002 ulong flags;
6003 int i;
6004 asc_board_t *boardp;
6005 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
6006 struct scsi_cmnd *new_last_scp;
6007 struct Scsi_Host *shp;
6009 ASC_DBG(1, "advansys_interrupt: begin\n");
6012 * Check for interrupts on all boards.
6013 * AscISR() will call asc_isr_callback().
6015 for (i = 0; i < asc_board_count; i++) {
6016 shp = asc_host[i];
6017 boardp = ASC_BOARDP(shp);
6018 ASC_DBG2(2, "advansys_interrupt: i %d, boardp 0x%lx\n",
6019 i, (ulong) boardp);
6020 spin_lock_irqsave(&boardp->lock, flags);
6021 if (ASC_NARROW_BOARD(boardp)) {
6023 * Narrow Board
6025 if (AscIsIntPending(shp->io_port)) {
6026 ASC_STATS(shp, interrupt);
6027 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
6028 AscISR(&boardp->dvc_var.asc_dvc_var);
6030 } else {
6032 * Wide Board
6034 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
6035 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
6036 ASC_STATS(shp, interrupt);
6041 * Start waiting requests and create a list of completed requests.
6043 * If a reset request is being performed for the board, the reset
6044 * handler will complete pending requests after it has completed.
6046 if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
6047 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%lx, last_scp 0x%lx\n",
6048 (ulong) done_scp, (ulong) last_scp);
6050 /* Start any waiting commands for the board. */
6051 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
6052 ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
6053 asc_execute_queue(&boardp->waiting);
6057 * Add to the list of requests that must be completed.
6059 * 'done_scp' will always be NULL on the first iteration
6060 * of this loop. 'last_scp' is set at the same time as
6061 * 'done_scp'.
6063 if (done_scp == NULL) {
6064 done_scp = asc_dequeue_list(&boardp->done, &last_scp,
6065 ASC_TID_ALL);
6066 } else {
6067 ASC_ASSERT(last_scp != NULL);
6068 last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
6069 &boardp->done, &new_last_scp, ASC_TID_ALL);
6070 if (new_last_scp != NULL) {
6071 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6072 last_scp = new_last_scp;
6076 spin_unlock_irqrestore(&boardp->lock, flags);
6080 * If interrupts were enabled on entry, then they
6081 * are now enabled here.
6083 * Complete all requests on the done list.
6086 asc_scsi_done_list(done_scp);
6088 ASC_DBG(1, "advansys_interrupt: end\n");
6089 return IRQ_HANDLED;
6093 * Set the number of commands to queue per device for the
6094 * specified host adapter.
6096 STATIC int
6097 advansys_slave_configure(struct scsi_device *device)
6099 asc_board_t *boardp;
6101 boardp = ASC_BOARDP(device->host);
6102 boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
6104 * Save a pointer to the device and set its initial/maximum
6105 * queue depth. Only save the pointer for a lun0 dev though.
6107 if(device->lun == 0)
6108 boardp->device[device->id] = device;
6109 if(device->tagged_supported) {
6110 if (ASC_NARROW_BOARD(boardp)) {
6111 scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
6112 boardp->dvc_var.asc_dvc_var.max_dvc_qng[device->id]);
6113 } else {
6114 scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
6115 boardp->dvc_var.adv_dvc_var.max_dvc_qng);
6117 } else {
6118 scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun);
6120 ASC_DBG4(1, "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n",
6121 (ulong) device, (ulong) boardp, device->id, device->queue_depth);
6122 return 0;
6126 * Complete all requests on the singly linked list pointed
6127 * to by 'scp'.
6129 * Interrupts can be enabled on entry.
6131 STATIC void
6132 asc_scsi_done_list(struct scsi_cmnd *scp)
6134 struct scsi_cmnd *tscp;
6136 ASC_DBG(2, "asc_scsi_done_list: begin\n");
6137 while (scp != NULL) {
6138 asc_board_t *boardp;
6139 struct device *dev;
6141 ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong) scp);
6142 tscp = REQPNEXT(scp);
6143 scp->host_scribble = NULL;
6145 boardp = ASC_BOARDP(scp->device->host);
6147 if (ASC_NARROW_BOARD(boardp))
6148 dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
6149 else
6150 dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
6152 if (scp->use_sg)
6153 dma_unmap_sg(dev, (struct scatterlist *)scp->request_buffer,
6154 scp->use_sg, scp->sc_data_direction);
6155 else if (scp->request_bufflen)
6156 dma_unmap_single(dev, scp->SCp.dma_handle,
6157 scp->request_bufflen, scp->sc_data_direction);
6159 ASC_STATS(scp->device->host, done);
6160 ASC_ASSERT(scp->scsi_done != NULL);
6162 scp->scsi_done(scp);
6164 scp = tscp;
6166 ASC_DBG(2, "asc_scsi_done_list: done\n");
6167 return;
6171 * Execute a single 'Scsi_Cmnd'.
6173 * The function 'done' is called when the request has been completed.
6175 * Scsi_Cmnd:
6177 * host - board controlling device
6178 * device - device to send command
6179 * target - target of device
6180 * lun - lun of device
6181 * cmd_len - length of SCSI CDB
6182 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
6183 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
6185 * if (use_sg == 0) {
6186 * request_buffer - buffer address for request
6187 * request_bufflen - length of request buffer
6188 * } else {
6189 * request_buffer - pointer to scatterlist structure
6192 * sense_buffer - sense command buffer
6194 * result (4 bytes of an int):
6195 * Byte Meaning
6196 * 0 SCSI Status Byte Code
6197 * 1 SCSI One Byte Message Code
6198 * 2 Host Error Code
6199 * 3 Mid-Level Error Code
6201 * host driver fields:
6202 * SCp - Scsi_Pointer used for command processing status
6203 * scsi_done - used to save caller's done function
6204 * host_scribble - used for pointer to another struct scsi_cmnd
6206 * If this function returns ASC_NOERROR the request has been enqueued
6207 * on the board's 'active' queue and will be completed from the
6208 * interrupt handler.
6210 * If this function returns ASC_NOERROR the request has been enqueued
6211 * on the board's 'done' queue and must be completed by the caller.
6213 * If ASC_BUSY is returned the request will be enqueued by the
6214 * caller on the target's waiting queue and re-tried later.
6216 STATIC int
6217 asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
6219 asc_board_t *boardp;
6220 ASC_DVC_VAR *asc_dvc_varp;
6221 ADV_DVC_VAR *adv_dvc_varp;
6222 ADV_SCSI_REQ_Q *adv_scsiqp;
6223 struct scsi_device *device;
6224 int ret;
6226 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
6227 (ulong) scp, (ulong) scp->scsi_done);
6229 boardp = ASC_BOARDP(scp->device->host);
6230 device = boardp->device[scp->device->id];
6232 if (ASC_NARROW_BOARD(boardp)) {
6234 * Build and execute Narrow Board request.
6237 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6240 * Build Asc Library request structure using the
6241 * global structures 'asc_scsi_req' and 'asc_sg_head'.
6243 * If an error is returned, then the request has been
6244 * queued on the board done queue. It will be completed
6245 * by the caller.
6247 * asc_build_req() can not return ASC_BUSY.
6249 if (asc_build_req(boardp, scp) == ASC_ERROR) {
6250 ASC_STATS(scp->device->host, build_error);
6251 return ASC_ERROR;
6255 * Execute the command. If there is no error, add the command
6256 * to the active queue.
6258 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
6259 case ASC_NOERROR:
6260 ASC_STATS(scp->device->host, exe_noerror);
6262 * Increment monotonically increasing per device successful
6263 * request counter. Wrapping doesn't matter.
6265 boardp->reqcnt[scp->device->id]++;
6266 asc_enqueue(&boardp->active, scp, ASC_BACK);
6267 ASC_DBG(1,
6268 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
6269 break;
6270 case ASC_BUSY:
6272 * Caller will enqueue request on the target's waiting queue
6273 * and retry later.
6275 ASC_STATS(scp->device->host, exe_busy);
6276 break;
6277 case ASC_ERROR:
6278 ASC_PRINT2(
6279 "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
6280 boardp->id, asc_dvc_varp->err_code);
6281 ASC_STATS(scp->device->host, exe_error);
6282 scp->result = HOST_BYTE(DID_ERROR);
6283 asc_enqueue(&boardp->done, scp, ASC_BACK);
6284 break;
6285 default:
6286 ASC_PRINT2(
6287 "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
6288 boardp->id, asc_dvc_varp->err_code);
6289 ASC_STATS(scp->device->host, exe_unknown);
6290 scp->result = HOST_BYTE(DID_ERROR);
6291 asc_enqueue(&boardp->done, scp, ASC_BACK);
6292 break;
6294 } else {
6296 * Build and execute Wide Board request.
6298 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6301 * Build and get a pointer to an Adv Library request structure.
6303 * If the request is successfully built then send it below,
6304 * otherwise return with an error.
6306 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
6307 case ASC_NOERROR:
6308 ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
6309 break;
6310 case ASC_BUSY:
6311 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
6313 * If busy is returned the request has not been enqueued.
6314 * It will be enqueued by the caller on the target's waiting
6315 * queue and retried later.
6317 * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg'
6318 * count wide board busy conditions. They are updated in
6319 * adv_build_req and adv_get_sglist, respectively.
6321 return ASC_BUSY;
6322 case ASC_ERROR:
6324 * If an error is returned, then the request has been
6325 * queued on the board done queue. It will be completed
6326 * by the caller.
6328 default:
6329 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
6330 ASC_STATS(scp->device->host, build_error);
6331 return ASC_ERROR;
6335 * Execute the command. If there is no error, add the command
6336 * to the active queue.
6338 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
6339 case ASC_NOERROR:
6340 ASC_STATS(scp->device->host, exe_noerror);
6342 * Increment monotonically increasing per device successful
6343 * request counter. Wrapping doesn't matter.
6345 boardp->reqcnt[scp->device->id]++;
6346 asc_enqueue(&boardp->active, scp, ASC_BACK);
6347 ASC_DBG(1,
6348 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
6349 break;
6350 case ASC_BUSY:
6352 * Caller will enqueue request on the target's waiting queue
6353 * and retry later.
6355 ASC_STATS(scp->device->host, exe_busy);
6356 break;
6357 case ASC_ERROR:
6358 ASC_PRINT2(
6359 "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
6360 boardp->id, adv_dvc_varp->err_code);
6361 ASC_STATS(scp->device->host, exe_error);
6362 scp->result = HOST_BYTE(DID_ERROR);
6363 asc_enqueue(&boardp->done, scp, ASC_BACK);
6364 break;
6365 default:
6366 ASC_PRINT2(
6367 "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
6368 boardp->id, adv_dvc_varp->err_code);
6369 ASC_STATS(scp->device->host, exe_unknown);
6370 scp->result = HOST_BYTE(DID_ERROR);
6371 asc_enqueue(&boardp->done, scp, ASC_BACK);
6372 break;
6376 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
6377 return ret;
6381 * Build a request structure for the Asc Library (Narrow Board).
6383 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
6384 * used to build the request.
6386 * If an error occurs, then queue the request on the board done
6387 * queue and return ASC_ERROR.
6389 STATIC int
6390 asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
6392 struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
6395 * Mutually exclusive access is required to 'asc_scsi_q' and
6396 * 'asc_sg_head' until after the request is started.
6398 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
6401 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
6403 asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
6406 * Build the ASC_SCSI_Q request.
6408 * For narrow boards a CDB length maximum of 12 bytes
6409 * is supported.
6411 if (scp->cmd_len > ASC_MAX_CDB_LEN) {
6412 ASC_PRINT3(
6413 "asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN %d\n",
6414 boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN);
6415 scp->result = HOST_BYTE(DID_ERROR);
6416 asc_enqueue(&boardp->done, scp, ASC_BACK);
6417 return ASC_ERROR;
6419 asc_scsi_q.cdbptr = &scp->cmnd[0];
6420 asc_scsi_q.q2.cdb_len = scp->cmd_len;
6421 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
6422 asc_scsi_q.q1.target_lun = scp->device->lun;
6423 asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
6424 asc_scsi_q.q1.sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
6425 asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
6428 * If there are any outstanding requests for the current target,
6429 * then every 255th request send an ORDERED request. This heuristic
6430 * tries to retain the benefit of request sorting while preventing
6431 * request starvation. 255 is the max number of tags or pending commands
6432 * a device may have outstanding.
6434 * The request count is incremented below for every successfully
6435 * started request.
6438 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
6439 (boardp->reqcnt[scp->device->id] % 255) == 0) {
6440 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
6441 } else {
6442 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
6446 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
6447 * buffer command.
6449 if (scp->use_sg == 0) {
6451 * CDB request of single contiguous buffer.
6453 ASC_STATS(scp->device->host, cont_cnt);
6454 scp->SCp.dma_handle = scp->request_bufflen ?
6455 dma_map_single(dev, scp->request_buffer,
6456 scp->request_bufflen, scp->sc_data_direction) : 0;
6457 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
6458 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
6459 ASC_STATS_ADD(scp->device->host, cont_xfer,
6460 ASC_CEILING(scp->request_bufflen, 512));
6461 asc_scsi_q.q1.sg_queue_cnt = 0;
6462 asc_scsi_q.sg_head = NULL;
6463 } else {
6465 * CDB scatter-gather request list.
6467 int sgcnt;
6468 int use_sg;
6469 struct scatterlist *slp;
6471 slp = (struct scatterlist *)scp->request_buffer;
6472 use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
6474 if (use_sg > scp->device->host->sg_tablesize) {
6475 ASC_PRINT3(
6476 "asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
6477 boardp->id, use_sg, scp->device->host->sg_tablesize);
6478 dma_unmap_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
6479 scp->result = HOST_BYTE(DID_ERROR);
6480 asc_enqueue(&boardp->done, scp, ASC_BACK);
6481 return ASC_ERROR;
6484 ASC_STATS(scp->device->host, sg_cnt);
6487 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
6488 * structure to point to it.
6490 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
6492 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
6493 asc_scsi_q.sg_head = &asc_sg_head;
6494 asc_scsi_q.q1.data_cnt = 0;
6495 asc_scsi_q.q1.data_addr = 0;
6496 /* This is a byte value, otherwise it would need to be swapped. */
6497 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
6498 ASC_STATS_ADD(scp->device->host, sg_elem, asc_sg_head.entry_cnt);
6501 * Convert scatter-gather list into ASC_SG_HEAD list.
6503 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
6504 asc_sg_head.sg_list[sgcnt].addr = cpu_to_le32(sg_dma_address(slp));
6505 asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(sg_dma_len(slp));
6506 ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512));
6510 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
6511 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6513 return ASC_NOERROR;
6517 * Build a request structure for the Adv Library (Wide Board).
6519 * If an adv_req_t can not be allocated to issue the request,
6520 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
6522 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
6523 * microcode for DMA addresses or math operations are byte swapped
6524 * to little-endian order.
6526 STATIC int
6527 adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
6528 ADV_SCSI_REQ_Q **adv_scsiqpp)
6530 adv_req_t *reqp;
6531 ADV_SCSI_REQ_Q *scsiqp;
6532 int i;
6533 int ret;
6534 struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
6537 * Allocate an adv_req_t structure from the board to execute
6538 * the command.
6540 if (boardp->adv_reqp == NULL) {
6541 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
6542 ASC_STATS(scp->device->host, adv_build_noreq);
6543 return ASC_BUSY;
6544 } else {
6545 reqp = boardp->adv_reqp;
6546 boardp->adv_reqp = reqp->next_reqp;
6547 reqp->next_reqp = NULL;
6551 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
6553 scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
6556 * Initialize the structure.
6558 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
6561 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
6563 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
6566 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
6568 reqp->cmndp = scp;
6571 * Build the ADV_SCSI_REQ_Q request.
6575 * Set CDB length and copy it to the request structure.
6576 * For wide boards a CDB length maximum of 16 bytes
6577 * is supported.
6579 if (scp->cmd_len > ADV_MAX_CDB_LEN) {
6580 ASC_PRINT3(
6581 "adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n",
6582 boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
6583 scp->result = HOST_BYTE(DID_ERROR);
6584 asc_enqueue(&boardp->done, scp, ASC_BACK);
6585 return ASC_ERROR;
6587 scsiqp->cdb_len = scp->cmd_len;
6588 /* Copy first 12 CDB bytes to cdb[]. */
6589 for (i = 0; i < scp->cmd_len && i < 12; i++) {
6590 scsiqp->cdb[i] = scp->cmnd[i];
6592 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
6593 for (; i < scp->cmd_len; i++) {
6594 scsiqp->cdb16[i - 12] = scp->cmnd[i];
6597 scsiqp->target_id = scp->device->id;
6598 scsiqp->target_lun = scp->device->lun;
6600 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
6601 scsiqp->sense_len = sizeof(scp->sense_buffer);
6604 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
6605 * buffer command.
6608 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
6609 scsiqp->vdata_addr = scp->request_buffer;
6610 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
6612 if (scp->use_sg == 0) {
6614 * CDB request of single contiguous buffer.
6616 reqp->sgblkp = NULL;
6617 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
6618 if (scp->request_bufflen) {
6619 scsiqp->vdata_addr = scp->request_buffer;
6620 scp->SCp.dma_handle =
6621 dma_map_single(dev, scp->request_buffer,
6622 scp->request_bufflen, scp->sc_data_direction);
6623 } else {
6624 scsiqp->vdata_addr = NULL;
6625 scp->SCp.dma_handle = 0;
6627 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
6628 scsiqp->sg_list_ptr = NULL;
6629 scsiqp->sg_real_addr = 0;
6630 ASC_STATS(scp->device->host, cont_cnt);
6631 ASC_STATS_ADD(scp->device->host, cont_xfer,
6632 ASC_CEILING(scp->request_bufflen, 512));
6633 } else {
6635 * CDB scatter-gather request list.
6637 struct scatterlist *slp;
6638 int use_sg;
6640 slp = (struct scatterlist *)scp->request_buffer;
6641 use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
6643 if (use_sg > ADV_MAX_SG_LIST) {
6644 ASC_PRINT3(
6645 "adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
6646 boardp->id, use_sg, scp->device->host->sg_tablesize);
6647 dma_unmap_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
6648 scp->result = HOST_BYTE(DID_ERROR);
6649 asc_enqueue(&boardp->done, scp, ASC_BACK);
6652 * Free the 'adv_req_t' structure by adding it back to the
6653 * board free list.
6655 reqp->next_reqp = boardp->adv_reqp;
6656 boardp->adv_reqp = reqp;
6658 return ASC_ERROR;
6661 if ((ret = adv_get_sglist(boardp, reqp, scp, use_sg)) != ADV_SUCCESS) {
6663 * Free the adv_req_t structure by adding it back to the
6664 * board free list.
6666 reqp->next_reqp = boardp->adv_reqp;
6667 boardp->adv_reqp = reqp;
6669 return ret;
6672 ASC_STATS(scp->device->host, sg_cnt);
6673 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
6676 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
6677 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6679 *adv_scsiqpp = scsiqp;
6681 return ASC_NOERROR;
6685 * Build scatter-gather list for Adv Library (Wide Board).
6687 * Additional ADV_SG_BLOCK structures will need to be allocated
6688 * if the total number of scatter-gather elements exceeds
6689 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
6690 * assumed to be physically contiguous.
6692 * Return:
6693 * ADV_SUCCESS(1) - SG List successfully created
6694 * ADV_ERROR(-1) - SG List creation failed
6696 STATIC int
6697 adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, int use_sg)
6699 adv_sgblk_t *sgblkp;
6700 ADV_SCSI_REQ_Q *scsiqp;
6701 struct scatterlist *slp;
6702 int sg_elem_cnt;
6703 ADV_SG_BLOCK *sg_block, *prev_sg_block;
6704 ADV_PADDR sg_block_paddr;
6705 int i;
6707 scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
6708 slp = (struct scatterlist *) scp->request_buffer;
6709 sg_elem_cnt = use_sg;
6710 prev_sg_block = NULL;
6711 reqp->sgblkp = NULL;
6716 * Allocate a 'adv_sgblk_t' structure from the board free
6717 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
6718 * (15) scatter-gather elements.
6720 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
6721 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
6722 ASC_STATS(scp->device->host, adv_build_nosg);
6725 * Allocation failed. Free 'adv_sgblk_t' structures already
6726 * allocated for the request.
6728 while ((sgblkp = reqp->sgblkp) != NULL)
6730 /* Remove 'sgblkp' from the request list. */
6731 reqp->sgblkp = sgblkp->next_sgblkp;
6733 /* Add 'sgblkp' to the board free list. */
6734 sgblkp->next_sgblkp = boardp->adv_sgblkp;
6735 boardp->adv_sgblkp = sgblkp;
6737 return ASC_BUSY;
6738 } else {
6739 /* Complete 'adv_sgblk_t' board allocation. */
6740 boardp->adv_sgblkp = sgblkp->next_sgblkp;
6741 sgblkp->next_sgblkp = NULL;
6744 * Get 8 byte aligned virtual and physical addresses for
6745 * the allocated ADV_SG_BLOCK structure.
6747 sg_block = (ADV_SG_BLOCK *) ADV_8BALIGN(&sgblkp->sg_block);
6748 sg_block_paddr = virt_to_bus(sg_block);
6751 * Check if this is the first 'adv_sgblk_t' for the request.
6753 if (reqp->sgblkp == NULL)
6755 /* Request's first scatter-gather block. */
6756 reqp->sgblkp = sgblkp;
6759 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
6760 * address pointers.
6762 scsiqp->sg_list_ptr = sg_block;
6763 scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr);
6764 } else
6766 /* Request's second or later scatter-gather block. */
6767 sgblkp->next_sgblkp = reqp->sgblkp;
6768 reqp->sgblkp = sgblkp;
6771 * Point the previous ADV_SG_BLOCK structure to
6772 * the newly allocated ADV_SG_BLOCK structure.
6774 ASC_ASSERT(prev_sg_block != NULL);
6775 prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr);
6779 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
6781 sg_block->sg_list[i].sg_addr = cpu_to_le32(sg_dma_address(slp));
6782 sg_block->sg_list[i].sg_count = cpu_to_le32(sg_dma_len(slp));
6783 ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512));
6785 if (--sg_elem_cnt == 0)
6786 { /* Last ADV_SG_BLOCK and scatter-gather entry. */
6787 sg_block->sg_cnt = i + 1;
6788 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
6789 return ADV_SUCCESS;
6791 slp++;
6793 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
6794 prev_sg_block = sg_block;
6796 while (1);
6797 /* NOTREACHED */
6801 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
6803 * Interrupt callback function for the Narrow SCSI Asc Library.
6805 STATIC void
6806 asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
6808 asc_board_t *boardp;
6809 struct scsi_cmnd *scp;
6810 struct Scsi_Host *shp;
6811 int i;
6813 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
6814 (ulong) asc_dvc_varp, (ulong) qdonep);
6815 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
6818 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
6819 * command that has been completed.
6821 scp = (struct scsi_cmnd *) ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
6822 ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong) scp);
6824 if (scp == NULL) {
6825 ASC_PRINT("asc_isr_callback: scp is NULL\n");
6826 return;
6828 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
6831 * If the request's host pointer is not valid, display a
6832 * message and return.
6834 shp = scp->device->host;
6835 for (i = 0; i < asc_board_count; i++) {
6836 if (asc_host[i] == shp) {
6837 break;
6840 if (i == asc_board_count) {
6841 ASC_PRINT2(
6842 "asc_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
6843 (ulong) scp, (ulong) shp);
6844 return;
6847 ASC_STATS(shp, callback);
6848 ASC_DBG1(1, "asc_isr_callback: shp 0x%lx\n", (ulong) shp);
6851 * If the request isn't found on the active queue, it may
6852 * have been removed to handle a reset request.
6853 * Display a message and return.
6855 boardp = ASC_BOARDP(shp);
6856 ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
6857 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
6858 ASC_PRINT2(
6859 "asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
6860 boardp->id, (ulong) scp);
6861 return;
6865 * 'qdonep' contains the command's ending status.
6867 switch (qdonep->d3.done_stat) {
6868 case QD_NO_ERROR:
6869 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
6870 scp->result = 0;
6873 * If an INQUIRY command completed successfully, then call
6874 * the AscInquiryHandling() function to set-up the device.
6876 if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 &&
6877 (scp->request_bufflen - qdonep->remain_bytes) >= 8)
6879 AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7,
6880 (ASC_SCSI_INQUIRY *) scp->request_buffer);
6884 * Check for an underrun condition.
6886 * If there was no error and an underrun condition, then
6887 * then return the number of underrun bytes.
6889 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
6890 qdonep->remain_bytes <= scp->request_bufflen) {
6891 ASC_DBG1(1, "asc_isr_callback: underrun condition %u bytes\n",
6892 (unsigned) qdonep->remain_bytes);
6893 scp->resid = qdonep->remain_bytes;
6895 break;
6897 case QD_WITH_ERROR:
6898 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
6899 switch (qdonep->d3.host_stat) {
6900 case QHSTA_NO_ERROR:
6901 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
6902 ASC_DBG(2, "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
6903 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
6904 sizeof(scp->sense_buffer));
6906 * Note: The 'status_byte()' macro used by target drivers
6907 * defined in scsi.h shifts the status byte returned by
6908 * host drivers right by 1 bit. This is why target drivers
6909 * also use right shifted status byte definitions. For
6910 * instance target drivers use CHECK_CONDITION, defined to
6911 * 0x1, instead of the SCSI defined check condition value
6912 * of 0x2. Host drivers are supposed to return the status
6913 * byte as it is defined by SCSI.
6915 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
6916 STATUS_BYTE(qdonep->d3.scsi_stat);
6917 } else {
6918 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
6920 break;
6922 default:
6923 /* QHSTA error occurred */
6924 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
6925 qdonep->d3.host_stat);
6926 scp->result = HOST_BYTE(DID_BAD_TARGET);
6927 break;
6929 break;
6931 case QD_ABORTED_BY_HOST:
6932 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
6933 scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.scsi_msg) |
6934 STATUS_BYTE(qdonep->d3.scsi_stat);
6935 break;
6937 default:
6938 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n", qdonep->d3.done_stat);
6939 scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
6940 STATUS_BYTE(qdonep->d3.scsi_stat);
6941 break;
6945 * If the 'init_tidmask' bit isn't already set for the target and the
6946 * current request finished normally, then set the bit for the target
6947 * to indicate that a device is present.
6949 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
6950 qdonep->d3.done_stat == QD_NO_ERROR &&
6951 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
6952 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
6956 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
6957 * function, add the command to the end of the board's done queue.
6958 * The done function for the command will be called from
6959 * advansys_interrupt().
6961 asc_enqueue(&boardp->done, scp, ASC_BACK);
6963 return;
6967 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
6969 * Callback function for the Wide SCSI Adv Library.
6971 STATIC void
6972 adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
6974 asc_board_t *boardp;
6975 adv_req_t *reqp;
6976 adv_sgblk_t *sgblkp;
6977 struct scsi_cmnd *scp;
6978 struct Scsi_Host *shp;
6979 int i;
6980 ADV_DCNT resid_cnt;
6983 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
6984 (ulong) adv_dvc_varp, (ulong) scsiqp);
6985 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
6988 * Get the adv_req_t structure for the command that has been
6989 * completed. The adv_req_t structure actually contains the
6990 * completed ADV_SCSI_REQ_Q structure.
6992 reqp = (adv_req_t *) ADV_U32_TO_VADDR(scsiqp->srb_ptr);
6993 ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong) reqp);
6994 if (reqp == NULL) {
6995 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
6996 return;
7000 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
7001 * command that has been completed.
7003 * Note: The adv_req_t request structure and adv_sgblk_t structure,
7004 * if any, are dropped, because a board structure pointer can not be
7005 * determined.
7007 scp = reqp->cmndp;
7008 ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong) scp);
7009 if (scp == NULL) {
7010 ASC_PRINT("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
7011 return;
7013 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
7016 * If the request's host pointer is not valid, display a message
7017 * and return.
7019 shp = scp->device->host;
7020 for (i = 0; i < asc_board_count; i++) {
7021 if (asc_host[i] == shp) {
7022 break;
7026 * Note: If the host structure is not found, the adv_req_t request
7027 * structure and adv_sgblk_t structure, if any, is dropped.
7029 if (i == asc_board_count) {
7030 ASC_PRINT2(
7031 "adv_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
7032 (ulong) scp, (ulong) shp);
7033 return;
7036 ASC_STATS(shp, callback);
7037 ASC_DBG1(1, "adv_isr_callback: shp 0x%lx\n", (ulong) shp);
7040 * If the request isn't found on the active queue, it may have been
7041 * removed to handle a reset request. Display a message and return.
7043 * Note: Because the structure may still be in use don't attempt
7044 * to free the adv_req_t and adv_sgblk_t, if any, structures.
7046 boardp = ASC_BOARDP(shp);
7047 ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
7048 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
7049 ASC_PRINT2(
7050 "adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
7051 boardp->id, (ulong) scp);
7052 return;
7056 * 'done_status' contains the command's ending status.
7058 switch (scsiqp->done_status) {
7059 case QD_NO_ERROR:
7060 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
7061 scp->result = 0;
7064 * Check for an underrun condition.
7066 * If there was no error and an underrun condition, then
7067 * then return the number of underrun bytes.
7069 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
7070 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
7071 resid_cnt <= scp->request_bufflen) {
7072 ASC_DBG1(1, "adv_isr_callback: underrun condition %lu bytes\n",
7073 (ulong) resid_cnt);
7074 scp->resid = resid_cnt;
7076 break;
7078 case QD_WITH_ERROR:
7079 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
7080 switch (scsiqp->host_status) {
7081 case QHSTA_NO_ERROR:
7082 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
7083 ASC_DBG(2, "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
7084 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
7085 sizeof(scp->sense_buffer));
7087 * Note: The 'status_byte()' macro used by target drivers
7088 * defined in scsi.h shifts the status byte returned by
7089 * host drivers right by 1 bit. This is why target drivers
7090 * also use right shifted status byte definitions. For
7091 * instance target drivers use CHECK_CONDITION, defined to
7092 * 0x1, instead of the SCSI defined check condition value
7093 * of 0x2. Host drivers are supposed to return the status
7094 * byte as it is defined by SCSI.
7096 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
7097 STATUS_BYTE(scsiqp->scsi_status);
7098 } else {
7099 scp->result = STATUS_BYTE(scsiqp->scsi_status);
7101 break;
7103 default:
7104 /* Some other QHSTA error occurred. */
7105 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
7106 scsiqp->host_status);
7107 scp->result = HOST_BYTE(DID_BAD_TARGET);
7108 break;
7110 break;
7112 case QD_ABORTED_BY_HOST:
7113 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
7114 scp->result = HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
7115 break;
7117 default:
7118 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n", scsiqp->done_status);
7119 scp->result = HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
7120 break;
7124 * If the 'init_tidmask' bit isn't already set for the target and the
7125 * current request finished normally, then set the bit for the target
7126 * to indicate that a device is present.
7128 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
7129 scsiqp->done_status == QD_NO_ERROR &&
7130 scsiqp->host_status == QHSTA_NO_ERROR) {
7131 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
7135 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
7136 * function, add the command to the end of the board's done queue.
7137 * The done function for the command will be called from
7138 * advansys_interrupt().
7140 asc_enqueue(&boardp->done, scp, ASC_BACK);
7143 * Free all 'adv_sgblk_t' structures allocated for the request.
7145 while ((sgblkp = reqp->sgblkp) != NULL)
7147 /* Remove 'sgblkp' from the request list. */
7148 reqp->sgblkp = sgblkp->next_sgblkp;
7150 /* Add 'sgblkp' to the board free list. */
7151 sgblkp->next_sgblkp = boardp->adv_sgblkp;
7152 boardp->adv_sgblkp = sgblkp;
7156 * Free the adv_req_t structure used with the command by adding
7157 * it back to the board free list.
7159 reqp->next_reqp = boardp->adv_reqp;
7160 boardp->adv_reqp = reqp;
7162 ASC_DBG(1, "adv_isr_callback: done\n");
7164 return;
7168 * adv_async_callback() - Adv Library asynchronous event callback function.
7170 STATIC void
7171 adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
7173 switch (code)
7175 case ADV_ASYNC_SCSI_BUS_RESET_DET:
7177 * The firmware detected a SCSI Bus reset.
7179 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
7180 break;
7182 case ADV_ASYNC_RDMA_FAILURE:
7184 * Handle RDMA failure by resetting the SCSI Bus and
7185 * possibly the chip if it is unresponsive. Log the error
7186 * with a unique code.
7188 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
7189 AdvResetChipAndSB(adv_dvc_varp);
7190 break;
7192 case ADV_HOST_SCSI_BUS_RESET:
7194 * Host generated SCSI bus reset occurred.
7196 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
7197 break;
7199 default:
7200 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
7201 break;
7206 * Add a 'REQP' to the end of specified queue. Set 'tidmask'
7207 * to indicate a command is queued for the device.
7209 * 'flag' may be either ASC_FRONT or ASC_BACK.
7211 * 'REQPNEXT(reqp)' returns reqp's next pointer.
7213 STATIC void
7214 asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
7216 int tid;
7218 ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
7219 (ulong) ascq, (ulong) reqp, flag);
7220 ASC_ASSERT(reqp != NULL);
7221 ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
7222 tid = REQPTID(reqp);
7223 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7224 if (flag == ASC_FRONT) {
7225 reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
7226 ascq->q_first[tid] = reqp;
7227 /* If the queue was empty, set the last pointer. */
7228 if (ascq->q_last[tid] == NULL) {
7229 ascq->q_last[tid] = reqp;
7231 } else { /* ASC_BACK */
7232 if (ascq->q_last[tid] != NULL) {
7233 ascq->q_last[tid]->host_scribble = (unsigned char *)reqp;
7235 ascq->q_last[tid] = reqp;
7236 reqp->host_scribble = NULL;
7237 /* If the queue was empty, set the first pointer. */
7238 if (ascq->q_first[tid] == NULL) {
7239 ascq->q_first[tid] = reqp;
7242 /* The queue has at least one entry, set its bit. */
7243 ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
7244 #ifdef ADVANSYS_STATS
7245 /* Maintain request queue statistics. */
7246 ascq->q_tot_cnt[tid]++;
7247 ascq->q_cur_cnt[tid]++;
7248 if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
7249 ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
7250 ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
7251 tid, ascq->q_max_cnt[tid]);
7253 REQPTIME(reqp) = REQTIMESTAMP();
7254 #endif /* ADVANSYS_STATS */
7255 ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong) reqp);
7256 return;
7260 * Return first queued 'REQP' on the specified queue for
7261 * the specified target device. Clear the 'tidmask' bit for
7262 * the device if no more commands are left queued for it.
7264 * 'REQPNEXT(reqp)' returns reqp's next pointer.
7266 STATIC REQP
7267 asc_dequeue(asc_queue_t *ascq, int tid)
7269 REQP reqp;
7271 ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong) ascq, tid);
7272 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7273 if ((reqp = ascq->q_first[tid]) != NULL) {
7274 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
7275 ascq->q_first[tid] = REQPNEXT(reqp);
7276 /* If the queue is empty, clear its bit and the last pointer. */
7277 if (ascq->q_first[tid] == NULL) {
7278 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7279 ASC_ASSERT(ascq->q_last[tid] == reqp);
7280 ascq->q_last[tid] = NULL;
7282 #ifdef ADVANSYS_STATS
7283 /* Maintain request queue statistics. */
7284 ascq->q_cur_cnt[tid]--;
7285 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
7286 REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
7287 #endif /* ADVANSYS_STATS */
7289 ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong) reqp);
7290 return reqp;
7294 * Return a pointer to a singly linked list of all the requests queued
7295 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
7297 * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
7298 * the last request returned in the singly linked list.
7300 * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
7301 * then all queued requests are concatenated into one list and
7302 * returned.
7304 * Note: If 'lastpp' is used to append a new list to the end of
7305 * an old list, only change the old list last pointer if '*lastpp'
7306 * (or the function return value) is not NULL, i.e. use a temporary
7307 * variable for 'lastpp' and check its value after the function return
7308 * before assigning it to the list last pointer.
7310 * Unfortunately collecting queuing time statistics adds overhead to
7311 * the function that isn't inherent to the function's algorithm.
7313 STATIC REQP
7314 asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
7316 REQP firstp, lastp;
7317 int i;
7319 ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong) ascq, tid);
7320 ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
7323 * If 'tid' is not ASC_TID_ALL, return requests only for
7324 * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
7325 * requests for all tids.
7327 if (tid != ASC_TID_ALL) {
7328 /* Return all requests for the specified 'tid'. */
7329 if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
7330 /* List is empty; Set first and last return pointers to NULL. */
7331 firstp = lastp = NULL;
7332 } else {
7333 firstp = ascq->q_first[tid];
7334 lastp = ascq->q_last[tid];
7335 ascq->q_first[tid] = ascq->q_last[tid] = NULL;
7336 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7337 #ifdef ADVANSYS_STATS
7339 REQP reqp;
7340 ascq->q_cur_cnt[tid] = 0;
7341 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
7342 REQTIMESTAT("asc_dequeue_list", ascq, reqp, tid);
7345 #endif /* ADVANSYS_STATS */
7347 } else {
7348 /* Return all requests for all tids. */
7349 firstp = lastp = NULL;
7350 for (i = 0; i <= ADV_MAX_TID; i++) {
7351 if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
7352 if (firstp == NULL) {
7353 firstp = ascq->q_first[i];
7354 lastp = ascq->q_last[i];
7355 } else {
7356 ASC_ASSERT(lastp != NULL);
7357 lastp->host_scribble = (unsigned char *)ascq->q_first[i];
7358 lastp = ascq->q_last[i];
7360 ascq->q_first[i] = ascq->q_last[i] = NULL;
7361 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7362 #ifdef ADVANSYS_STATS
7363 ascq->q_cur_cnt[i] = 0;
7364 #endif /* ADVANSYS_STATS */
7367 #ifdef ADVANSYS_STATS
7369 REQP reqp;
7370 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
7371 REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->device->id);
7374 #endif /* ADVANSYS_STATS */
7376 if (lastpp) {
7377 *lastpp = lastp;
7379 ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong) firstp);
7380 return firstp;
7384 * Remove the specified 'REQP' from the specified queue for
7385 * the specified target device. Clear the 'tidmask' bit for the
7386 * device if no more commands are left queued for it.
7388 * 'REQPNEXT(reqp)' returns reqp's the next pointer.
7390 * Return ASC_TRUE if the command was found and removed,
7391 * otherwise return ASC_FALSE.
7393 STATIC int
7394 asc_rmqueue(asc_queue_t *ascq, REQP reqp)
7396 REQP currp, prevp;
7397 int tid;
7398 int ret = ASC_FALSE;
7400 ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
7401 (ulong) ascq, (ulong) reqp);
7402 ASC_ASSERT(reqp != NULL);
7404 tid = REQPTID(reqp);
7405 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7408 * Handle the common case of 'reqp' being the first
7409 * entry on the queue.
7411 if (reqp == ascq->q_first[tid]) {
7412 ret = ASC_TRUE;
7413 ascq->q_first[tid] = REQPNEXT(reqp);
7414 /* If the queue is now empty, clear its bit and the last pointer. */
7415 if (ascq->q_first[tid] == NULL) {
7416 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7417 ASC_ASSERT(ascq->q_last[tid] == reqp);
7418 ascq->q_last[tid] = NULL;
7420 } else if (ascq->q_first[tid] != NULL) {
7421 ASC_ASSERT(ascq->q_last[tid] != NULL);
7423 * Because the case of 'reqp' being the first entry has been
7424 * handled above and it is known the queue is not empty, if
7425 * 'reqp' is found on the queue it is guaranteed the queue will
7426 * not become empty and that 'q_first[tid]' will not be changed.
7428 * Set 'prevp' to the first entry, 'currp' to the second entry,
7429 * and search for 'reqp'.
7431 for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
7432 currp; prevp = currp, currp = REQPNEXT(currp)) {
7433 if (currp == reqp) {
7434 ret = ASC_TRUE;
7435 prevp->host_scribble = (unsigned char *)REQPNEXT(currp);
7436 reqp->host_scribble = NULL;
7437 if (ascq->q_last[tid] == reqp) {
7438 ascq->q_last[tid] = prevp;
7440 break;
7444 #ifdef ADVANSYS_STATS
7445 /* Maintain request queue statistics. */
7446 if (ret == ASC_TRUE) {
7447 ascq->q_cur_cnt[tid]--;
7448 REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
7450 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
7451 #endif /* ADVANSYS_STATS */
7452 ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong) reqp, ret);
7453 return ret;
7457 * Execute as many queued requests as possible for the specified queue.
7459 * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd.
7461 STATIC void
7462 asc_execute_queue(asc_queue_t *ascq)
7464 ADV_SCSI_BIT_ID_TYPE scan_tidmask;
7465 REQP reqp;
7466 int i;
7468 ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong) ascq);
7470 * Execute queued commands for devices attached to
7471 * the current board in round-robin fashion.
7473 scan_tidmask = ascq->q_tidmask;
7474 do {
7475 for (i = 0; i <= ADV_MAX_TID; i++) {
7476 if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
7477 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
7478 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7479 } else if (asc_execute_scsi_cmnd((struct scsi_cmnd *) reqp)
7480 == ASC_BUSY) {
7481 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7483 * The request returned ASC_BUSY. Enqueue at the front of
7484 * target's waiting list to maintain correct ordering.
7486 asc_enqueue(ascq, reqp, ASC_FRONT);
7490 } while (scan_tidmask);
7491 return;
7494 #ifdef CONFIG_PROC_FS
7496 * asc_prt_board_devices()
7498 * Print driver information for devices attached to the board.
7500 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7501 * cf. asc_prt_line().
7503 * Return the number of characters copied into 'cp'. No more than
7504 * 'cplen' characters will be copied to 'cp'.
7506 STATIC int
7507 asc_prt_board_devices(struct Scsi_Host *shp, char *cp, int cplen)
7509 asc_board_t *boardp;
7510 int leftlen;
7511 int totlen;
7512 int len;
7513 int chip_scsi_id;
7514 int i;
7516 boardp = ASC_BOARDP(shp);
7517 leftlen = cplen;
7518 totlen = len = 0;
7520 len = asc_prt_line(cp, leftlen,
7521 "\nDevice Information for AdvanSys SCSI Host %d:\n", shp->host_no);
7522 ASC_PRT_NEXT();
7524 if (ASC_NARROW_BOARD(boardp)) {
7525 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7526 } else {
7527 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7530 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
7531 ASC_PRT_NEXT();
7532 for (i = 0; i <= ADV_MAX_TID; i++) {
7533 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
7534 len = asc_prt_line(cp, leftlen, " %X,", i);
7535 ASC_PRT_NEXT();
7538 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
7539 ASC_PRT_NEXT();
7541 return totlen;
7545 * Display Wide Board BIOS Information.
7547 STATIC int
7548 asc_prt_adv_bios(struct Scsi_Host *shp, char *cp, int cplen)
7550 asc_board_t *boardp;
7551 int leftlen;
7552 int totlen;
7553 int len;
7554 ushort major, minor, letter;
7556 boardp = ASC_BOARDP(shp);
7557 leftlen = cplen;
7558 totlen = len = 0;
7560 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
7561 ASC_PRT_NEXT();
7564 * If the BIOS saved a valid signature, then fill in
7565 * the BIOS code segment base address.
7567 if (boardp->bios_signature != 0x55AA) {
7568 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
7569 ASC_PRT_NEXT();
7570 len = asc_prt_line(cp, leftlen,
7571 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
7572 ASC_PRT_NEXT();
7573 len = asc_prt_line(cp, leftlen,
7574 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
7575 ASC_PRT_NEXT();
7576 } else {
7577 major = (boardp->bios_version >> 12) & 0xF;
7578 minor = (boardp->bios_version >> 8) & 0xF;
7579 letter = (boardp->bios_version & 0xFF);
7581 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
7582 major, minor, letter >= 26 ? '?' : letter + 'A');
7583 ASC_PRT_NEXT();
7586 * Current available ROM BIOS release is 3.1I for UW
7587 * and 3.2I for U2W. This code doesn't differentiate
7588 * UW and U2W boards.
7590 if (major < 3 || (major <= 3 && minor < 1) ||
7591 (major <= 3 && minor <= 1 && letter < ('I'- 'A'))) {
7592 len = asc_prt_line(cp, leftlen,
7593 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
7594 ASC_PRT_NEXT();
7595 len = asc_prt_line(cp, leftlen,
7596 "ftp://ftp.connectcom.net/pub\n");
7597 ASC_PRT_NEXT();
7601 return totlen;
7605 * Add serial number to information bar if signature AAh
7606 * is found in at bit 15-9 (7 bits) of word 1.
7608 * Serial Number consists fo 12 alpha-numeric digits.
7610 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
7611 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
7612 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
7613 * 5 - Product revision (A-J) Word0: " "
7615 * Signature Word1: 15-9 (7 bits)
7616 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
7617 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
7619 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
7621 * Note 1: Only production cards will have a serial number.
7623 * Note 2: Signature is most significant 7 bits (0xFE).
7625 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
7627 STATIC int
7628 asc_get_eeprom_string(ushort *serialnum, uchar *cp)
7630 ushort w, num;
7632 if ((serialnum[1] & 0xFE00) != ((ushort) 0xAA << 8)) {
7633 return ASC_FALSE;
7634 } else {
7636 * First word - 6 digits.
7638 w = serialnum[0];
7640 /* Product type - 1st digit. */
7641 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
7642 /* Product type is P=Prototype */
7643 *cp += 0x8;
7645 cp++;
7647 /* Manufacturing location - 2nd digit. */
7648 *cp++ = 'A' + ((w & 0x1C00) >> 10);
7650 /* Product ID - 3rd, 4th digits. */
7651 num = w & 0x3FF;
7652 *cp++ = '0' + (num / 100);
7653 num %= 100;
7654 *cp++ = '0' + (num / 10);
7656 /* Product revision - 5th digit. */
7657 *cp++ = 'A' + (num % 10);
7660 * Second word
7662 w = serialnum[1];
7665 * Year - 6th digit.
7667 * If bit 15 of third word is set, then the
7668 * last digit of the year is greater than 7.
7670 if (serialnum[2] & 0x8000) {
7671 *cp++ = '8' + ((w & 0x1C0) >> 6);
7672 } else {
7673 *cp++ = '0' + ((w & 0x1C0) >> 6);
7676 /* Week of year - 7th, 8th digits. */
7677 num = w & 0x003F;
7678 *cp++ = '0' + num / 10;
7679 num %= 10;
7680 *cp++ = '0' + num;
7683 * Third word
7685 w = serialnum[2] & 0x7FFF;
7687 /* Serial number - 9th digit. */
7688 *cp++ = 'A' + (w / 1000);
7690 /* 10th, 11th, 12th digits. */
7691 num = w % 1000;
7692 *cp++ = '0' + num / 100;
7693 num %= 100;
7694 *cp++ = '0' + num / 10;
7695 num %= 10;
7696 *cp++ = '0' + num;
7698 *cp = '\0'; /* Null Terminate the string. */
7699 return ASC_TRUE;
7704 * asc_prt_asc_board_eeprom()
7706 * Print board EEPROM configuration.
7708 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7709 * cf. asc_prt_line().
7711 * Return the number of characters copied into 'cp'. No more than
7712 * 'cplen' characters will be copied to 'cp'.
7714 STATIC int
7715 asc_prt_asc_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
7717 asc_board_t *boardp;
7718 ASC_DVC_VAR *asc_dvc_varp;
7719 int leftlen;
7720 int totlen;
7721 int len;
7722 ASCEEP_CONFIG *ep;
7723 int i;
7724 #ifdef CONFIG_ISA
7725 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
7726 #endif /* CONFIG_ISA */
7727 uchar serialstr[13];
7729 boardp = ASC_BOARDP(shp);
7730 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
7731 ep = &boardp->eep_config.asc_eep;
7733 leftlen = cplen;
7734 totlen = len = 0;
7736 len = asc_prt_line(cp, leftlen,
7737 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
7738 ASC_PRT_NEXT();
7740 if (asc_get_eeprom_string((ushort *) &ep->adapter_info[0], serialstr) ==
7741 ASC_TRUE) {
7742 len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
7743 ASC_PRT_NEXT();
7744 } else {
7745 if (ep->adapter_info[5] == 0xBB) {
7746 len = asc_prt_line(cp, leftlen,
7747 " Default Settings Used for EEPROM-less Adapter.\n");
7748 ASC_PRT_NEXT();
7749 } else {
7750 len = asc_prt_line(cp, leftlen,
7751 " Serial Number Signature Not Present.\n");
7752 ASC_PRT_NEXT();
7756 len = asc_prt_line(cp, leftlen,
7757 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7758 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng, ep->max_tag_qng);
7759 ASC_PRT_NEXT();
7761 len = asc_prt_line(cp, leftlen,
7762 " cntl 0x%x, no_scam 0x%x\n",
7763 ep->cntl, ep->no_scam);
7764 ASC_PRT_NEXT();
7766 len = asc_prt_line(cp, leftlen,
7767 " Target ID: ");
7768 ASC_PRT_NEXT();
7769 for (i = 0; i <= ASC_MAX_TID; i++) {
7770 len = asc_prt_line(cp, leftlen, " %d", i);
7771 ASC_PRT_NEXT();
7773 len = asc_prt_line(cp, leftlen, "\n");
7774 ASC_PRT_NEXT();
7776 len = asc_prt_line(cp, leftlen,
7777 " Disconnects: ");
7778 ASC_PRT_NEXT();
7779 for (i = 0; i <= ASC_MAX_TID; i++) {
7780 len = asc_prt_line(cp, leftlen, " %c",
7781 (ep->disc_enable & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7782 ASC_PRT_NEXT();
7784 len = asc_prt_line(cp, leftlen, "\n");
7785 ASC_PRT_NEXT();
7787 len = asc_prt_line(cp, leftlen,
7788 " Command Queuing: ");
7789 ASC_PRT_NEXT();
7790 for (i = 0; i <= ASC_MAX_TID; i++) {
7791 len = asc_prt_line(cp, leftlen, " %c",
7792 (ep->use_cmd_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7793 ASC_PRT_NEXT();
7795 len = asc_prt_line(cp, leftlen, "\n");
7796 ASC_PRT_NEXT();
7798 len = asc_prt_line(cp, leftlen,
7799 " Start Motor: ");
7800 ASC_PRT_NEXT();
7801 for (i = 0; i <= ASC_MAX_TID; i++) {
7802 len = asc_prt_line(cp, leftlen, " %c",
7803 (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7804 ASC_PRT_NEXT();
7806 len = asc_prt_line(cp, leftlen, "\n");
7807 ASC_PRT_NEXT();
7809 len = asc_prt_line(cp, leftlen,
7810 " Synchronous Transfer:");
7811 ASC_PRT_NEXT();
7812 for (i = 0; i <= ASC_MAX_TID; i++) {
7813 len = asc_prt_line(cp, leftlen, " %c",
7814 (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7815 ASC_PRT_NEXT();
7817 len = asc_prt_line(cp, leftlen, "\n");
7818 ASC_PRT_NEXT();
7820 #ifdef CONFIG_ISA
7821 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
7822 len = asc_prt_line(cp, leftlen,
7823 " Host ISA DMA speed: %d MB/S\n",
7824 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
7825 ASC_PRT_NEXT();
7827 #endif /* CONFIG_ISA */
7829 return totlen;
7833 * asc_prt_adv_board_eeprom()
7835 * Print board EEPROM configuration.
7837 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7838 * cf. asc_prt_line().
7840 * Return the number of characters copied into 'cp'. No more than
7841 * 'cplen' characters will be copied to 'cp'.
7843 STATIC int
7844 asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
7846 asc_board_t *boardp;
7847 ADV_DVC_VAR *adv_dvc_varp;
7848 int leftlen;
7849 int totlen;
7850 int len;
7851 int i;
7852 char *termstr;
7853 uchar serialstr[13];
7854 ADVEEP_3550_CONFIG *ep_3550 = NULL;
7855 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
7856 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
7857 ushort word;
7858 ushort *wordp;
7859 ushort sdtr_speed = 0;
7861 boardp = ASC_BOARDP(shp);
7862 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
7863 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7865 ep_3550 = &boardp->eep_config.adv_3550_eep;
7866 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7868 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
7869 } else
7871 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
7874 leftlen = cplen;
7875 totlen = len = 0;
7877 len = asc_prt_line(cp, leftlen,
7878 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
7879 ASC_PRT_NEXT();
7881 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7883 wordp = &ep_3550->serial_number_word1;
7884 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7886 wordp = &ep_38C0800->serial_number_word1;
7887 } else
7889 wordp = &ep_38C1600->serial_number_word1;
7892 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
7893 len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
7894 ASC_PRT_NEXT();
7895 } else {
7896 len = asc_prt_line(cp, leftlen,
7897 " Serial Number Signature Not Present.\n");
7898 ASC_PRT_NEXT();
7901 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7903 len = asc_prt_line(cp, leftlen,
7904 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7905 ep_3550->adapter_scsi_id, ep_3550->max_host_qng,
7906 ep_3550->max_dvc_qng);
7907 ASC_PRT_NEXT();
7908 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7910 len = asc_prt_line(cp, leftlen,
7911 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7912 ep_38C0800->adapter_scsi_id, ep_38C0800->max_host_qng,
7913 ep_38C0800->max_dvc_qng);
7914 ASC_PRT_NEXT();
7915 } else
7917 len = asc_prt_line(cp, leftlen,
7918 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7919 ep_38C1600->adapter_scsi_id, ep_38C1600->max_host_qng,
7920 ep_38C1600->max_dvc_qng);
7921 ASC_PRT_NEXT();
7923 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7925 word = ep_3550->termination;
7926 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7928 word = ep_38C0800->termination_lvd;
7929 } else
7931 word = ep_38C1600->termination_lvd;
7933 switch (word) {
7934 case 1:
7935 termstr = "Low Off/High Off";
7936 break;
7937 case 2:
7938 termstr = "Low Off/High On";
7939 break;
7940 case 3:
7941 termstr = "Low On/High On";
7942 break;
7943 default:
7944 case 0:
7945 termstr = "Automatic";
7946 break;
7949 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7951 len = asc_prt_line(cp, leftlen,
7952 " termination: %u (%s), bios_ctrl: 0x%x\n",
7953 ep_3550->termination, termstr, ep_3550->bios_ctrl);
7954 ASC_PRT_NEXT();
7955 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7957 len = asc_prt_line(cp, leftlen,
7958 " termination: %u (%s), bios_ctrl: 0x%x\n",
7959 ep_38C0800->termination_lvd, termstr, ep_38C0800->bios_ctrl);
7960 ASC_PRT_NEXT();
7961 } else
7963 len = asc_prt_line(cp, leftlen,
7964 " termination: %u (%s), bios_ctrl: 0x%x\n",
7965 ep_38C1600->termination_lvd, termstr, ep_38C1600->bios_ctrl);
7966 ASC_PRT_NEXT();
7969 len = asc_prt_line(cp, leftlen,
7970 " Target ID: ");
7971 ASC_PRT_NEXT();
7972 for (i = 0; i <= ADV_MAX_TID; i++) {
7973 len = asc_prt_line(cp, leftlen, " %X", i);
7974 ASC_PRT_NEXT();
7976 len = asc_prt_line(cp, leftlen, "\n");
7977 ASC_PRT_NEXT();
7979 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7981 word = ep_3550->disc_enable;
7982 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7984 word = ep_38C0800->disc_enable;
7985 } else
7987 word = ep_38C1600->disc_enable;
7989 len = asc_prt_line(cp, leftlen,
7990 " Disconnects: ");
7991 ASC_PRT_NEXT();
7992 for (i = 0; i <= ADV_MAX_TID; i++) {
7993 len = asc_prt_line(cp, leftlen, " %c",
7994 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7995 ASC_PRT_NEXT();
7997 len = asc_prt_line(cp, leftlen, "\n");
7998 ASC_PRT_NEXT();
8000 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8002 word = ep_3550->tagqng_able;
8003 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8005 word = ep_38C0800->tagqng_able;
8006 } else
8008 word = ep_38C1600->tagqng_able;
8010 len = asc_prt_line(cp, leftlen,
8011 " Command Queuing: ");
8012 ASC_PRT_NEXT();
8013 for (i = 0; i <= ADV_MAX_TID; i++) {
8014 len = asc_prt_line(cp, leftlen, " %c",
8015 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8016 ASC_PRT_NEXT();
8018 len = asc_prt_line(cp, leftlen, "\n");
8019 ASC_PRT_NEXT();
8021 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8023 word = ep_3550->start_motor;
8024 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8026 word = ep_38C0800->start_motor;
8027 } else
8029 word = ep_38C1600->start_motor;
8031 len = asc_prt_line(cp, leftlen,
8032 " Start Motor: ");
8033 ASC_PRT_NEXT();
8034 for (i = 0; i <= ADV_MAX_TID; i++) {
8035 len = asc_prt_line(cp, leftlen, " %c",
8036 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8037 ASC_PRT_NEXT();
8039 len = asc_prt_line(cp, leftlen, "\n");
8040 ASC_PRT_NEXT();
8042 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8044 len = asc_prt_line(cp, leftlen,
8045 " Synchronous Transfer:");
8046 ASC_PRT_NEXT();
8047 for (i = 0; i <= ADV_MAX_TID; i++) {
8048 len = asc_prt_line(cp, leftlen, " %c",
8049 (ep_3550->sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8050 ASC_PRT_NEXT();
8052 len = asc_prt_line(cp, leftlen, "\n");
8053 ASC_PRT_NEXT();
8056 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8058 len = asc_prt_line(cp, leftlen,
8059 " Ultra Transfer: ");
8060 ASC_PRT_NEXT();
8061 for (i = 0; i <= ADV_MAX_TID; i++) {
8062 len = asc_prt_line(cp, leftlen, " %c",
8063 (ep_3550->ultra_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8064 ASC_PRT_NEXT();
8066 len = asc_prt_line(cp, leftlen, "\n");
8067 ASC_PRT_NEXT();
8070 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8072 word = ep_3550->wdtr_able;
8073 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8075 word = ep_38C0800->wdtr_able;
8076 } else
8078 word = ep_38C1600->wdtr_able;
8080 len = asc_prt_line(cp, leftlen,
8081 " Wide Transfer: ");
8082 ASC_PRT_NEXT();
8083 for (i = 0; i <= ADV_MAX_TID; i++) {
8084 len = asc_prt_line(cp, leftlen, " %c",
8085 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8086 ASC_PRT_NEXT();
8088 len = asc_prt_line(cp, leftlen, "\n");
8089 ASC_PRT_NEXT();
8091 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
8092 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600)
8094 len = asc_prt_line(cp, leftlen,
8095 " Synchronous Transfer Speed (Mhz):\n ");
8096 ASC_PRT_NEXT();
8097 for (i = 0; i <= ADV_MAX_TID; i++) {
8098 char *speed_str;
8100 if (i == 0)
8102 sdtr_speed = adv_dvc_varp->sdtr_speed1;
8103 } else if (i == 4)
8105 sdtr_speed = adv_dvc_varp->sdtr_speed2;
8106 } else if (i == 8)
8108 sdtr_speed = adv_dvc_varp->sdtr_speed3;
8109 } else if (i == 12)
8111 sdtr_speed = adv_dvc_varp->sdtr_speed4;
8113 switch (sdtr_speed & ADV_MAX_TID)
8115 case 0: speed_str = "Off"; break;
8116 case 1: speed_str = " 5"; break;
8117 case 2: speed_str = " 10"; break;
8118 case 3: speed_str = " 20"; break;
8119 case 4: speed_str = " 40"; break;
8120 case 5: speed_str = " 80"; break;
8121 default: speed_str = "Unk"; break;
8123 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
8124 ASC_PRT_NEXT();
8125 if (i == 7)
8127 len = asc_prt_line(cp, leftlen, "\n ");
8128 ASC_PRT_NEXT();
8130 sdtr_speed >>= 4;
8132 len = asc_prt_line(cp, leftlen, "\n");
8133 ASC_PRT_NEXT();
8136 return totlen;
8140 * asc_prt_driver_conf()
8142 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8143 * cf. asc_prt_line().
8145 * Return the number of characters copied into 'cp'. No more than
8146 * 'cplen' characters will be copied to 'cp'.
8148 STATIC int
8149 asc_prt_driver_conf(struct Scsi_Host *shp, char *cp, int cplen)
8151 asc_board_t *boardp;
8152 int leftlen;
8153 int totlen;
8154 int len;
8155 int chip_scsi_id;
8157 boardp = ASC_BOARDP(shp);
8159 leftlen = cplen;
8160 totlen = len = 0;
8162 len = asc_prt_line(cp, leftlen,
8163 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
8164 shp->host_no);
8165 ASC_PRT_NEXT();
8167 len = asc_prt_line(cp, leftlen,
8168 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
8169 shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun,
8170 shp->max_channel);
8171 ASC_PRT_NEXT();
8173 len = asc_prt_line(cp, leftlen,
8174 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
8175 shp->unique_id, shp->can_queue, shp->this_id, shp->sg_tablesize,
8176 shp->cmd_per_lun);
8177 ASC_PRT_NEXT();
8179 len = asc_prt_line(cp, leftlen,
8180 " unchecked_isa_dma %d, use_clustering %d\n",
8181 shp->unchecked_isa_dma, shp->use_clustering);
8182 ASC_PRT_NEXT();
8184 len = asc_prt_line(cp, leftlen,
8185 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
8186 boardp->flags, boardp->last_reset, jiffies, boardp->asc_n_io_port);
8187 ASC_PRT_NEXT();
8189 /* 'shp->n_io_port' may be truncated because it is only one byte. */
8190 len = asc_prt_line(cp, leftlen,
8191 " io_port 0x%x, n_io_port 0x%x\n",
8192 shp->io_port, shp->n_io_port);
8193 ASC_PRT_NEXT();
8195 if (ASC_NARROW_BOARD(boardp)) {
8196 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
8197 } else {
8198 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
8201 return totlen;
8205 * asc_prt_asc_board_info()
8207 * Print dynamic board configuration information.
8209 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8210 * cf. asc_prt_line().
8212 * Return the number of characters copied into 'cp'. No more than
8213 * 'cplen' characters will be copied to 'cp'.
8215 STATIC int
8216 asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8218 asc_board_t *boardp;
8219 int chip_scsi_id;
8220 int leftlen;
8221 int totlen;
8222 int len;
8223 ASC_DVC_VAR *v;
8224 ASC_DVC_CFG *c;
8225 int i;
8226 int renegotiate = 0;
8228 boardp = ASC_BOARDP(shp);
8229 v = &boardp->dvc_var.asc_dvc_var;
8230 c = &boardp->dvc_cfg.asc_dvc_cfg;
8231 chip_scsi_id = c->chip_scsi_id;
8233 leftlen = cplen;
8234 totlen = len = 0;
8236 len = asc_prt_line(cp, leftlen,
8237 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8238 shp->host_no);
8239 ASC_PRT_NEXT();
8241 len = asc_prt_line(cp, leftlen,
8242 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
8243 c->chip_version, c->lib_version, c->lib_serial_no, c->mcode_date);
8244 ASC_PRT_NEXT();
8246 len = asc_prt_line(cp, leftlen,
8247 " mcode_version 0x%x, err_code %u\n",
8248 c->mcode_version, v->err_code);
8249 ASC_PRT_NEXT();
8251 /* Current number of commands waiting for the host. */
8252 len = asc_prt_line(cp, leftlen,
8253 " Total Command Pending: %d\n", v->cur_total_qng);
8254 ASC_PRT_NEXT();
8256 len = asc_prt_line(cp, leftlen,
8257 " Command Queuing:");
8258 ASC_PRT_NEXT();
8259 for (i = 0; i <= ASC_MAX_TID; i++) {
8260 if ((chip_scsi_id == i) ||
8261 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8262 continue;
8264 len = asc_prt_line(cp, leftlen, " %X:%c",
8265 i, (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8266 ASC_PRT_NEXT();
8268 len = asc_prt_line(cp, leftlen, "\n");
8269 ASC_PRT_NEXT();
8271 /* Current number of commands waiting for a device. */
8272 len = asc_prt_line(cp, leftlen,
8273 " Command Queue Pending:");
8274 ASC_PRT_NEXT();
8275 for (i = 0; i <= ASC_MAX_TID; i++) {
8276 if ((chip_scsi_id == i) ||
8277 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8278 continue;
8280 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
8281 ASC_PRT_NEXT();
8283 len = asc_prt_line(cp, leftlen, "\n");
8284 ASC_PRT_NEXT();
8286 /* Current limit on number of commands that can be sent to a device. */
8287 len = asc_prt_line(cp, leftlen,
8288 " Command Queue Limit:");
8289 ASC_PRT_NEXT();
8290 for (i = 0; i <= ASC_MAX_TID; i++) {
8291 if ((chip_scsi_id == i) ||
8292 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8293 continue;
8295 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
8296 ASC_PRT_NEXT();
8298 len = asc_prt_line(cp, leftlen, "\n");
8299 ASC_PRT_NEXT();
8301 /* Indicate whether the device has returned queue full status. */
8302 len = asc_prt_line(cp, leftlen,
8303 " Command Queue Full:");
8304 ASC_PRT_NEXT();
8305 for (i = 0; i <= ASC_MAX_TID; i++) {
8306 if ((chip_scsi_id == i) ||
8307 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8308 continue;
8310 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
8311 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
8312 i, boardp->queue_full_cnt[i]);
8313 } else {
8314 len = asc_prt_line(cp, leftlen, " %X:N", i);
8316 ASC_PRT_NEXT();
8318 len = asc_prt_line(cp, leftlen, "\n");
8319 ASC_PRT_NEXT();
8321 len = asc_prt_line(cp, leftlen,
8322 " Synchronous Transfer:");
8323 ASC_PRT_NEXT();
8324 for (i = 0; i <= ASC_MAX_TID; i++) {
8325 if ((chip_scsi_id == i) ||
8326 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8327 continue;
8329 len = asc_prt_line(cp, leftlen, " %X:%c",
8330 i, (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8331 ASC_PRT_NEXT();
8333 len = asc_prt_line(cp, leftlen, "\n");
8334 ASC_PRT_NEXT();
8336 for (i = 0; i <= ASC_MAX_TID; i++) {
8337 uchar syn_period_ix;
8339 if ((chip_scsi_id == i) ||
8340 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
8341 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
8342 continue;
8345 len = asc_prt_line(cp, leftlen, " %X:", i);
8346 ASC_PRT_NEXT();
8348 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0)
8350 len = asc_prt_line(cp, leftlen, " Asynchronous");
8351 ASC_PRT_NEXT();
8352 } else
8354 syn_period_ix =
8355 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1);
8357 len = asc_prt_line(cp, leftlen,
8358 " Transfer Period Factor: %d (%d.%d Mhz),",
8359 v->sdtr_period_tbl[syn_period_ix],
8360 250 / v->sdtr_period_tbl[syn_period_ix],
8361 ASC_TENTHS(250, v->sdtr_period_tbl[syn_period_ix]));
8362 ASC_PRT_NEXT();
8364 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
8365 boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET);
8366 ASC_PRT_NEXT();
8369 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8370 len = asc_prt_line(cp, leftlen, "*\n");
8371 renegotiate = 1;
8372 } else
8374 len = asc_prt_line(cp, leftlen, "\n");
8376 ASC_PRT_NEXT();
8379 if (renegotiate)
8381 len = asc_prt_line(cp, leftlen,
8382 " * = Re-negotiation pending before next command.\n");
8383 ASC_PRT_NEXT();
8386 return totlen;
8390 * asc_prt_adv_board_info()
8392 * Print dynamic board configuration information.
8394 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8395 * cf. asc_prt_line().
8397 * Return the number of characters copied into 'cp'. No more than
8398 * 'cplen' characters will be copied to 'cp'.
8400 STATIC int
8401 asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8403 asc_board_t *boardp;
8404 int leftlen;
8405 int totlen;
8406 int len;
8407 int i;
8408 ADV_DVC_VAR *v;
8409 ADV_DVC_CFG *c;
8410 AdvPortAddr iop_base;
8411 ushort chip_scsi_id;
8412 ushort lramword;
8413 uchar lrambyte;
8414 ushort tagqng_able;
8415 ushort sdtr_able, wdtr_able;
8416 ushort wdtr_done, sdtr_done;
8417 ushort period = 0;
8418 int renegotiate = 0;
8420 boardp = ASC_BOARDP(shp);
8421 v = &boardp->dvc_var.adv_dvc_var;
8422 c = &boardp->dvc_cfg.adv_dvc_cfg;
8423 iop_base = v->iop_base;
8424 chip_scsi_id = v->chip_scsi_id;
8426 leftlen = cplen;
8427 totlen = len = 0;
8429 len = asc_prt_line(cp, leftlen,
8430 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8431 shp->host_no);
8432 ASC_PRT_NEXT();
8434 len = asc_prt_line(cp, leftlen,
8435 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
8436 v->iop_base,
8437 AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1) & CABLE_DETECT,
8438 v->err_code);
8439 ASC_PRT_NEXT();
8441 len = asc_prt_line(cp, leftlen,
8442 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
8443 c->chip_version, c->lib_version, c->mcode_date, c->mcode_version);
8444 ASC_PRT_NEXT();
8446 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8447 len = asc_prt_line(cp, leftlen,
8448 " Queuing Enabled:");
8449 ASC_PRT_NEXT();
8450 for (i = 0; i <= ADV_MAX_TID; i++) {
8451 if ((chip_scsi_id == i) ||
8452 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8453 continue;
8456 len = asc_prt_line(cp, leftlen, " %X:%c",
8457 i, (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8458 ASC_PRT_NEXT();
8460 len = asc_prt_line(cp, leftlen, "\n");
8461 ASC_PRT_NEXT();
8463 len = asc_prt_line(cp, leftlen,
8464 " Queue Limit:");
8465 ASC_PRT_NEXT();
8466 for (i = 0; i <= ADV_MAX_TID; i++) {
8467 if ((chip_scsi_id == i) ||
8468 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8469 continue;
8472 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, lrambyte);
8474 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
8475 ASC_PRT_NEXT();
8477 len = asc_prt_line(cp, leftlen, "\n");
8478 ASC_PRT_NEXT();
8480 len = asc_prt_line(cp, leftlen,
8481 " Command Pending:");
8482 ASC_PRT_NEXT();
8483 for (i = 0; i <= ADV_MAX_TID; i++) {
8484 if ((chip_scsi_id == i) ||
8485 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8486 continue;
8489 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, lrambyte);
8491 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
8492 ASC_PRT_NEXT();
8494 len = asc_prt_line(cp, leftlen, "\n");
8495 ASC_PRT_NEXT();
8497 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8498 len = asc_prt_line(cp, leftlen,
8499 " Wide Enabled:");
8500 ASC_PRT_NEXT();
8501 for (i = 0; i <= ADV_MAX_TID; i++) {
8502 if ((chip_scsi_id == i) ||
8503 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8504 continue;
8507 len = asc_prt_line(cp, leftlen, " %X:%c",
8508 i, (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8509 ASC_PRT_NEXT();
8511 len = asc_prt_line(cp, leftlen, "\n");
8512 ASC_PRT_NEXT();
8514 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
8515 len = asc_prt_line(cp, leftlen,
8516 " Transfer Bit Width:");
8517 ASC_PRT_NEXT();
8518 for (i = 0; i <= ADV_MAX_TID; i++) {
8519 if ((chip_scsi_id == i) ||
8520 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8521 continue;
8524 AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
8525 lramword);
8527 len = asc_prt_line(cp, leftlen, " %X:%d",
8528 i, (lramword & 0x8000) ? 16 : 8);
8529 ASC_PRT_NEXT();
8531 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
8532 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8533 len = asc_prt_line(cp, leftlen, "*");
8534 ASC_PRT_NEXT();
8535 renegotiate = 1;
8538 len = asc_prt_line(cp, leftlen, "\n");
8539 ASC_PRT_NEXT();
8541 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8542 len = asc_prt_line(cp, leftlen,
8543 " Synchronous Enabled:");
8544 ASC_PRT_NEXT();
8545 for (i = 0; i <= ADV_MAX_TID; i++) {
8546 if ((chip_scsi_id == i) ||
8547 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8548 continue;
8551 len = asc_prt_line(cp, leftlen, " %X:%c",
8552 i, (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8553 ASC_PRT_NEXT();
8555 len = asc_prt_line(cp, leftlen, "\n");
8556 ASC_PRT_NEXT();
8558 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
8559 for (i = 0; i <= ADV_MAX_TID; i++) {
8561 AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
8562 lramword);
8563 lramword &= ~0x8000;
8565 if ((chip_scsi_id == i) ||
8566 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
8567 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
8568 continue;
8571 len = asc_prt_line(cp, leftlen, " %X:", i);
8572 ASC_PRT_NEXT();
8574 if ((lramword & 0x1F) == 0) /* Check for REQ/ACK Offset 0. */
8576 len = asc_prt_line(cp, leftlen, " Asynchronous");
8577 ASC_PRT_NEXT();
8578 } else
8580 len = asc_prt_line(cp, leftlen, " Transfer Period Factor: ");
8581 ASC_PRT_NEXT();
8583 if ((lramword & 0x1F00) == 0x1100) /* 80 Mhz */
8585 len = asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
8586 ASC_PRT_NEXT();
8587 } else if ((lramword & 0x1F00) == 0x1000) /* 40 Mhz */
8589 len = asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
8590 ASC_PRT_NEXT();
8591 } else /* 20 Mhz or below. */
8593 period = (((lramword >> 8) * 25) + 50)/4;
8595 if (period == 0) /* Should never happen. */
8597 len = asc_prt_line(cp, leftlen, "%d (? Mhz), ");
8598 ASC_PRT_NEXT();
8599 } else
8601 len = asc_prt_line(cp, leftlen,
8602 "%d (%d.%d Mhz),",
8603 period, 250/period, ASC_TENTHS(250, period));
8604 ASC_PRT_NEXT();
8608 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
8609 lramword & 0x1F);
8610 ASC_PRT_NEXT();
8613 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8614 len = asc_prt_line(cp, leftlen, "*\n");
8615 renegotiate = 1;
8616 } else
8618 len = asc_prt_line(cp, leftlen, "\n");
8620 ASC_PRT_NEXT();
8623 if (renegotiate)
8625 len = asc_prt_line(cp, leftlen,
8626 " * = Re-negotiation pending before next command.\n");
8627 ASC_PRT_NEXT();
8630 return totlen;
8634 * asc_proc_copy()
8636 * Copy proc information to a read buffer taking into account the current
8637 * read offset in the file and the remaining space in the read buffer.
8639 STATIC int
8640 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
8641 char *cp, int cplen)
8643 int cnt = 0;
8645 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
8646 (unsigned) offset, (unsigned) advoffset, cplen);
8647 if (offset <= advoffset) {
8648 /* Read offset below current offset, copy everything. */
8649 cnt = min(cplen, leftlen);
8650 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
8651 (ulong) curbuf, (ulong) cp, cnt);
8652 memcpy(curbuf, cp, cnt);
8653 } else if (offset < advoffset + cplen) {
8654 /* Read offset within current range, partial copy. */
8655 cnt = (advoffset + cplen) - offset;
8656 cp = (cp + cplen) - cnt;
8657 cnt = min(cnt, leftlen);
8658 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
8659 (ulong) curbuf, (ulong) cp, cnt);
8660 memcpy(curbuf, cp, cnt);
8662 return cnt;
8666 * asc_prt_line()
8668 * If 'cp' is NULL print to the console, otherwise print to a buffer.
8670 * Return 0 if printing to the console, otherwise return the number of
8671 * bytes written to the buffer.
8673 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
8674 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
8676 STATIC int
8677 asc_prt_line(char *buf, int buflen, char *fmt, ...)
8679 va_list args;
8680 int ret;
8681 char s[ASC_PRTLINE_SIZE];
8683 va_start(args, fmt);
8684 ret = vsprintf(s, fmt, args);
8685 ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
8686 if (buf == NULL) {
8687 (void) printk(s);
8688 ret = 0;
8689 } else {
8690 ret = min(buflen, ret);
8691 memcpy(buf, s, ret);
8693 va_end(args);
8694 return ret;
8696 #endif /* CONFIG_PROC_FS */
8700 * --- Functions Required by the Asc Library
8704 * Delay for 'n' milliseconds. Don't use the 'jiffies'
8705 * global variable which is incremented once every 5 ms
8706 * from a timer interrupt, because this function may be
8707 * called when interrupts are disabled.
8709 STATIC void
8710 DvcSleepMilliSecond(ADV_DCNT n)
8712 ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong) n);
8713 mdelay(n);
8717 * Currently and inline noop but leave as a placeholder.
8718 * Leave DvcEnterCritical() as a noop placeholder.
8720 STATIC inline ulong
8721 DvcEnterCritical(void)
8723 return 0;
8727 * Critical sections are all protected by the board spinlock.
8728 * Leave DvcLeaveCritical() as a noop placeholder.
8730 STATIC inline void
8731 DvcLeaveCritical(ulong flags)
8733 return;
8737 * void
8738 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
8740 * Calling/Exit State:
8741 * none
8743 * Description:
8744 * Output an ASC_SCSI_Q structure to the chip
8746 STATIC void
8747 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
8749 int i;
8751 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
8752 AscSetChipLramAddr(iop_base, s_addr);
8753 for (i = 0; i < 2 * words; i += 2) {
8754 if (i == 4 || i == 20) {
8755 continue;
8757 outpw(iop_base + IOP_RAM_DATA,
8758 ((ushort) outbuf[i + 1] << 8) | outbuf[i]);
8763 * void
8764 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
8766 * Calling/Exit State:
8767 * none
8769 * Description:
8770 * Input an ASC_QDONE_INFO structure from the chip
8772 STATIC void
8773 DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
8775 int i;
8776 ushort word;
8778 AscSetChipLramAddr(iop_base, s_addr);
8779 for (i = 0; i < 2 * words; i += 2) {
8780 if (i == 10) {
8781 continue;
8783 word = inpw(iop_base + IOP_RAM_DATA);
8784 inbuf[i] = word & 0xff;
8785 inbuf[i + 1] = (word >> 8) & 0xff;
8787 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
8791 * Read a PCI configuration byte.
8793 STATIC uchar __init
8794 DvcReadPCIConfigByte(
8795 ASC_DVC_VAR *asc_dvc,
8796 ushort offset)
8798 #ifdef CONFIG_PCI
8799 uchar byte_data;
8800 pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
8801 return byte_data;
8802 #else /* !defined(CONFIG_PCI) */
8803 return 0;
8804 #endif /* !defined(CONFIG_PCI) */
8808 * Write a PCI configuration byte.
8810 STATIC void __init
8811 DvcWritePCIConfigByte(
8812 ASC_DVC_VAR *asc_dvc,
8813 ushort offset,
8814 uchar byte_data)
8816 #ifdef CONFIG_PCI
8817 pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
8818 #endif /* CONFIG_PCI */
8822 * Return the BIOS address of the adapter at the specified
8823 * I/O port and with the specified bus type.
8825 STATIC ushort __init
8826 AscGetChipBiosAddress(
8827 PortAddr iop_base,
8828 ushort bus_type)
8830 ushort cfg_lsw;
8831 ushort bios_addr;
8834 * The PCI BIOS is re-located by the motherboard BIOS. Because
8835 * of this the driver can not determine where a PCI BIOS is
8836 * loaded and executes.
8838 if (bus_type & ASC_IS_PCI)
8840 return(0);
8843 #ifdef CONFIG_ISA
8844 if((bus_type & ASC_IS_EISA) != 0)
8846 cfg_lsw = AscGetEisaChipCfg(iop_base);
8847 cfg_lsw &= 0x000F;
8848 bios_addr = (ushort)(ASC_BIOS_MIN_ADDR +
8849 (cfg_lsw * ASC_BIOS_BANK_SIZE));
8850 return(bios_addr);
8851 }/* if */
8852 #endif /* CONFIG_ISA */
8854 cfg_lsw = AscGetChipCfgLsw(iop_base);
8857 * ISA PnP uses the top bit as the 32K BIOS flag
8859 if (bus_type == ASC_IS_ISAPNP)
8861 cfg_lsw &= 0x7FFF;
8862 }/* if */
8864 bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
8865 ASC_BIOS_MIN_ADDR);
8866 return(bios_addr);
8871 * --- Functions Required by the Adv Library
8875 * DvcGetPhyAddr()
8877 * Return the physical address of 'vaddr' and set '*lenp' to the
8878 * number of physically contiguous bytes that follow 'vaddr'.
8879 * 'flag' indicates the type of structure whose physical address
8880 * is being translated.
8882 * Note: Because Linux currently doesn't page the kernel and all
8883 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
8885 ADV_PADDR
8886 DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
8887 uchar *vaddr, ADV_SDCNT *lenp, int flag)
8889 ADV_PADDR paddr;
8891 paddr = virt_to_bus(vaddr);
8893 ASC_DBG4(4,
8894 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
8895 (ulong) vaddr, (ulong) lenp, (ulong) *((ulong *) lenp), (ulong) paddr);
8897 return paddr;
8901 * Read a PCI configuration byte.
8903 STATIC uchar __init
8904 DvcAdvReadPCIConfigByte(
8905 ADV_DVC_VAR *asc_dvc,
8906 ushort offset)
8908 #ifdef CONFIG_PCI
8909 uchar byte_data;
8910 pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
8911 return byte_data;
8912 #else /* CONFIG_PCI */
8913 return 0;
8914 #endif /* CONFIG_PCI */
8918 * Write a PCI configuration byte.
8920 STATIC void __init
8921 DvcAdvWritePCIConfigByte(
8922 ADV_DVC_VAR *asc_dvc,
8923 ushort offset,
8924 uchar byte_data)
8926 #ifdef CONFIG_PCI
8927 pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
8928 #else /* CONFIG_PCI */
8929 return;
8930 #endif /* CONFIG_PCI */
8934 * --- Tracing and Debugging Functions
8937 #ifdef ADVANSYS_STATS
8938 #ifdef CONFIG_PROC_FS
8940 * asc_prt_board_stats()
8942 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8943 * cf. asc_prt_line().
8945 * Return the number of characters copied into 'cp'. No more than
8946 * 'cplen' characters will be copied to 'cp'.
8948 STATIC int
8949 asc_prt_board_stats(struct Scsi_Host *shp, char *cp, int cplen)
8951 int leftlen;
8952 int totlen;
8953 int len;
8954 struct asc_stats *s;
8955 asc_board_t *boardp;
8957 leftlen = cplen;
8958 totlen = len = 0;
8960 boardp = ASC_BOARDP(shp);
8961 s = &boardp->asc_stats;
8963 len = asc_prt_line(cp, leftlen,
8964 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", shp->host_no);
8965 ASC_PRT_NEXT();
8967 len = asc_prt_line(cp, leftlen,
8968 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
8969 s->queuecommand, s->reset, s->biosparam, s->interrupt);
8970 ASC_PRT_NEXT();
8972 len = asc_prt_line(cp, leftlen,
8973 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
8974 s->callback, s->done, s->build_error, s->adv_build_noreq,
8975 s->adv_build_nosg);
8976 ASC_PRT_NEXT();
8978 len = asc_prt_line(cp, leftlen,
8979 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
8980 s->exe_noerror, s->exe_busy, s->exe_error, s->exe_unknown);
8981 ASC_PRT_NEXT();
8984 * Display data transfer statistics.
8986 if (s->cont_cnt > 0) {
8987 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
8988 ASC_PRT_NEXT();
8990 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
8991 s->cont_xfer/2,
8992 ASC_TENTHS(s->cont_xfer, 2));
8993 ASC_PRT_NEXT();
8995 /* Contiguous transfer average size */
8996 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
8997 (s->cont_xfer/2)/s->cont_cnt,
8998 ASC_TENTHS((s->cont_xfer/2), s->cont_cnt));
8999 ASC_PRT_NEXT();
9002 if (s->sg_cnt > 0) {
9004 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
9005 s->sg_cnt, s->sg_elem);
9006 ASC_PRT_NEXT();
9008 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
9009 s->sg_xfer/2,
9010 ASC_TENTHS(s->sg_xfer, 2));
9011 ASC_PRT_NEXT();
9013 /* Scatter gather transfer statistics */
9014 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
9015 s->sg_elem/s->sg_cnt,
9016 ASC_TENTHS(s->sg_elem, s->sg_cnt));
9017 ASC_PRT_NEXT();
9019 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
9020 (s->sg_xfer/2)/s->sg_elem,
9021 ASC_TENTHS((s->sg_xfer/2), s->sg_elem));
9022 ASC_PRT_NEXT();
9024 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
9025 (s->sg_xfer/2)/s->sg_cnt,
9026 ASC_TENTHS((s->sg_xfer/2), s->sg_cnt));
9027 ASC_PRT_NEXT();
9031 * Display request queuing statistics.
9033 len = asc_prt_line(cp, leftlen,
9034 " Active and Waiting Request Queues (Time Unit: %d HZ):\n", HZ);
9035 ASC_PRT_NEXT();
9038 return totlen;
9042 * asc_prt_target_stats()
9044 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
9045 * cf. asc_prt_line().
9047 * This is separated from asc_prt_board_stats because a full set
9048 * of targets will overflow ASC_PRTBUF_SIZE.
9050 * Return the number of characters copied into 'cp'. No more than
9051 * 'cplen' characters will be copied to 'cp'.
9053 STATIC int
9054 asc_prt_target_stats(struct Scsi_Host *shp, int tgt_id, char *cp, int cplen)
9056 int leftlen;
9057 int totlen;
9058 int len;
9059 struct asc_stats *s;
9060 ushort chip_scsi_id;
9061 asc_board_t *boardp;
9062 asc_queue_t *active;
9063 asc_queue_t *waiting;
9065 leftlen = cplen;
9066 totlen = len = 0;
9068 boardp = ASC_BOARDP(shp);
9069 s = &boardp->asc_stats;
9071 active = &ASC_BOARDP(shp)->active;
9072 waiting = &ASC_BOARDP(shp)->waiting;
9074 if (ASC_NARROW_BOARD(boardp)) {
9075 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
9076 } else {
9077 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
9080 if ((chip_scsi_id == tgt_id) ||
9081 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
9082 return 0;
9085 do {
9086 if (active->q_tot_cnt[tgt_id] > 0 || waiting->q_tot_cnt[tgt_id] > 0) {
9087 len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
9088 ASC_PRT_NEXT();
9090 len = asc_prt_line(cp, leftlen,
9091 " active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
9092 active->q_cur_cnt[tgt_id], active->q_max_cnt[tgt_id],
9093 active->q_tot_cnt[tgt_id],
9094 active->q_min_tim[tgt_id], active->q_max_tim[tgt_id],
9095 (active->q_tot_cnt[tgt_id] == 0) ? 0 :
9096 (active->q_tot_tim[tgt_id]/active->q_tot_cnt[tgt_id]),
9097 (active->q_tot_cnt[tgt_id] == 0) ? 0 :
9098 ASC_TENTHS(active->q_tot_tim[tgt_id],
9099 active->q_tot_cnt[tgt_id]));
9100 ASC_PRT_NEXT();
9102 len = asc_prt_line(cp, leftlen,
9103 " waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
9104 waiting->q_cur_cnt[tgt_id], waiting->q_max_cnt[tgt_id],
9105 waiting->q_tot_cnt[tgt_id],
9106 waiting->q_min_tim[tgt_id], waiting->q_max_tim[tgt_id],
9107 (waiting->q_tot_cnt[tgt_id] == 0) ? 0 :
9108 (waiting->q_tot_tim[tgt_id]/waiting->q_tot_cnt[tgt_id]),
9109 (waiting->q_tot_cnt[tgt_id] == 0) ? 0 :
9110 ASC_TENTHS(waiting->q_tot_tim[tgt_id],
9111 waiting->q_tot_cnt[tgt_id]));
9112 ASC_PRT_NEXT();
9114 } while (0);
9116 return totlen;
9118 #endif /* CONFIG_PROC_FS */
9119 #endif /* ADVANSYS_STATS */
9121 #ifdef ADVANSYS_DEBUG
9123 * asc_prt_scsi_host()
9125 STATIC void
9126 asc_prt_scsi_host(struct Scsi_Host *s)
9128 asc_board_t *boardp;
9130 boardp = ASC_BOARDP(s);
9132 printk("Scsi_Host at addr 0x%lx\n", (ulong) s);
9133 printk(
9134 " host_busy %u, host_no %d, last_reset %d,\n",
9135 s->host_busy, s->host_no,
9136 (unsigned) s->last_reset);
9138 printk(
9139 " base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
9140 (ulong) s->base, (ulong) s->io_port, s->n_io_port, s->irq);
9142 printk(
9143 " dma_channel %d, this_id %d, can_queue %d,\n",
9144 s->dma_channel, s->this_id, s->can_queue);
9146 printk(
9147 " cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
9148 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
9150 if (ASC_NARROW_BOARD(boardp)) {
9151 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
9152 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
9153 } else {
9154 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
9155 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
9160 * asc_prt_scsi_cmnd()
9162 STATIC void
9163 asc_prt_scsi_cmnd(struct scsi_cmnd *s)
9165 printk("struct scsi_cmnd at addr 0x%lx\n", (ulong) s);
9167 printk(
9168 " host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
9169 (ulong) s->device->host, (ulong) s->device, s->device->id, s->device->lun,
9170 s->device->channel);
9172 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
9174 printk (
9175 "sc_data_direction %u, resid %d\n",
9176 s->sc_data_direction, s->resid);
9178 printk(
9179 " use_sg %u, sglist_len %u\n",
9180 s->use_sg, s->sglist_len);
9182 printk(
9183 " serial_number 0x%x, retries %d, allowed %d\n",
9184 (unsigned) s->serial_number, s->retries, s->allowed);
9186 printk(
9187 " timeout_per_command %d\n",
9188 s->timeout_per_command);
9190 printk(
9191 " scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
9192 (ulong) s->scsi_done, (ulong) s->done,
9193 (ulong) s->host_scribble, s->result);
9195 printk(
9196 " tag %u, pid %u\n",
9197 (unsigned) s->tag, (unsigned) s->pid);
9201 * asc_prt_asc_dvc_var()
9203 STATIC void
9204 asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
9206 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong) h);
9208 printk(
9209 " iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n",
9210 h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
9212 printk(
9213 " bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n",
9214 h->bus_type, (ulong) h->isr_callback, (ulong) h->exe_callback,
9215 (unsigned) h->init_sdtr);
9217 printk(
9218 " sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n",
9219 (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng,
9220 (unsigned) h->unit_not_ready, (unsigned) h->chip_no);
9222 printk(
9223 " queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n",
9224 (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor,
9225 (unsigned) h->scsi_reset_wait);
9227 printk(
9228 " is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n",
9229 (unsigned) h->is_in_int, (unsigned) h->max_total_qng,
9230 (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt);
9232 printk(
9233 " last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n",
9234 (unsigned) h->last_q_shortage, (unsigned) h->init_state,
9235 (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer);
9237 printk(
9238 " cfg 0x%lx, irq_no 0x%x\n",
9239 (ulong) h->cfg, (unsigned) h->irq_no);
9243 * asc_prt_asc_dvc_cfg()
9245 STATIC void
9246 asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
9248 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong) h);
9250 printk(
9251 " can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
9252 h->can_tagged_qng, h->cmd_qng_enabled);
9253 printk(
9254 " disc_enable 0x%x, sdtr_enable 0x%x,\n",
9255 h->disc_enable, h->sdtr_enable);
9257 printk(
9258 " chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
9259 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
9260 h->chip_version);
9262 printk(
9263 " pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
9264 to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
9265 h->mcode_date);
9267 printk(
9268 " mcode_version %d, overrun_buf 0x%lx\n",
9269 h->mcode_version, (ulong) h->overrun_buf);
9273 * asc_prt_asc_scsi_q()
9275 STATIC void
9276 asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
9278 ASC_SG_HEAD *sgp;
9279 int i;
9281 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong) q);
9283 printk(
9284 " target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
9285 q->q2.target_ix, q->q1.target_lun,
9286 (ulong) q->q2.srb_ptr, q->q2.tag_code);
9288 printk(
9289 " data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
9290 (ulong) le32_to_cpu(q->q1.data_addr),
9291 (ulong) le32_to_cpu(q->q1.data_cnt),
9292 (ulong) le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
9294 printk(
9295 " cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
9296 (ulong) q->cdbptr, q->q2.cdb_len,
9297 (ulong) q->sg_head, q->q1.sg_queue_cnt);
9299 if (q->sg_head) {
9300 sgp = q->sg_head;
9301 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong) sgp);
9302 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt);
9303 for (i = 0; i < sgp->entry_cnt; i++) {
9304 printk(" [%u]: addr 0x%lx, bytes %lu\n",
9305 i, (ulong) le32_to_cpu(sgp->sg_list[i].addr),
9306 (ulong) le32_to_cpu(sgp->sg_list[i].bytes));
9313 * asc_prt_asc_qdone_info()
9315 STATIC void
9316 asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
9318 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong) q);
9319 printk(
9320 " srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
9321 (ulong) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
9322 q->d2.tag_code);
9323 printk(
9324 " done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
9325 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
9329 * asc_prt_adv_dvc_var()
9331 * Display an ADV_DVC_VAR structure.
9333 STATIC void
9334 asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
9336 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong) h);
9338 printk(
9339 " iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
9340 (ulong) h->iop_base, h->err_code, (unsigned) h->ultra_able);
9342 printk(
9343 " isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
9344 (ulong) h->isr_callback, (unsigned) h->sdtr_able,
9345 (unsigned) h->wdtr_able);
9347 printk(
9348 " start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
9349 (unsigned) h->start_motor,
9350 (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
9352 printk(
9353 " max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
9354 (unsigned) h->max_host_qng, (unsigned) h->max_dvc_qng,
9355 (ulong) h->carr_freelist);
9357 printk(
9358 " icq_sp 0x%lx, irq_sp 0x%lx\n",
9359 (ulong) h->icq_sp, (ulong) h->irq_sp);
9361 printk(
9362 " no_scam 0x%x, tagqng_able 0x%x\n",
9363 (unsigned) h->no_scam, (unsigned) h->tagqng_able);
9365 printk(
9366 " chip_scsi_id 0x%x, cfg 0x%lx\n",
9367 (unsigned) h->chip_scsi_id, (ulong) h->cfg);
9371 * asc_prt_adv_dvc_cfg()
9373 * Display an ADV_DVC_CFG structure.
9375 STATIC void
9376 asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
9378 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong) h);
9380 printk(
9381 " disc_enable 0x%x, termination 0x%x\n",
9382 h->disc_enable, h->termination);
9384 printk(
9385 " chip_version 0x%x, mcode_date 0x%x\n",
9386 h->chip_version, h->mcode_date);
9388 printk(
9389 " mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
9390 h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
9392 printk(
9393 " control_flag 0x%x, pci_slot_info 0x%x\n",
9394 h->control_flag, h->pci_slot_info);
9398 * asc_prt_adv_scsi_req_q()
9400 * Display an ADV_SCSI_REQ_Q structure.
9402 STATIC void
9403 asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
9405 int sg_blk_cnt;
9406 struct asc_sg_block *sg_ptr;
9408 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong) q);
9410 printk(
9411 " target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
9412 q->target_id, q->target_lun, (ulong) q->srb_ptr, q->a_flag);
9414 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
9415 q->cntl, (ulong) le32_to_cpu(q->data_addr), (ulong) q->vdata_addr);
9417 printk(
9418 " data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
9419 (ulong) le32_to_cpu(q->data_cnt),
9420 (ulong) le32_to_cpu(q->sense_addr), q->sense_len);
9422 printk(
9423 " cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
9424 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
9426 printk(
9427 " sg_working_ix 0x%x, target_cmd %u\n",
9428 q->sg_working_ix, q->target_cmd);
9430 printk(
9431 " scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
9432 (ulong) le32_to_cpu(q->scsiq_rptr),
9433 (ulong) le32_to_cpu(q->sg_real_addr), (ulong) q->sg_list_ptr);
9435 /* Display the request's ADV_SG_BLOCK structures. */
9436 if (q->sg_list_ptr != NULL)
9438 sg_blk_cnt = 0;
9439 while (1) {
9441 * 'sg_ptr' is a physical address. Convert it to a virtual
9442 * address by indexing 'sg_blk_cnt' into the virtual address
9443 * array 'sg_list_ptr'.
9445 * XXX - Assumes all SG physical blocks are virtually contiguous.
9447 sg_ptr = &(((ADV_SG_BLOCK *) (q->sg_list_ptr))[sg_blk_cnt]);
9448 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
9449 if (sg_ptr->sg_ptr == 0)
9451 break;
9453 sg_blk_cnt++;
9459 * asc_prt_adv_sgblock()
9461 * Display an ADV_SG_BLOCK structure.
9463 STATIC void
9464 asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
9466 int i;
9468 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
9469 (ulong) b, sgblockno);
9470 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
9471 b->sg_cnt, (ulong) le32_to_cpu(b->sg_ptr));
9472 ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
9473 if (b->sg_ptr != 0)
9475 ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
9477 for (i = 0; i < b->sg_cnt; i++) {
9478 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
9479 i, (ulong) b->sg_list[i].sg_addr, (ulong) b->sg_list[i].sg_count);
9484 * asc_prt_hex()
9486 * Print hexadecimal output in 4 byte groupings 32 bytes
9487 * or 8 double-words per line.
9489 STATIC void
9490 asc_prt_hex(char *f, uchar *s, int l)
9492 int i;
9493 int j;
9494 int k;
9495 int m;
9497 printk("%s: (%d bytes)\n", f, l);
9499 for (i = 0; i < l; i += 32) {
9501 /* Display a maximum of 8 double-words per line. */
9502 if ((k = (l - i) / 4) >= 8) {
9503 k = 8;
9504 m = 0;
9505 } else {
9506 m = (l - i) % 4;
9509 for (j = 0; j < k; j++) {
9510 printk(" %2.2X%2.2X%2.2X%2.2X",
9511 (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1],
9512 (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]);
9515 switch (m) {
9516 case 0:
9517 default:
9518 break;
9519 case 1:
9520 printk(" %2.2X",
9521 (unsigned) s[i+(j*4)]);
9522 break;
9523 case 2:
9524 printk(" %2.2X%2.2X",
9525 (unsigned) s[i+(j*4)],
9526 (unsigned) s[i+(j*4)+1]);
9527 break;
9528 case 3:
9529 printk(" %2.2X%2.2X%2.2X",
9530 (unsigned) s[i+(j*4)+1],
9531 (unsigned) s[i+(j*4)+2],
9532 (unsigned) s[i+(j*4)+3]);
9533 break;
9536 printk("\n");
9539 #endif /* ADVANSYS_DEBUG */
9542 * --- Asc Library Functions
9545 STATIC ushort __init
9546 AscGetEisaChipCfg(
9547 PortAddr iop_base)
9549 PortAddr eisa_cfg_iop;
9551 eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
9552 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
9553 return (inpw(eisa_cfg_iop));
9556 STATIC uchar __init
9557 AscSetChipScsiID(
9558 PortAddr iop_base,
9559 uchar new_host_id
9562 ushort cfg_lsw;
9564 if (AscGetChipScsiID(iop_base) == new_host_id) {
9565 return (new_host_id);
9567 cfg_lsw = AscGetChipCfgLsw(iop_base);
9568 cfg_lsw &= 0xF8FF;
9569 cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID) << 8);
9570 AscSetChipCfgLsw(iop_base, cfg_lsw);
9571 return (AscGetChipScsiID(iop_base));
9574 STATIC uchar __init
9575 AscGetChipScsiCtrl(
9576 PortAddr iop_base)
9578 uchar sc;
9580 AscSetBank(iop_base, 1);
9581 sc = inp(iop_base + IOP_REG_SC);
9582 AscSetBank(iop_base, 0);
9583 return (sc);
9586 STATIC uchar __init
9587 AscGetChipVersion(
9588 PortAddr iop_base,
9589 ushort bus_type
9592 if ((bus_type & ASC_IS_EISA) != 0) {
9593 PortAddr eisa_iop;
9594 uchar revision;
9595 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
9596 (PortAddr) ASC_EISA_REV_IOP_MASK;
9597 revision = inp(eisa_iop);
9598 return ((uchar) ((ASC_CHIP_MIN_VER_EISA - 1) + revision));
9600 return (AscGetChipVerNo(iop_base));
9603 STATIC ushort __init
9604 AscGetChipBusType(
9605 PortAddr iop_base)
9607 ushort chip_ver;
9609 chip_ver = AscGetChipVerNo(iop_base);
9610 if (
9611 (chip_ver >= ASC_CHIP_MIN_VER_VL)
9612 && (chip_ver <= ASC_CHIP_MAX_VER_VL)
9614 if (
9615 ((iop_base & 0x0C30) == 0x0C30)
9616 || ((iop_base & 0x0C50) == 0x0C50)
9618 return (ASC_IS_EISA);
9620 return (ASC_IS_VL);
9622 if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
9623 (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
9624 if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
9625 return (ASC_IS_ISAPNP);
9627 return (ASC_IS_ISA);
9628 } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
9629 (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
9630 return (ASC_IS_PCI);
9632 return (0);
9635 STATIC ASC_DCNT
9636 AscLoadMicroCode(
9637 PortAddr iop_base,
9638 ushort s_addr,
9639 uchar *mcode_buf,
9640 ushort mcode_size
9643 ASC_DCNT chksum;
9644 ushort mcode_word_size;
9645 ushort mcode_chksum;
9647 /* Write the microcode buffer starting at LRAM address 0. */
9648 mcode_word_size = (ushort) (mcode_size >> 1);
9649 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
9650 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
9652 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
9653 ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong) chksum);
9654 mcode_chksum = (ushort) AscMemSumLramWord(iop_base,
9655 (ushort) ASC_CODE_SEC_BEG,
9656 (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2));
9657 ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
9658 (ulong) mcode_chksum);
9659 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
9660 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
9661 return (chksum);
9664 STATIC int
9665 AscFindSignature(
9666 PortAddr iop_base
9669 ushort sig_word;
9671 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
9672 iop_base, AscGetChipSignatureByte(iop_base));
9673 if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) {
9674 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
9675 iop_base, AscGetChipSignatureWord(iop_base));
9676 sig_word = AscGetChipSignatureWord(iop_base);
9677 if ((sig_word == (ushort) ASC_1000_ID0W) ||
9678 (sig_word == (ushort) ASC_1000_ID0W_FIX)) {
9679 return (1);
9682 return (0);
9685 STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __initdata =
9687 0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
9688 ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
9691 #ifdef CONFIG_ISA
9692 STATIC uchar _isa_pnp_inited __initdata = 0;
9694 STATIC PortAddr __init
9695 AscSearchIOPortAddr(
9696 PortAddr iop_beg,
9697 ushort bus_type)
9699 if (bus_type & ASC_IS_VL) {
9700 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
9701 if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL) {
9702 return (iop_beg);
9705 return (0);
9707 if (bus_type & ASC_IS_ISA) {
9708 if (_isa_pnp_inited == 0) {
9709 AscSetISAPNPWaitForKey();
9710 _isa_pnp_inited++;
9712 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
9713 if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT) != 0) {
9714 return (iop_beg);
9717 return (0);
9719 if (bus_type & ASC_IS_EISA) {
9720 if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
9721 return (iop_beg);
9723 return (0);
9725 return (0);
9728 STATIC PortAddr __init
9729 AscSearchIOPortAddr11(
9730 PortAddr s_addr
9733 int i;
9734 PortAddr iop_base;
9736 for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
9737 if (_asc_def_iop_base[i] > s_addr) {
9738 break;
9741 for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
9742 iop_base = _asc_def_iop_base[i];
9743 if (check_region(iop_base, ASC_IOADR_GAP) != 0) {
9744 ASC_DBG1(1,
9745 "AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n",
9746 iop_base);
9747 continue;
9749 ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n", iop_base);
9750 if (AscFindSignature(iop_base)) {
9751 return (iop_base);
9754 return (0);
9757 STATIC void __init
9758 AscSetISAPNPWaitForKey(void)
9760 outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
9761 outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
9762 return;
9764 #endif /* CONFIG_ISA */
9766 STATIC void __init
9767 AscToggleIRQAct(
9768 PortAddr iop_base
9771 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
9772 AscSetChipStatus(iop_base, 0);
9773 return;
9776 STATIC uchar __init
9777 AscGetChipIRQ(
9778 PortAddr iop_base,
9779 ushort bus_type)
9781 ushort cfg_lsw;
9782 uchar chip_irq;
9784 if ((bus_type & ASC_IS_EISA) != 0) {
9785 cfg_lsw = AscGetEisaChipCfg(iop_base);
9786 chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10);
9787 if ((chip_irq == 13) || (chip_irq > 15)) {
9788 return (0);
9790 return (chip_irq);
9792 if ((bus_type & ASC_IS_VL) != 0) {
9793 cfg_lsw = AscGetChipCfgLsw(iop_base);
9794 chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07));
9795 if ((chip_irq == 0) ||
9796 (chip_irq == 4) ||
9797 (chip_irq == 7)) {
9798 return (0);
9800 return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1)));
9802 cfg_lsw = AscGetChipCfgLsw(iop_base);
9803 chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03));
9804 if (chip_irq == 3)
9805 chip_irq += (uchar) 2;
9806 return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
9809 STATIC uchar __init
9810 AscSetChipIRQ(
9811 PortAddr iop_base,
9812 uchar irq_no,
9813 ushort bus_type)
9815 ushort cfg_lsw;
9817 if ((bus_type & ASC_IS_VL) != 0) {
9818 if (irq_no != 0) {
9819 if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) {
9820 irq_no = 0;
9821 } else {
9822 irq_no -= (uchar) ((ASC_MIN_IRQ_NO - 1));
9825 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE3);
9826 cfg_lsw |= (ushort) 0x0010;
9827 AscSetChipCfgLsw(iop_base, cfg_lsw);
9828 AscToggleIRQAct(iop_base);
9829 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE0);
9830 cfg_lsw |= (ushort) ((irq_no & 0x07) << 2);
9831 AscSetChipCfgLsw(iop_base, cfg_lsw);
9832 AscToggleIRQAct(iop_base);
9833 return (AscGetChipIRQ(iop_base, bus_type));
9835 if ((bus_type & (ASC_IS_ISA)) != 0) {
9836 if (irq_no == 15)
9837 irq_no -= (uchar) 2;
9838 irq_no -= (uchar) ASC_MIN_IRQ_NO;
9839 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFF3);
9840 cfg_lsw |= (ushort) ((irq_no & 0x03) << 2);
9841 AscSetChipCfgLsw(iop_base, cfg_lsw);
9842 return (AscGetChipIRQ(iop_base, bus_type));
9844 return (0);
9847 #ifdef CONFIG_ISA
9848 STATIC void __init
9849 AscEnableIsaDma(
9850 uchar dma_channel)
9852 if (dma_channel < 4) {
9853 outp(0x000B, (ushort) (0xC0 | dma_channel));
9854 outp(0x000A, dma_channel);
9855 } else if (dma_channel < 8) {
9856 outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4)));
9857 outp(0x00D4, (ushort) (dma_channel - 4));
9859 return;
9861 #endif /* CONFIG_ISA */
9863 STATIC int
9864 AscIsrChipHalted(
9865 ASC_DVC_VAR *asc_dvc
9868 EXT_MSG ext_msg;
9869 EXT_MSG out_msg;
9870 ushort halt_q_addr;
9871 int sdtr_accept;
9872 ushort int_halt_code;
9873 ASC_SCSI_BIT_ID_TYPE scsi_busy;
9874 ASC_SCSI_BIT_ID_TYPE target_id;
9875 PortAddr iop_base;
9876 uchar tag_code;
9877 uchar q_status;
9878 uchar halt_qp;
9879 uchar sdtr_data;
9880 uchar target_ix;
9881 uchar q_cntl, tid_no;
9882 uchar cur_dvc_qng;
9883 uchar asyn_sdtr;
9884 uchar scsi_status;
9885 asc_board_t *boardp;
9887 ASC_ASSERT(asc_dvc->drv_ptr != NULL);
9888 boardp = asc_dvc->drv_ptr;
9890 iop_base = asc_dvc->iop_base;
9891 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
9893 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
9894 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
9895 target_ix = AscReadLramByte(iop_base,
9896 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX));
9897 q_cntl = AscReadLramByte(iop_base,
9898 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL));
9899 tid_no = ASC_TIX_TO_TID(target_ix);
9900 target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no);
9901 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
9902 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
9903 } else {
9904 asyn_sdtr = 0;
9906 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
9907 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
9908 AscSetChipSDTR(iop_base, 0, tid_no);
9909 boardp->sdtr_data[tid_no] = 0;
9911 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9912 return (0);
9913 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
9914 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
9915 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
9916 boardp->sdtr_data[tid_no] = asyn_sdtr;
9918 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9919 return (0);
9920 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
9922 AscMemWordCopyPtrFromLram(iop_base,
9923 ASCV_MSGIN_BEG,
9924 (uchar *) &ext_msg,
9925 sizeof(EXT_MSG) >> 1);
9927 if (ext_msg.msg_type == MS_EXTEND &&
9928 ext_msg.msg_req == MS_SDTR_CODE &&
9929 ext_msg.msg_len == MS_SDTR_LEN) {
9930 sdtr_accept = TRUE;
9931 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
9933 sdtr_accept = FALSE;
9934 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
9936 if ((ext_msg.xfer_period <
9937 asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index]) ||
9938 (ext_msg.xfer_period >
9939 asc_dvc->sdtr_period_tbl[asc_dvc->max_sdtr_index])) {
9940 sdtr_accept = FALSE;
9941 ext_msg.xfer_period =
9942 asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index];
9944 if (sdtr_accept) {
9945 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
9946 ext_msg.req_ack_offset);
9947 if ((sdtr_data == 0xFF)) {
9949 q_cntl |= QC_MSG_OUT;
9950 asc_dvc->init_sdtr &= ~target_id;
9951 asc_dvc->sdtr_done &= ~target_id;
9952 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
9953 boardp->sdtr_data[tid_no] = asyn_sdtr;
9956 if (ext_msg.req_ack_offset == 0) {
9958 q_cntl &= ~QC_MSG_OUT;
9959 asc_dvc->init_sdtr &= ~target_id;
9960 asc_dvc->sdtr_done &= ~target_id;
9961 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
9962 } else {
9963 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
9965 q_cntl &= ~QC_MSG_OUT;
9966 asc_dvc->sdtr_done |= target_id;
9967 asc_dvc->init_sdtr |= target_id;
9968 asc_dvc->pci_fix_asyn_xfer &= ~target_id;
9969 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
9970 ext_msg.req_ack_offset);
9971 AscSetChipSDTR(iop_base, sdtr_data, tid_no);
9972 boardp->sdtr_data[tid_no] = sdtr_data;
9973 } else {
9975 q_cntl |= QC_MSG_OUT;
9976 AscMsgOutSDTR(asc_dvc,
9977 ext_msg.xfer_period,
9978 ext_msg.req_ack_offset);
9979 asc_dvc->pci_fix_asyn_xfer &= ~target_id;
9980 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
9981 ext_msg.req_ack_offset);
9982 AscSetChipSDTR(iop_base, sdtr_data, tid_no);
9983 boardp->sdtr_data[tid_no] = sdtr_data;
9984 asc_dvc->sdtr_done |= target_id;
9985 asc_dvc->init_sdtr |= target_id;
9989 AscWriteLramByte(iop_base,
9990 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
9991 q_cntl);
9992 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9993 return (0);
9994 } else if (ext_msg.msg_type == MS_EXTEND &&
9995 ext_msg.msg_req == MS_WDTR_CODE &&
9996 ext_msg.msg_len == MS_WDTR_LEN) {
9998 ext_msg.wdtr_width = 0;
9999 AscMemWordCopyPtrToLram(iop_base,
10000 ASCV_MSGOUT_BEG,
10001 (uchar *) &ext_msg,
10002 sizeof(EXT_MSG) >> 1);
10003 q_cntl |= QC_MSG_OUT;
10004 AscWriteLramByte(iop_base,
10005 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10006 q_cntl);
10007 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10008 return (0);
10009 } else {
10011 ext_msg.msg_type = MESSAGE_REJECT;
10012 AscMemWordCopyPtrToLram(iop_base,
10013 ASCV_MSGOUT_BEG,
10014 (uchar *) &ext_msg,
10015 sizeof(EXT_MSG) >> 1);
10016 q_cntl |= QC_MSG_OUT;
10017 AscWriteLramByte(iop_base,
10018 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10019 q_cntl);
10020 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10021 return (0);
10023 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
10025 q_cntl |= QC_REQ_SENSE;
10027 if ((asc_dvc->init_sdtr & target_id) != 0) {
10029 asc_dvc->sdtr_done &= ~target_id;
10031 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10032 q_cntl |= QC_MSG_OUT;
10033 AscMsgOutSDTR(asc_dvc,
10034 asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
10035 (uchar) (asc_dvc->max_sdtr_index - 1)],
10036 (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
10039 AscWriteLramByte(iop_base,
10040 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10041 q_cntl);
10043 tag_code = AscReadLramByte(iop_base,
10044 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
10045 tag_code &= 0xDC;
10046 if (
10047 (asc_dvc->pci_fix_asyn_xfer & target_id)
10048 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
10051 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
10052 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
10055 AscWriteLramByte(iop_base,
10056 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE),
10057 tag_code);
10059 q_status = AscReadLramByte(iop_base,
10060 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS));
10061 q_status |= (QS_READY | QS_BUSY);
10062 AscWriteLramByte(iop_base,
10063 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10064 q_status);
10066 scsi_busy = AscReadLramByte(iop_base,
10067 (ushort) ASCV_SCSIBUSY_B);
10068 scsi_busy &= ~target_id;
10069 AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10071 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10072 return (0);
10073 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
10075 AscMemWordCopyPtrFromLram(iop_base,
10076 ASCV_MSGOUT_BEG,
10077 (uchar *) &out_msg,
10078 sizeof(EXT_MSG) >> 1);
10080 if ((out_msg.msg_type == MS_EXTEND) &&
10081 (out_msg.msg_len == MS_SDTR_LEN) &&
10082 (out_msg.msg_req == MS_SDTR_CODE)) {
10084 asc_dvc->init_sdtr &= ~target_id;
10085 asc_dvc->sdtr_done &= ~target_id;
10086 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10087 boardp->sdtr_data[tid_no] = asyn_sdtr;
10089 q_cntl &= ~QC_MSG_OUT;
10090 AscWriteLramByte(iop_base,
10091 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10092 q_cntl);
10093 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10094 return (0);
10095 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
10097 scsi_status = AscReadLramByte(iop_base,
10098 (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS));
10099 cur_dvc_qng = AscReadLramByte(iop_base,
10100 (ushort) ((ushort) ASC_QADR_BEG + (ushort) target_ix));
10101 if ((cur_dvc_qng > 0) &&
10102 (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
10104 scsi_busy = AscReadLramByte(iop_base,
10105 (ushort) ASCV_SCSIBUSY_B);
10106 scsi_busy |= target_id;
10107 AscWriteLramByte(iop_base,
10108 (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10109 asc_dvc->queue_full_or_busy |= target_id;
10111 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
10112 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
10113 cur_dvc_qng -= 1;
10114 asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
10116 AscWriteLramByte(iop_base,
10117 (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG +
10118 (ushort) tid_no),
10119 cur_dvc_qng);
10122 * Set the device queue depth to the number of
10123 * active requests when the QUEUE FULL condition
10124 * was encountered.
10126 boardp->queue_full |= target_id;
10127 boardp->queue_full_cnt[tid_no] = cur_dvc_qng;
10131 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10132 return (0);
10134 #if CC_VERY_LONG_SG_LIST
10135 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC)
10137 uchar q_no;
10138 ushort q_addr;
10139 uchar sg_wk_q_no;
10140 uchar first_sg_wk_q_no;
10141 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
10142 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
10143 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
10144 ushort sg_list_dwords;
10145 ushort sg_entry_cnt;
10146 uchar next_qp;
10147 int i;
10149 q_no = AscReadLramByte(iop_base, (ushort) ASCV_REQ_SG_LIST_QP);
10150 if (q_no == ASC_QLINK_END)
10152 return(0);
10155 q_addr = ASC_QNO_TO_QADDR(q_no);
10158 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
10159 * structure pointer using a macro provided by the driver.
10160 * The ASC_SCSI_REQ pointer provides a pointer to the
10161 * host ASC_SG_HEAD structure.
10163 /* Read request's SRB pointer. */
10164 scsiq = (ASC_SCSI_Q *)
10165 ASC_SRB2SCSIQ(
10166 ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
10167 (ushort) (q_addr + ASC_SCSIQ_D_SRBPTR))));
10170 * Get request's first and working SG queue.
10172 sg_wk_q_no = AscReadLramByte(iop_base,
10173 (ushort) (q_addr + ASC_SCSIQ_B_SG_WK_QP));
10175 first_sg_wk_q_no = AscReadLramByte(iop_base,
10176 (ushort) (q_addr + ASC_SCSIQ_B_FIRST_SG_WK_QP));
10179 * Reset request's working SG queue back to the
10180 * first SG queue.
10182 AscWriteLramByte(iop_base,
10183 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SG_WK_QP),
10184 first_sg_wk_q_no);
10186 sg_head = scsiq->sg_head;
10189 * Set sg_entry_cnt to the number of SG elements
10190 * that will be completed on this interrupt.
10192 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
10193 * SG elements. The data_cnt and data_addr fields which
10194 * add 1 to the SG element capacity are not used when
10195 * restarting SG handling after a halt.
10197 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1))
10199 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
10202 * Keep track of remaining number of SG elements that will
10203 * need to be handled on the next interrupt.
10205 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
10206 } else
10208 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
10209 scsiq->remain_sg_entry_cnt = 0;
10213 * Copy SG elements into the list of allocated SG queues.
10215 * Last index completed is saved in scsiq->next_sg_index.
10217 next_qp = first_sg_wk_q_no;
10218 q_addr = ASC_QNO_TO_QADDR(next_qp);
10219 scsi_sg_q.sg_head_qp = q_no;
10220 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
10221 for( i = 0; i < sg_head->queue_cnt; i++)
10223 scsi_sg_q.seq_no = i + 1;
10224 if (sg_entry_cnt > ASC_SG_LIST_PER_Q)
10226 sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
10227 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
10229 * After very first SG queue RISC FW uses next
10230 * SG queue first element then checks sg_list_cnt
10231 * against zero and then decrements, so set
10232 * sg_list_cnt 1 less than number of SG elements
10233 * in each SG queue.
10235 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
10236 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
10237 } else {
10239 * This is the last SG queue in the list of
10240 * allocated SG queues. If there are more
10241 * SG elements than will fit in the allocated
10242 * queues, then set the QCSG_SG_XFER_MORE flag.
10244 if (scsiq->remain_sg_entry_cnt != 0)
10246 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
10247 } else
10249 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
10251 /* equals sg_entry_cnt * 2 */
10252 sg_list_dwords = sg_entry_cnt << 1;
10253 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
10254 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
10255 sg_entry_cnt = 0;
10258 scsi_sg_q.q_no = next_qp;
10259 AscMemWordCopyPtrToLram(iop_base,
10260 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
10261 (uchar *) &scsi_sg_q,
10262 sizeof(ASC_SG_LIST_Q) >> 1);
10264 AscMemDWordCopyPtrToLram(iop_base,
10265 q_addr + ASC_SGQ_LIST_BEG,
10266 (uchar *) &sg_head->sg_list[scsiq->next_sg_index],
10267 sg_list_dwords);
10269 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
10272 * If the just completed SG queue contained the
10273 * last SG element, then no more SG queues need
10274 * to be written.
10276 if (scsi_sg_q.cntl & QCSG_SG_XFER_END)
10278 break;
10281 next_qp = AscReadLramByte( iop_base,
10282 ( ushort )( q_addr+ASC_SCSIQ_B_FWD ) );
10283 q_addr = ASC_QNO_TO_QADDR( next_qp );
10287 * Clear the halt condition so the RISC will be restarted
10288 * after the return.
10290 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10291 return(0);
10293 #endif /* CC_VERY_LONG_SG_LIST */
10294 return (0);
10297 STATIC uchar
10298 _AscCopyLramScsiDoneQ(
10299 PortAddr iop_base,
10300 ushort q_addr,
10301 ASC_QDONE_INFO * scsiq,
10302 ASC_DCNT max_dma_count
10305 ushort _val;
10306 uchar sg_queue_cnt;
10308 DvcGetQinfo(iop_base,
10309 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
10310 (uchar *) scsiq,
10311 (sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2);
10313 _val = AscReadLramWord(iop_base,
10314 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS));
10315 scsiq->q_status = (uchar) _val;
10316 scsiq->q_no = (uchar) (_val >> 8);
10317 _val = AscReadLramWord(iop_base,
10318 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL));
10319 scsiq->cntl = (uchar) _val;
10320 sg_queue_cnt = (uchar) (_val >> 8);
10321 _val = AscReadLramWord(iop_base,
10322 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN));
10323 scsiq->sense_len = (uchar) _val;
10324 scsiq->extra_bytes = (uchar) (_val >> 8);
10327 * Read high word of remain bytes from alternate location.
10329 scsiq->remain_bytes = (((ADV_DCNT) AscReadLramWord( iop_base,
10330 (ushort) (q_addr+ (ushort) ASC_SCSIQ_W_ALT_DC1))) << 16);
10332 * Read low word of remain bytes from original location.
10334 scsiq->remain_bytes += AscReadLramWord(iop_base,
10335 (ushort) (q_addr+ (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT));
10337 scsiq->remain_bytes &= max_dma_count;
10338 return (sg_queue_cnt);
10341 STATIC int
10342 AscIsrQDone(
10343 ASC_DVC_VAR *asc_dvc
10346 uchar next_qp;
10347 uchar n_q_used;
10348 uchar sg_list_qp;
10349 uchar sg_queue_cnt;
10350 uchar q_cnt;
10351 uchar done_q_tail;
10352 uchar tid_no;
10353 ASC_SCSI_BIT_ID_TYPE scsi_busy;
10354 ASC_SCSI_BIT_ID_TYPE target_id;
10355 PortAddr iop_base;
10356 ushort q_addr;
10357 ushort sg_q_addr;
10358 uchar cur_target_qng;
10359 ASC_QDONE_INFO scsiq_buf;
10360 ASC_QDONE_INFO *scsiq;
10361 int false_overrun;
10362 ASC_ISR_CALLBACK asc_isr_callback;
10364 iop_base = asc_dvc->iop_base;
10365 asc_isr_callback = asc_dvc->isr_callback;
10366 n_q_used = 1;
10367 scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
10368 done_q_tail = (uchar) AscGetVarDoneQTail(iop_base);
10369 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
10370 next_qp = AscReadLramByte(iop_base,
10371 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD));
10372 if (next_qp != ASC_QLINK_END) {
10373 AscPutVarDoneQTail(iop_base, next_qp);
10374 q_addr = ASC_QNO_TO_QADDR(next_qp);
10375 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
10376 asc_dvc->max_dma_count);
10377 AscWriteLramByte(iop_base,
10378 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10379 (uchar) (scsiq->q_status & (uchar) ~ (QS_READY | QS_ABORTED)));
10380 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
10381 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
10382 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
10383 sg_q_addr = q_addr;
10384 sg_list_qp = next_qp;
10385 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
10386 sg_list_qp = AscReadLramByte(iop_base,
10387 (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_FWD));
10388 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
10389 if (sg_list_qp == ASC_QLINK_END) {
10390 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_Q_LINKS);
10391 scsiq->d3.done_stat = QD_WITH_ERROR;
10392 scsiq->d3.host_stat = QHSTA_D_QDONE_SG_LIST_CORRUPTED;
10393 goto FATAL_ERR_QDONE;
10395 AscWriteLramByte(iop_base,
10396 (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10397 QS_FREE);
10399 n_q_used = sg_queue_cnt + 1;
10400 AscPutVarDoneQTail(iop_base, sg_list_qp);
10402 if (asc_dvc->queue_full_or_busy & target_id) {
10403 cur_target_qng = AscReadLramByte(iop_base,
10404 (ushort) ((ushort) ASC_QADR_BEG + (ushort) scsiq->d2.target_ix));
10405 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
10406 scsi_busy = AscReadLramByte(iop_base,
10407 (ushort) ASCV_SCSIBUSY_B);
10408 scsi_busy &= ~target_id;
10409 AscWriteLramByte(iop_base,
10410 (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10411 asc_dvc->queue_full_or_busy &= ~target_id;
10414 if (asc_dvc->cur_total_qng >= n_q_used) {
10415 asc_dvc->cur_total_qng -= n_q_used;
10416 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
10417 asc_dvc->cur_dvc_qng[tid_no]--;
10419 } else {
10420 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
10421 scsiq->d3.done_stat = QD_WITH_ERROR;
10422 goto FATAL_ERR_QDONE;
10424 if ((scsiq->d2.srb_ptr == 0UL) ||
10425 ((scsiq->q_status & QS_ABORTED) != 0)) {
10426 return (0x11);
10427 } else if (scsiq->q_status == QS_DONE) {
10428 false_overrun = FALSE;
10429 if (scsiq->extra_bytes != 0) {
10430 scsiq->remain_bytes += (ADV_DCNT) scsiq->extra_bytes;
10432 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
10433 if (scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN) {
10434 if ((scsiq->cntl & (QC_DATA_IN | QC_DATA_OUT)) == 0) {
10435 scsiq->d3.done_stat = QD_NO_ERROR;
10436 scsiq->d3.host_stat = QHSTA_NO_ERROR;
10437 } else if (false_overrun) {
10438 scsiq->d3.done_stat = QD_NO_ERROR;
10439 scsiq->d3.host_stat = QHSTA_NO_ERROR;
10441 } else if (scsiq->d3.host_stat ==
10442 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
10443 AscStopChip(iop_base);
10444 AscSetChipControl(iop_base,
10445 (uchar) (CC_SCSI_RESET | CC_HALT));
10446 DvcDelayNanoSecond(asc_dvc, 60000);
10447 AscSetChipControl(iop_base, CC_HALT);
10448 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10449 AscSetChipStatus(iop_base, 0);
10450 AscSetChipControl(iop_base, 0);
10453 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
10454 (*asc_isr_callback) (asc_dvc, scsiq);
10455 } else {
10456 if ((AscReadLramByte(iop_base,
10457 (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) ==
10458 START_STOP)) {
10459 asc_dvc->unit_not_ready &= ~target_id;
10460 if (scsiq->d3.done_stat != QD_NO_ERROR) {
10461 asc_dvc->start_motor &= ~target_id;
10465 return (1);
10466 } else {
10467 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
10468 FATAL_ERR_QDONE:
10469 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
10470 (*asc_isr_callback) (asc_dvc, scsiq);
10472 return (0x80);
10475 return (0);
10478 STATIC int
10479 AscISR(
10480 ASC_DVC_VAR *asc_dvc
10483 ASC_CS_TYPE chipstat;
10484 PortAddr iop_base;
10485 ushort saved_ram_addr;
10486 uchar ctrl_reg;
10487 uchar saved_ctrl_reg;
10488 int int_pending;
10489 int status;
10490 uchar host_flag;
10492 iop_base = asc_dvc->iop_base;
10493 int_pending = FALSE;
10495 if (AscIsIntPending(iop_base) == 0)
10497 return int_pending;
10500 if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
10501 || (asc_dvc->isr_callback == 0)
10503 return (ERR);
10505 if (asc_dvc->in_critical_cnt != 0) {
10506 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
10507 return (ERR);
10509 if (asc_dvc->is_in_int) {
10510 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
10511 return (ERR);
10513 asc_dvc->is_in_int = TRUE;
10514 ctrl_reg = AscGetChipControl(iop_base);
10515 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
10516 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
10517 chipstat = AscGetChipStatus(iop_base);
10518 if (chipstat & CSW_SCSI_RESET_LATCH) {
10519 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
10520 int i = 10;
10521 int_pending = TRUE;
10522 asc_dvc->sdtr_done = 0;
10523 saved_ctrl_reg &= (uchar) (~CC_HALT);
10524 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) &&
10525 (i-- > 0))
10527 DvcSleepMilliSecond(100);
10529 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
10530 AscSetChipControl(iop_base, CC_HALT);
10531 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10532 AscSetChipStatus(iop_base, 0);
10533 chipstat = AscGetChipStatus(iop_base);
10536 saved_ram_addr = AscGetChipLramAddr(iop_base);
10537 host_flag = AscReadLramByte(iop_base,
10538 ASCV_HOST_FLAG_B) & (uchar) (~ASC_HOST_FLAG_IN_ISR);
10539 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10540 (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR));
10541 if ((chipstat & CSW_INT_PENDING)
10542 || (int_pending)
10544 AscAckInterrupt(iop_base);
10545 int_pending = TRUE;
10546 if ((chipstat & CSW_HALTED) &&
10547 (ctrl_reg & CC_SINGLE_STEP)) {
10548 if (AscIsrChipHalted(asc_dvc) == ERR) {
10549 goto ISR_REPORT_QDONE_FATAL_ERROR;
10550 } else {
10551 saved_ctrl_reg &= (uchar) (~CC_HALT);
10553 } else {
10554 ISR_REPORT_QDONE_FATAL_ERROR:
10555 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
10556 while (((status = AscIsrQDone(asc_dvc)) & 0x01) != 0) {
10558 } else {
10559 do {
10560 if ((status = AscIsrQDone(asc_dvc)) == 1) {
10561 break;
10563 } while (status == 0x11);
10565 if ((status & 0x80) != 0)
10566 int_pending = ERR;
10569 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10570 AscSetChipLramAddr(iop_base, saved_ram_addr);
10571 AscSetChipControl(iop_base, saved_ctrl_reg);
10572 asc_dvc->is_in_int = FALSE;
10573 return (int_pending);
10576 /* Microcode buffer is kept after initialization for error recovery. */
10577 STATIC uchar _asc_mcode_buf[] =
10579 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10580 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10581 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10582 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10583 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
10584 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10585 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
10586 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00,
10587 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
10588 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2, 0xC2, 0x00, 0x92, 0x80,
10589 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80,
10590 0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
10591 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8, 0xCD, 0x04, 0x4D, 0x00,
10592 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1,
10593 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88,
10594 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00, 0x84, 0x97, 0x07, 0xA6,
10595 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00,
10596 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6,
10597 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6, 0x34, 0x01, 0x00, 0x33,
10598 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04,
10599 0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23,
10600 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01, 0x00, 0x33, 0x0A, 0x00,
10601 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04,
10602 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01,
10603 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3, 0x3C, 0x01, 0x00, 0x05,
10604 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01,
10605 0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0,
10606 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00, 0xC2, 0x88, 0x06, 0x23,
10607 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0,
10608 0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61,
10609 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC, 0x4F, 0x00, 0x84, 0x97,
10610 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80,
10611 0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
10612 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88, 0x04, 0x98, 0xF0, 0x80,
10613 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6,
10614 0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95,
10615 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02, 0x07, 0xA6, 0x5A, 0x02,
10616 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96,
10617 0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC,
10618 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01, 0x6F, 0x00, 0xA5, 0x01,
10619 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02,
10620 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02,
10621 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E, 0x80, 0x63, 0x00, 0x43,
10622 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01,
10623 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82,
10624 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8, 0x00, 0x33, 0x1F, 0x00,
10625 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6,
10626 0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6,
10627 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xEE, 0x82,
10628 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8,
10629 0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98,
10630 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6, 0x3C, 0x04, 0x06, 0xA6,
10631 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83,
10632 0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33,
10633 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05, 0xFF, 0xA2, 0x7A, 0x03,
10634 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03,
10635 0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03,
10636 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6, 0xA4, 0x03, 0x00, 0xA6,
10637 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03,
10638 0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42,
10639 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95, 0xC0, 0x83, 0x00, 0x33,
10640 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23,
10641 0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
10642 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04, 0x06, 0xA6, 0x0A, 0x04,
10643 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84,
10644 0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
10645 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6, 0x38, 0x04, 0x00, 0x33,
10646 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC,
10647 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
10648 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0xA3, 0x01,
10649 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00,
10650 0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
10651 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04, 0x08, 0x23, 0x22, 0xA3,
10652 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23,
10653 0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98,
10654 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20, 0x81, 0x62, 0xE8, 0x81,
10655 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81,
10656 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23,
10657 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3, 0xF4, 0x04, 0x00, 0x33,
10658 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01,
10659 0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
10660 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85, 0x46, 0x97, 0xCD, 0x04,
10661 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85,
10662 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
10663 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x49, 0x00, 0x81, 0x01,
10664 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01,
10665 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
10666 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63, 0x07, 0xA4, 0xF8, 0x05,
10667 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0,
10668 0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
10669 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00, 0x62, 0x97, 0x04, 0x85,
10670 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0,
10671 0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
10672 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05, 0x80, 0x67, 0x80, 0x63,
10673 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23,
10674 0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
10675 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23, 0x07, 0x41, 0x83, 0x03,
10676 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6,
10677 0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
10678 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00, 0x52, 0x00, 0x06, 0x61,
10679 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01,
10680 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
10681 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23, 0xDF, 0x00, 0x06, 0xA6,
10682 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20,
10683 0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
10684 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B, 0x40, 0x0E, 0x80, 0x63,
10685 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43,
10686 0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
10687 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x07, 0xA6, 0xD6, 0x06,
10688 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6,
10689 0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
10690 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20, 0x81, 0x62, 0x04, 0x01,
10691 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33,
10692 0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
10693 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88, 0x00, 0x00, 0x80, 0x67,
10694 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61,
10695 0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
10696 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04, 0x80, 0x05, 0x81, 0x05,
10697 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01,
10698 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
10699 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01, 0xF1, 0x00, 0x70, 0x00,
10700 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00,
10701 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
10702 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1, 0xC4, 0x07, 0x00, 0x33,
10703 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01,
10704 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
10705 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x05, 0x05, 0x00, 0x63,
10706 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02,
10707 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
10708 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63, 0xF3, 0x04,
10709 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08,
10710 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
10711 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04, 0x5A, 0x88, 0x02, 0x01,
10712 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08,
10713 0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
10714 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x38, 0x2B,
10715 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09,
10716 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
10717 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32, 0x40, 0x36, 0x40, 0x3A,
10718 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3,
10719 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
10720 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01, 0xA1, 0x23, 0xA1, 0x01,
10721 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2,
10722 0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
10725 STATIC ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
10726 STATIC ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
10728 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
10729 STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] =
10731 INQUIRY,
10732 REQUEST_SENSE,
10733 READ_CAPACITY,
10734 READ_TOC,
10735 MODE_SELECT,
10736 MODE_SENSE,
10737 MODE_SELECT_10,
10738 MODE_SENSE_10,
10739 0xFF,
10740 0xFF,
10741 0xFF,
10742 0xFF,
10743 0xFF,
10744 0xFF,
10745 0xFF,
10746 0xFF
10749 STATIC int
10750 AscExeScsiQueue(
10751 ASC_DVC_VAR *asc_dvc,
10752 ASC_SCSI_Q *scsiq
10755 PortAddr iop_base;
10756 ulong last_int_level;
10757 int sta;
10758 int n_q_required;
10759 int disable_syn_offset_one_fix;
10760 int i;
10761 ASC_PADDR addr;
10762 ASC_EXE_CALLBACK asc_exe_callback;
10763 ushort sg_entry_cnt = 0;
10764 ushort sg_entry_cnt_minus_one = 0;
10765 uchar target_ix;
10766 uchar tid_no;
10767 uchar sdtr_data;
10768 uchar extra_bytes;
10769 uchar scsi_cmd;
10770 uchar disable_cmd;
10771 ASC_SG_HEAD *sg_head;
10772 ASC_DCNT data_cnt;
10774 iop_base = asc_dvc->iop_base;
10775 sg_head = scsiq->sg_head;
10776 asc_exe_callback = asc_dvc->exe_callback;
10777 if (asc_dvc->err_code != 0)
10778 return (ERR);
10779 if (scsiq == (ASC_SCSI_Q *) 0L) {
10780 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
10781 return (ERR);
10783 scsiq->q1.q_no = 0;
10784 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
10785 scsiq->q1.extra_bytes = 0;
10787 sta = 0;
10788 target_ix = scsiq->q2.target_ix;
10789 tid_no = ASC_TIX_TO_TID(target_ix);
10790 n_q_required = 1;
10791 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
10792 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
10793 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
10794 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10795 AscMsgOutSDTR(asc_dvc,
10796 asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
10797 (uchar) (asc_dvc->max_sdtr_index - 1)],
10798 (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
10799 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
10802 last_int_level = DvcEnterCritical();
10803 if (asc_dvc->in_critical_cnt != 0) {
10804 DvcLeaveCritical(last_int_level);
10805 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
10806 return (ERR);
10808 asc_dvc->in_critical_cnt++;
10809 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10810 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
10811 asc_dvc->in_critical_cnt--;
10812 DvcLeaveCritical(last_int_level);
10813 return (ERR);
10815 #if !CC_VERY_LONG_SG_LIST
10816 if (sg_entry_cnt > ASC_MAX_SG_LIST)
10818 asc_dvc->in_critical_cnt--;
10819 DvcLeaveCritical(last_int_level);
10820 return(ERR);
10822 #endif /* !CC_VERY_LONG_SG_LIST */
10823 if (sg_entry_cnt == 1) {
10824 scsiq->q1.data_addr = (ADV_PADDR) sg_head->sg_list[0].addr;
10825 scsiq->q1.data_cnt = (ADV_DCNT) sg_head->sg_list[0].bytes;
10826 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
10828 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
10830 scsi_cmd = scsiq->cdbptr[0];
10831 disable_syn_offset_one_fix = FALSE;
10832 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
10833 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
10834 if (scsiq->q1.cntl & QC_SG_HEAD) {
10835 data_cnt = 0;
10836 for (i = 0; i < sg_entry_cnt; i++) {
10837 data_cnt += (ADV_DCNT) le32_to_cpu(sg_head->sg_list[i].bytes);
10839 } else {
10840 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
10842 if (data_cnt != 0UL) {
10843 if (data_cnt < 512UL) {
10844 disable_syn_offset_one_fix = TRUE;
10845 } else {
10846 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST; i++) {
10847 disable_cmd = _syn_offset_one_disable_cmd[i];
10848 if (disable_cmd == 0xFF) {
10849 break;
10851 if (scsi_cmd == disable_cmd) {
10852 disable_syn_offset_one_fix = TRUE;
10853 break;
10859 if (disable_syn_offset_one_fix) {
10860 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
10861 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
10862 ASC_TAG_FLAG_DISABLE_DISCONNECT);
10863 } else {
10864 scsiq->q2.tag_code &= 0x27;
10866 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10867 if (asc_dvc->bug_fix_cntl) {
10868 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10869 if ((scsi_cmd == READ_6) ||
10870 (scsi_cmd == READ_10)) {
10871 addr =
10872 (ADV_PADDR) le32_to_cpu(
10873 sg_head->sg_list[sg_entry_cnt_minus_one].addr) +
10874 (ADV_DCNT) le32_to_cpu(
10875 sg_head->sg_list[sg_entry_cnt_minus_one].bytes);
10876 extra_bytes = (uchar) ((ushort) addr & 0x0003);
10877 if ((extra_bytes != 0) &&
10878 ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
10879 == 0)) {
10880 scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
10881 scsiq->q1.extra_bytes = extra_bytes;
10882 data_cnt = le32_to_cpu(
10883 sg_head->sg_list[sg_entry_cnt_minus_one].bytes);
10884 data_cnt -= (ASC_DCNT) extra_bytes;
10885 sg_head->sg_list[sg_entry_cnt_minus_one].bytes =
10886 cpu_to_le32(data_cnt);
10891 sg_head->entry_to_copy = sg_head->entry_cnt;
10892 #if CC_VERY_LONG_SG_LIST
10894 * Set the sg_entry_cnt to the maximum possible. The rest of
10895 * the SG elements will be copied when the RISC completes the
10896 * SG elements that fit and halts.
10898 if (sg_entry_cnt > ASC_MAX_SG_LIST)
10900 sg_entry_cnt = ASC_MAX_SG_LIST;
10902 #endif /* CC_VERY_LONG_SG_LIST */
10903 n_q_required = AscSgListToQueue(sg_entry_cnt);
10904 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
10905 (uint) n_q_required) || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
10906 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
10907 n_q_required)) == 1) {
10908 asc_dvc->in_critical_cnt--;
10909 if (asc_exe_callback != 0) {
10910 (*asc_exe_callback) (asc_dvc, scsiq);
10912 DvcLeaveCritical(last_int_level);
10913 return (sta);
10916 } else {
10917 if (asc_dvc->bug_fix_cntl) {
10918 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10919 if ((scsi_cmd == READ_6) ||
10920 (scsi_cmd == READ_10)) {
10921 addr = le32_to_cpu(scsiq->q1.data_addr) +
10922 le32_to_cpu(scsiq->q1.data_cnt);
10923 extra_bytes = (uchar) ((ushort) addr & 0x0003);
10924 if ((extra_bytes != 0) &&
10925 ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
10926 == 0)) {
10927 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
10928 if (((ushort) data_cnt & 0x01FF) == 0) {
10929 scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
10930 data_cnt -= (ASC_DCNT) extra_bytes;
10931 scsiq->q1.data_cnt = cpu_to_le32(data_cnt);
10932 scsiq->q1.extra_bytes = extra_bytes;
10938 n_q_required = 1;
10939 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
10940 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
10941 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
10942 n_q_required)) == 1) {
10943 asc_dvc->in_critical_cnt--;
10944 if (asc_exe_callback != 0) {
10945 (*asc_exe_callback) (asc_dvc, scsiq);
10947 DvcLeaveCritical(last_int_level);
10948 return (sta);
10952 asc_dvc->in_critical_cnt--;
10953 DvcLeaveCritical(last_int_level);
10954 return (sta);
10957 STATIC int
10958 AscSendScsiQueue(
10959 ASC_DVC_VAR *asc_dvc,
10960 ASC_SCSI_Q *scsiq,
10961 uchar n_q_required
10964 PortAddr iop_base;
10965 uchar free_q_head;
10966 uchar next_qp;
10967 uchar tid_no;
10968 uchar target_ix;
10969 int sta;
10971 iop_base = asc_dvc->iop_base;
10972 target_ix = scsiq->q2.target_ix;
10973 tid_no = ASC_TIX_TO_TID(target_ix);
10974 sta = 0;
10975 free_q_head = (uchar) AscGetVarFreeQHead(iop_base);
10976 if (n_q_required > 1) {
10977 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
10978 free_q_head, (uchar) (n_q_required)))
10979 != (uchar) ASC_QLINK_END) {
10980 asc_dvc->last_q_shortage = 0;
10981 scsiq->sg_head->queue_cnt = n_q_required - 1;
10982 scsiq->q1.q_no = free_q_head;
10983 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
10984 free_q_head)) == 1) {
10985 AscPutVarFreeQHead(iop_base, next_qp);
10986 asc_dvc->cur_total_qng += (uchar) (n_q_required);
10987 asc_dvc->cur_dvc_qng[tid_no]++;
10989 return (sta);
10991 } else if (n_q_required == 1) {
10992 if ((next_qp = AscAllocFreeQueue(iop_base,
10993 free_q_head)) != ASC_QLINK_END) {
10994 scsiq->q1.q_no = free_q_head;
10995 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
10996 free_q_head)) == 1) {
10997 AscPutVarFreeQHead(iop_base, next_qp);
10998 asc_dvc->cur_total_qng++;
10999 asc_dvc->cur_dvc_qng[tid_no]++;
11001 return (sta);
11004 return (sta);
11007 STATIC int
11008 AscSgListToQueue(
11009 int sg_list
11012 int n_sg_list_qs;
11014 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
11015 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
11016 n_sg_list_qs++;
11017 return (n_sg_list_qs + 1);
11021 STATIC uint
11022 AscGetNumOfFreeQueue(
11023 ASC_DVC_VAR *asc_dvc,
11024 uchar target_ix,
11025 uchar n_qs
11028 uint cur_used_qs;
11029 uint cur_free_qs;
11030 ASC_SCSI_BIT_ID_TYPE target_id;
11031 uchar tid_no;
11033 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
11034 tid_no = ASC_TIX_TO_TID(target_ix);
11035 if ((asc_dvc->unit_not_ready & target_id) ||
11036 (asc_dvc->queue_full_or_busy & target_id)) {
11037 return (0);
11039 if (n_qs == 1) {
11040 cur_used_qs = (uint) asc_dvc->cur_total_qng +
11041 (uint) asc_dvc->last_q_shortage +
11042 (uint) ASC_MIN_FREE_Q;
11043 } else {
11044 cur_used_qs = (uint) asc_dvc->cur_total_qng +
11045 (uint) ASC_MIN_FREE_Q;
11047 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
11048 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
11049 if (asc_dvc->cur_dvc_qng[tid_no] >=
11050 asc_dvc->max_dvc_qng[tid_no]) {
11051 return (0);
11053 return (cur_free_qs);
11055 if (n_qs > 1) {
11056 if ((n_qs > asc_dvc->last_q_shortage) && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
11057 asc_dvc->last_q_shortage = n_qs;
11060 return (0);
11063 STATIC int
11064 AscPutReadyQueue(
11065 ASC_DVC_VAR *asc_dvc,
11066 ASC_SCSI_Q *scsiq,
11067 uchar q_no
11070 ushort q_addr;
11071 uchar tid_no;
11072 uchar sdtr_data;
11073 uchar syn_period_ix;
11074 uchar syn_offset;
11075 PortAddr iop_base;
11077 iop_base = asc_dvc->iop_base;
11078 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
11079 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
11080 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
11081 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
11082 syn_period_ix = (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
11083 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
11084 AscMsgOutSDTR(asc_dvc,
11085 asc_dvc->sdtr_period_tbl[syn_period_ix],
11086 syn_offset);
11087 scsiq->q1.cntl |= QC_MSG_OUT;
11089 q_addr = ASC_QNO_TO_QADDR(q_no);
11090 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
11091 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG ;
11093 scsiq->q1.status = QS_FREE;
11094 AscMemWordCopyPtrToLram(iop_base,
11095 q_addr + ASC_SCSIQ_CDB_BEG,
11096 (uchar *) scsiq->cdbptr,
11097 scsiq->q2.cdb_len >> 1);
11099 DvcPutScsiQ(iop_base,
11100 q_addr + ASC_SCSIQ_CPY_BEG,
11101 (uchar *) &scsiq->q1.cntl,
11102 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
11103 AscWriteLramWord(iop_base,
11104 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
11105 (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY));
11106 return (1);
11109 STATIC int
11110 AscPutReadySgListQueue(
11111 ASC_DVC_VAR *asc_dvc,
11112 ASC_SCSI_Q *scsiq,
11113 uchar q_no
11116 int sta;
11117 int i;
11118 ASC_SG_HEAD *sg_head;
11119 ASC_SG_LIST_Q scsi_sg_q;
11120 ASC_DCNT saved_data_addr;
11121 ASC_DCNT saved_data_cnt;
11122 PortAddr iop_base;
11123 ushort sg_list_dwords;
11124 ushort sg_index;
11125 ushort sg_entry_cnt;
11126 ushort q_addr;
11127 uchar next_qp;
11129 iop_base = asc_dvc->iop_base;
11130 sg_head = scsiq->sg_head;
11131 saved_data_addr = scsiq->q1.data_addr;
11132 saved_data_cnt = scsiq->q1.data_cnt;
11133 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
11134 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
11135 #if CC_VERY_LONG_SG_LIST
11137 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
11138 * then not all SG elements will fit in the allocated queues.
11139 * The rest of the SG elements will be copied when the RISC
11140 * completes the SG elements that fit and halts.
11142 if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
11145 * Set sg_entry_cnt to be the number of SG elements that
11146 * will fit in the allocated SG queues. It is minus 1, because
11147 * the first SG element is handled above. ASC_MAX_SG_LIST is
11148 * already inflated by 1 to account for this. For example it
11149 * may be 50 which is 1 + 7 queues * 7 SG elements.
11151 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
11154 * Keep track of remaining number of SG elements that will
11155 * need to be handled from a_isr.c.
11157 scsiq->remain_sg_entry_cnt = sg_head->entry_cnt - ASC_MAX_SG_LIST;
11158 } else
11160 #endif /* CC_VERY_LONG_SG_LIST */
11162 * Set sg_entry_cnt to be the number of SG elements that
11163 * will fit in the allocated SG queues. It is minus 1, because
11164 * the first SG element is handled above.
11166 sg_entry_cnt = sg_head->entry_cnt - 1;
11167 #if CC_VERY_LONG_SG_LIST
11169 #endif /* CC_VERY_LONG_SG_LIST */
11170 if (sg_entry_cnt != 0) {
11171 scsiq->q1.cntl |= QC_SG_HEAD;
11172 q_addr = ASC_QNO_TO_QADDR(q_no);
11173 sg_index = 1;
11174 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
11175 scsi_sg_q.sg_head_qp = q_no;
11176 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
11177 for (i = 0; i < sg_head->queue_cnt; i++) {
11178 scsi_sg_q.seq_no = i + 1;
11179 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
11180 sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
11181 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
11182 if (i == 0) {
11183 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q;
11184 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q;
11185 } else {
11186 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
11187 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
11189 } else {
11190 #if CC_VERY_LONG_SG_LIST
11192 * This is the last SG queue in the list of
11193 * allocated SG queues. If there are more
11194 * SG elements than will fit in the allocated
11195 * queues, then set the QCSG_SG_XFER_MORE flag.
11197 if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
11199 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
11200 } else
11202 #endif /* CC_VERY_LONG_SG_LIST */
11203 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
11204 #if CC_VERY_LONG_SG_LIST
11206 #endif /* CC_VERY_LONG_SG_LIST */
11207 sg_list_dwords = sg_entry_cnt << 1;
11208 if (i == 0) {
11209 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
11210 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt;
11211 } else {
11212 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
11213 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
11215 sg_entry_cnt = 0;
11217 next_qp = AscReadLramByte(iop_base,
11218 (ushort) (q_addr + ASC_SCSIQ_B_FWD));
11219 scsi_sg_q.q_no = next_qp;
11220 q_addr = ASC_QNO_TO_QADDR(next_qp);
11221 AscMemWordCopyPtrToLram(iop_base,
11222 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
11223 (uchar *) &scsi_sg_q,
11224 sizeof(ASC_SG_LIST_Q) >> 1);
11225 AscMemDWordCopyPtrToLram(iop_base,
11226 q_addr + ASC_SGQ_LIST_BEG,
11227 (uchar *) &sg_head->sg_list[sg_index],
11228 sg_list_dwords);
11229 sg_index += ASC_SG_LIST_PER_Q;
11230 scsiq->next_sg_index = sg_index;
11232 } else {
11233 scsiq->q1.cntl &= ~QC_SG_HEAD;
11235 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
11236 scsiq->q1.data_addr = saved_data_addr;
11237 scsiq->q1.data_cnt = saved_data_cnt;
11238 return (sta);
11241 STATIC int
11242 AscSetRunChipSynRegAtID(
11243 PortAddr iop_base,
11244 uchar tid_no,
11245 uchar sdtr_data
11248 int sta = FALSE;
11250 if (AscHostReqRiscHalt(iop_base)) {
11251 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
11252 AscStartChip(iop_base);
11253 return (sta);
11255 return (sta);
11258 STATIC int
11259 AscSetChipSynRegAtID(
11260 PortAddr iop_base,
11261 uchar id,
11262 uchar sdtr_data
11265 ASC_SCSI_BIT_ID_TYPE org_id;
11266 int i;
11267 int sta = TRUE;
11269 AscSetBank(iop_base, 1);
11270 org_id = AscReadChipDvcID(iop_base);
11271 for (i = 0; i <= ASC_MAX_TID; i++) {
11272 if (org_id == (0x01 << i))
11273 break;
11275 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
11276 AscWriteChipDvcID(iop_base, id);
11277 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
11278 AscSetBank(iop_base, 0);
11279 AscSetChipSyn(iop_base, sdtr_data);
11280 if (AscGetChipSyn(iop_base) != sdtr_data) {
11281 sta = FALSE;
11283 } else {
11284 sta = FALSE;
11286 AscSetBank(iop_base, 1);
11287 AscWriteChipDvcID(iop_base, org_id);
11288 AscSetBank(iop_base, 0);
11289 return (sta);
11292 STATIC ushort
11293 AscInitLram(
11294 ASC_DVC_VAR *asc_dvc
11297 uchar i;
11298 ushort s_addr;
11299 PortAddr iop_base;
11300 ushort warn_code;
11302 iop_base = asc_dvc->iop_base;
11303 warn_code = 0;
11304 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
11305 (ushort) (((int) (asc_dvc->max_total_qng + 2 + 1) * 64) >> 1)
11307 i = ASC_MIN_ACTIVE_QNO;
11308 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
11309 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11310 (uchar) (i + 1));
11311 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11312 (uchar) (asc_dvc->max_total_qng));
11313 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11314 (uchar) i);
11315 i++;
11316 s_addr += ASC_QBLK_SIZE;
11317 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
11318 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11319 (uchar) (i + 1));
11320 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11321 (uchar) (i - 1));
11322 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11323 (uchar) i);
11325 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11326 (uchar) ASC_QLINK_END);
11327 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11328 (uchar) (asc_dvc->max_total_qng - 1));
11329 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11330 (uchar) asc_dvc->max_total_qng);
11331 i++;
11332 s_addr += ASC_QBLK_SIZE;
11333 for (; i <= (uchar) (asc_dvc->max_total_qng + 3);
11334 i++, s_addr += ASC_QBLK_SIZE) {
11335 AscWriteLramByte(iop_base,
11336 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_FWD), i);
11337 AscWriteLramByte(iop_base,
11338 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_BWD), i);
11339 AscWriteLramByte(iop_base,
11340 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_QNO), i);
11342 return (warn_code);
11345 STATIC ushort
11346 AscInitQLinkVar(
11347 ASC_DVC_VAR *asc_dvc
11350 PortAddr iop_base;
11351 int i;
11352 ushort lram_addr;
11354 iop_base = asc_dvc->iop_base;
11355 AscPutRiscVarFreeQHead(iop_base, 1);
11356 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
11357 AscPutVarFreeQHead(iop_base, 1);
11358 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
11359 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
11360 (uchar) ((int) asc_dvc->max_total_qng + 1));
11361 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
11362 (uchar) ((int) asc_dvc->max_total_qng + 2));
11363 AscWriteLramByte(iop_base, (ushort) ASCV_TOTAL_READY_Q_B,
11364 asc_dvc->max_total_qng);
11365 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
11366 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
11367 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
11368 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
11369 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
11370 AscPutQDoneInProgress(iop_base, 0);
11371 lram_addr = ASC_QADR_BEG;
11372 for (i = 0; i < 32; i++, lram_addr += 2) {
11373 AscWriteLramWord(iop_base, lram_addr, 0);
11375 return (0);
11378 STATIC int
11379 AscSetLibErrorCode(
11380 ASC_DVC_VAR *asc_dvc,
11381 ushort err_code
11384 if (asc_dvc->err_code == 0) {
11385 asc_dvc->err_code = err_code;
11386 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
11387 err_code);
11389 return (err_code);
11393 STATIC uchar
11394 AscMsgOutSDTR(
11395 ASC_DVC_VAR *asc_dvc,
11396 uchar sdtr_period,
11397 uchar sdtr_offset
11400 EXT_MSG sdtr_buf;
11401 uchar sdtr_period_index;
11402 PortAddr iop_base;
11404 iop_base = asc_dvc->iop_base;
11405 sdtr_buf.msg_type = MS_EXTEND;
11406 sdtr_buf.msg_len = MS_SDTR_LEN;
11407 sdtr_buf.msg_req = MS_SDTR_CODE;
11408 sdtr_buf.xfer_period = sdtr_period;
11409 sdtr_offset &= ASC_SYN_MAX_OFFSET;
11410 sdtr_buf.req_ack_offset = sdtr_offset;
11411 if ((sdtr_period_index =
11412 AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
11413 asc_dvc->max_sdtr_index) {
11414 AscMemWordCopyPtrToLram(iop_base,
11415 ASCV_MSGOUT_BEG,
11416 (uchar *) &sdtr_buf,
11417 sizeof (EXT_MSG) >> 1);
11418 return ((sdtr_period_index << 4) | sdtr_offset);
11419 } else {
11421 sdtr_buf.req_ack_offset = 0;
11422 AscMemWordCopyPtrToLram(iop_base,
11423 ASCV_MSGOUT_BEG,
11424 (uchar *) &sdtr_buf,
11425 sizeof (EXT_MSG) >> 1);
11426 return (0);
11430 STATIC uchar
11431 AscCalSDTRData(
11432 ASC_DVC_VAR *asc_dvc,
11433 uchar sdtr_period,
11434 uchar syn_offset
11437 uchar byte;
11438 uchar sdtr_period_ix;
11440 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
11441 if (
11442 (sdtr_period_ix > asc_dvc->max_sdtr_index)
11444 return (0xFF);
11446 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
11447 return (byte);
11450 STATIC void
11451 AscSetChipSDTR(
11452 PortAddr iop_base,
11453 uchar sdtr_data,
11454 uchar tid_no
11457 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
11458 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
11459 return;
11462 STATIC uchar
11463 AscGetSynPeriodIndex(
11464 ASC_DVC_VAR *asc_dvc,
11465 uchar syn_time
11468 uchar *period_table;
11469 int max_index;
11470 int min_index;
11471 int i;
11473 period_table = asc_dvc->sdtr_period_tbl;
11474 max_index = (int) asc_dvc->max_sdtr_index;
11475 min_index = (int)asc_dvc->host_init_sdtr_index;
11476 if ((syn_time <= period_table[max_index])) {
11477 for (i = min_index; i < (max_index - 1); i++) {
11478 if (syn_time <= period_table[i]) {
11479 return ((uchar) i);
11482 return ((uchar) max_index);
11483 } else {
11484 return ((uchar) (max_index + 1));
11488 STATIC uchar
11489 AscAllocFreeQueue(
11490 PortAddr iop_base,
11491 uchar free_q_head
11494 ushort q_addr;
11495 uchar next_qp;
11496 uchar q_status;
11498 q_addr = ASC_QNO_TO_QADDR(free_q_head);
11499 q_status = (uchar) AscReadLramByte(iop_base,
11500 (ushort) (q_addr + ASC_SCSIQ_B_STATUS));
11501 next_qp = AscReadLramByte(iop_base,
11502 (ushort) (q_addr + ASC_SCSIQ_B_FWD));
11503 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
11504 return (next_qp);
11506 return (ASC_QLINK_END);
11509 STATIC uchar
11510 AscAllocMultipleFreeQueue(
11511 PortAddr iop_base,
11512 uchar free_q_head,
11513 uchar n_free_q
11516 uchar i;
11518 for (i = 0; i < n_free_q; i++) {
11519 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
11520 == ASC_QLINK_END) {
11521 return (ASC_QLINK_END);
11524 return (free_q_head);
11527 STATIC int
11528 AscHostReqRiscHalt(
11529 PortAddr iop_base
11532 int count = 0;
11533 int sta = 0;
11534 uchar saved_stop_code;
11536 if (AscIsChipHalted(iop_base))
11537 return (1);
11538 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
11539 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11540 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP
11542 do {
11543 if (AscIsChipHalted(iop_base)) {
11544 sta = 1;
11545 break;
11547 DvcSleepMilliSecond(100);
11548 } while (count++ < 20);
11549 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
11550 return (sta);
11553 STATIC int
11554 AscStopQueueExe(
11555 PortAddr iop_base
11558 int count = 0;
11560 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
11561 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11562 ASC_STOP_REQ_RISC_STOP);
11563 do {
11564 if (
11565 AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
11566 ASC_STOP_ACK_RISC_STOP) {
11567 return (1);
11569 DvcSleepMilliSecond(100);
11570 } while (count++ < 20);
11572 return (0);
11575 STATIC void
11576 DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
11578 udelay(micro_sec);
11581 STATIC void
11582 DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
11584 udelay((nano_sec + 999)/1000);
11587 #ifdef CONFIG_ISA
11588 STATIC ASC_DCNT __init
11589 AscGetEisaProductID(
11590 PortAddr iop_base)
11592 PortAddr eisa_iop;
11593 ushort product_id_high, product_id_low;
11594 ASC_DCNT product_id;
11596 eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
11597 product_id_low = inpw(eisa_iop);
11598 product_id_high = inpw(eisa_iop + 2);
11599 product_id = ((ASC_DCNT) product_id_high << 16) |
11600 (ASC_DCNT) product_id_low;
11601 return (product_id);
11604 STATIC PortAddr __init
11605 AscSearchIOPortAddrEISA(
11606 PortAddr iop_base)
11608 ASC_DCNT eisa_product_id;
11610 if (iop_base == 0) {
11611 iop_base = ASC_EISA_MIN_IOP_ADDR;
11612 } else {
11613 if (iop_base == ASC_EISA_MAX_IOP_ADDR)
11614 return (0);
11615 if ((iop_base & 0x0050) == 0x0050) {
11616 iop_base += ASC_EISA_BIG_IOP_GAP;
11617 } else {
11618 iop_base += ASC_EISA_SMALL_IOP_GAP;
11621 while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
11622 eisa_product_id = AscGetEisaProductID(iop_base);
11623 if ((eisa_product_id == ASC_EISA_ID_740) ||
11624 (eisa_product_id == ASC_EISA_ID_750)) {
11625 if (AscFindSignature(iop_base)) {
11626 inpw(iop_base + 4);
11627 return (iop_base);
11630 if (iop_base == ASC_EISA_MAX_IOP_ADDR)
11631 return (0);
11632 if ((iop_base & 0x0050) == 0x0050) {
11633 iop_base += ASC_EISA_BIG_IOP_GAP;
11634 } else {
11635 iop_base += ASC_EISA_SMALL_IOP_GAP;
11638 return (0);
11640 #endif /* CONFIG_ISA */
11642 STATIC int
11643 AscStartChip(
11644 PortAddr iop_base
11647 AscSetChipControl(iop_base, 0);
11648 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
11649 return (0);
11651 return (1);
11654 STATIC int
11655 AscStopChip(
11656 PortAddr iop_base
11659 uchar cc_val;
11661 cc_val = AscGetChipControl(iop_base) & (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
11662 AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT));
11663 AscSetChipIH(iop_base, INS_HALT);
11664 AscSetChipIH(iop_base, INS_RFLAG_WTM);
11665 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
11666 return (0);
11668 return (1);
11671 STATIC int
11672 AscIsChipHalted(
11673 PortAddr iop_base
11676 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
11677 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
11678 return (1);
11681 return (0);
11684 STATIC void
11685 AscSetChipIH(
11686 PortAddr iop_base,
11687 ushort ins_code
11690 AscSetBank(iop_base, 1);
11691 AscWriteChipIH(iop_base, ins_code);
11692 AscSetBank(iop_base, 0);
11693 return;
11696 STATIC void
11697 AscAckInterrupt(
11698 PortAddr iop_base
11701 uchar host_flag;
11702 uchar risc_flag;
11703 ushort loop;
11705 loop = 0;
11706 do {
11707 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
11708 if (loop++ > 0x7FFF) {
11709 break;
11711 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
11712 host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
11713 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
11714 (uchar) (host_flag | ASC_HOST_FLAG_ACK_INT));
11715 AscSetChipStatus(iop_base, CIW_INT_ACK);
11716 loop = 0;
11717 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
11718 AscSetChipStatus(iop_base, CIW_INT_ACK);
11719 if (loop++ > 3) {
11720 break;
11723 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
11724 return;
11727 STATIC void
11728 AscDisableInterrupt(
11729 PortAddr iop_base
11732 ushort cfg;
11734 cfg = AscGetChipCfgLsw(iop_base);
11735 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
11736 return;
11739 STATIC void
11740 AscEnableInterrupt(
11741 PortAddr iop_base
11744 ushort cfg;
11746 cfg = AscGetChipCfgLsw(iop_base);
11747 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
11748 return;
11753 STATIC void
11754 AscSetBank(
11755 PortAddr iop_base,
11756 uchar bank
11759 uchar val;
11761 val = AscGetChipControl(iop_base) &
11762 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | CC_CHIP_RESET));
11763 if (bank == 1) {
11764 val |= CC_BANK_ONE;
11765 } else if (bank == 2) {
11766 val |= CC_DIAG | CC_BANK_ONE;
11767 } else {
11768 val &= ~CC_BANK_ONE;
11770 AscSetChipControl(iop_base, val);
11771 return;
11774 STATIC int
11775 AscResetChipAndScsiBus(
11776 ASC_DVC_VAR *asc_dvc
11779 PortAddr iop_base;
11780 int i = 10;
11782 iop_base = asc_dvc->iop_base;
11783 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) && (i-- > 0))
11785 DvcSleepMilliSecond(100);
11787 AscStopChip(iop_base);
11788 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
11789 DvcDelayNanoSecond(asc_dvc, 60000);
11790 AscSetChipIH(iop_base, INS_RFLAG_WTM);
11791 AscSetChipIH(iop_base, INS_HALT);
11792 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
11793 AscSetChipControl(iop_base, CC_HALT);
11794 DvcSleepMilliSecond(200);
11795 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
11796 AscSetChipStatus(iop_base, 0);
11797 return (AscIsChipHalted(iop_base));
11800 STATIC ASC_DCNT __init
11801 AscGetMaxDmaCount(
11802 ushort bus_type)
11804 if (bus_type & ASC_IS_ISA)
11805 return (ASC_MAX_ISA_DMA_COUNT);
11806 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
11807 return (ASC_MAX_VL_DMA_COUNT);
11808 return (ASC_MAX_PCI_DMA_COUNT);
11811 #ifdef CONFIG_ISA
11812 STATIC ushort __init
11813 AscGetIsaDmaChannel(
11814 PortAddr iop_base)
11816 ushort channel;
11818 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
11819 if (channel == 0x03)
11820 return (0);
11821 else if (channel == 0x00)
11822 return (7);
11823 return (channel + 4);
11826 STATIC ushort __init
11827 AscSetIsaDmaChannel(
11828 PortAddr iop_base,
11829 ushort dma_channel)
11831 ushort cfg_lsw;
11832 uchar value;
11834 if ((dma_channel >= 5) && (dma_channel <= 7)) {
11835 if (dma_channel == 7)
11836 value = 0x00;
11837 else
11838 value = dma_channel - 4;
11839 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
11840 cfg_lsw |= value;
11841 AscSetChipCfgLsw(iop_base, cfg_lsw);
11842 return (AscGetIsaDmaChannel(iop_base));
11844 return (0);
11847 STATIC uchar __init
11848 AscSetIsaDmaSpeed(
11849 PortAddr iop_base,
11850 uchar speed_value)
11852 speed_value &= 0x07;
11853 AscSetBank(iop_base, 1);
11854 AscWriteChipDmaSpeed(iop_base, speed_value);
11855 AscSetBank(iop_base, 0);
11856 return (AscGetIsaDmaSpeed(iop_base));
11859 STATIC uchar __init
11860 AscGetIsaDmaSpeed(
11861 PortAddr iop_base
11864 uchar speed_value;
11866 AscSetBank(iop_base, 1);
11867 speed_value = AscReadChipDmaSpeed(iop_base);
11868 speed_value &= 0x07;
11869 AscSetBank(iop_base, 0);
11870 return (speed_value);
11872 #endif /* CONFIG_ISA */
11874 STATIC ushort __init
11875 AscReadPCIConfigWord(
11876 ASC_DVC_VAR *asc_dvc,
11877 ushort pci_config_offset)
11879 uchar lsb, msb;
11881 lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
11882 msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
11883 return ((ushort) ((msb << 8) | lsb));
11886 STATIC ushort __init
11887 AscInitGetConfig(
11888 ASC_DVC_VAR *asc_dvc
11891 ushort warn_code;
11892 PortAddr iop_base;
11893 ushort PCIDeviceID;
11894 ushort PCIVendorID;
11895 uchar PCIRevisionID;
11896 uchar prevCmdRegBits;
11898 warn_code = 0;
11899 iop_base = asc_dvc->iop_base;
11900 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
11901 if (asc_dvc->err_code != 0) {
11902 return (UW_ERR);
11904 if (asc_dvc->bus_type == ASC_IS_PCI) {
11905 PCIVendorID = AscReadPCIConfigWord(asc_dvc,
11906 AscPCIConfigVendorIDRegister);
11908 PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
11909 AscPCIConfigDeviceIDRegister);
11911 PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
11912 AscPCIConfigRevisionIDRegister);
11914 if (PCIVendorID != PCI_VENDOR_ID_ASP) {
11915 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
11917 prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
11918 AscPCIConfigCommandRegister);
11920 if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
11921 AscPCICmdRegBits_IOMemBusMaster) {
11922 DvcWritePCIConfigByte(asc_dvc,
11923 AscPCIConfigCommandRegister,
11924 (prevCmdRegBits |
11925 AscPCICmdRegBits_IOMemBusMaster));
11927 if ((DvcReadPCIConfigByte(asc_dvc,
11928 AscPCIConfigCommandRegister)
11929 & AscPCICmdRegBits_IOMemBusMaster)
11930 != AscPCICmdRegBits_IOMemBusMaster) {
11931 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
11934 if ((PCIDeviceID == PCI_DEVICE_ID_ASP_1200A) ||
11935 (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940)) {
11936 DvcWritePCIConfigByte(asc_dvc,
11937 AscPCIConfigLatencyTimer, 0x00);
11938 if (DvcReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer)
11939 != 0x00) {
11940 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
11942 } else if (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940U) {
11943 if (DvcReadPCIConfigByte(asc_dvc,
11944 AscPCIConfigLatencyTimer) < 0x20) {
11945 DvcWritePCIConfigByte(asc_dvc,
11946 AscPCIConfigLatencyTimer, 0x20);
11948 if (DvcReadPCIConfigByte(asc_dvc,
11949 AscPCIConfigLatencyTimer) < 0x20) {
11950 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
11956 if (AscFindSignature(iop_base)) {
11957 warn_code |= AscInitAscDvcVar(asc_dvc);
11958 warn_code |= AscInitFromEEP(asc_dvc);
11959 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
11960 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
11961 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
11963 } else {
11964 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11966 return(warn_code);
11969 STATIC ushort __init
11970 AscInitSetConfig(
11971 ASC_DVC_VAR *asc_dvc
11974 ushort warn_code = 0;
11976 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
11977 if (asc_dvc->err_code != 0)
11978 return (UW_ERR);
11979 if (AscFindSignature(asc_dvc->iop_base)) {
11980 warn_code |= AscInitFromAscDvcVar(asc_dvc);
11981 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
11982 } else {
11983 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11985 return (warn_code);
11988 STATIC ushort __init
11989 AscInitFromAscDvcVar(
11990 ASC_DVC_VAR *asc_dvc
11993 PortAddr iop_base;
11994 ushort cfg_msw;
11995 ushort warn_code;
11996 ushort pci_device_id = 0;
11998 iop_base = asc_dvc->iop_base;
11999 #ifdef CONFIG_PCI
12000 if (asc_dvc->cfg->dev)
12001 pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device;
12002 #endif
12003 warn_code = 0;
12004 cfg_msw = AscGetChipCfgMsw(iop_base);
12005 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12006 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
12007 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12008 AscSetChipCfgMsw(iop_base, cfg_msw);
12010 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
12011 asc_dvc->cfg->cmd_qng_enabled) {
12012 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
12013 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12015 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12016 warn_code |= ASC_WARN_AUTO_CONFIG;
12018 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
12019 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
12020 != asc_dvc->irq_no) {
12021 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
12024 if (asc_dvc->bus_type & ASC_IS_PCI) {
12025 cfg_msw &= 0xFFC0;
12026 AscSetChipCfgMsw(iop_base, cfg_msw);
12027 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
12028 } else {
12029 if ((pci_device_id == PCI_DEVICE_ID_ASP_1200A) ||
12030 (pci_device_id == PCI_DEVICE_ID_ASP_ABP940)) {
12031 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
12032 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
12035 } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
12036 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
12037 == ASC_CHIP_VER_ASYN_BUG) {
12038 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
12041 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
12042 asc_dvc->cfg->chip_scsi_id) {
12043 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
12045 #ifdef CONFIG_ISA
12046 if (asc_dvc->bus_type & ASC_IS_ISA) {
12047 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
12048 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
12050 #endif /* CONFIG_ISA */
12051 return (warn_code);
12054 STATIC ushort
12055 AscInitAsc1000Driver(
12056 ASC_DVC_VAR *asc_dvc
12059 ushort warn_code;
12060 PortAddr iop_base;
12062 iop_base = asc_dvc->iop_base;
12063 warn_code = 0;
12064 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
12065 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
12066 AscResetChipAndScsiBus(asc_dvc);
12067 DvcSleepMilliSecond((ASC_DCNT)
12068 ((ushort) asc_dvc->scsi_reset_wait * 1000));
12070 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
12071 if (asc_dvc->err_code != 0)
12072 return (UW_ERR);
12073 if (!AscFindSignature(asc_dvc->iop_base)) {
12074 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12075 return (warn_code);
12077 AscDisableInterrupt(iop_base);
12078 warn_code |= AscInitLram(asc_dvc);
12079 if (asc_dvc->err_code != 0)
12080 return (UW_ERR);
12081 ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
12082 (ulong) _asc_mcode_chksum);
12083 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
12084 _asc_mcode_size) != _asc_mcode_chksum) {
12085 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
12086 return (warn_code);
12088 warn_code |= AscInitMicroCodeVar(asc_dvc);
12089 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
12090 AscEnableInterrupt(iop_base);
12091 return (warn_code);
12094 STATIC ushort __init
12095 AscInitAscDvcVar(
12096 ASC_DVC_VAR *asc_dvc)
12098 int i;
12099 PortAddr iop_base;
12100 ushort warn_code;
12101 uchar chip_version;
12103 iop_base = asc_dvc->iop_base;
12104 warn_code = 0;
12105 asc_dvc->err_code = 0;
12106 if ((asc_dvc->bus_type &
12107 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
12108 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
12110 AscSetChipControl(iop_base, CC_HALT);
12111 AscSetChipStatus(iop_base, 0);
12112 asc_dvc->bug_fix_cntl = 0;
12113 asc_dvc->pci_fix_asyn_xfer = 0;
12114 asc_dvc->pci_fix_asyn_xfer_always = 0;
12115 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
12116 asc_dvc->sdtr_done = 0;
12117 asc_dvc->cur_total_qng = 0;
12118 asc_dvc->is_in_int = 0;
12119 asc_dvc->in_critical_cnt = 0;
12120 asc_dvc->last_q_shortage = 0;
12121 asc_dvc->use_tagged_qng = 0;
12122 asc_dvc->no_scam = 0;
12123 asc_dvc->unit_not_ready = 0;
12124 asc_dvc->queue_full_or_busy = 0;
12125 asc_dvc->redo_scam = 0;
12126 asc_dvc->res2 = 0;
12127 asc_dvc->host_init_sdtr_index = 0;
12128 asc_dvc->cfg->can_tagged_qng = 0;
12129 asc_dvc->cfg->cmd_qng_enabled = 0;
12130 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
12131 asc_dvc->init_sdtr = 0;
12132 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
12133 asc_dvc->scsi_reset_wait = 3;
12134 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
12135 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
12136 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
12137 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
12138 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
12139 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
12140 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
12141 ASC_LIB_VERSION_MINOR;
12142 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
12143 asc_dvc->cfg->chip_version = chip_version;
12144 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
12145 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
12146 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
12147 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
12148 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
12149 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
12150 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
12151 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
12152 asc_dvc->max_sdtr_index = 7;
12153 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
12154 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
12155 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
12156 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
12157 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
12158 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
12159 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
12160 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
12161 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
12162 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
12163 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
12164 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
12165 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
12166 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
12167 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
12168 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
12169 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
12170 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
12171 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
12172 asc_dvc->max_sdtr_index = 15;
12173 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150)
12175 AscSetExtraControl(iop_base,
12176 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
12177 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
12178 AscSetExtraControl(iop_base,
12179 (SEC_ACTIVE_NEGATE | SEC_ENABLE_FILTER));
12182 if (asc_dvc->bus_type == ASC_IS_PCI) {
12183 AscSetExtraControl(iop_base, (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
12186 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
12187 if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
12188 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
12189 asc_dvc->bus_type = ASC_IS_ISAPNP;
12191 #ifdef CONFIG_ISA
12192 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
12193 asc_dvc->cfg->isa_dma_channel = (uchar) AscGetIsaDmaChannel(iop_base);
12195 #endif /* CONFIG_ISA */
12196 for (i = 0; i <= ASC_MAX_TID; i++) {
12197 asc_dvc->cur_dvc_qng[i] = 0;
12198 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
12199 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *) 0L;
12200 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *) 0L;
12201 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
12203 return (warn_code);
12206 STATIC ushort __init
12207 AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
12209 ASCEEP_CONFIG eep_config_buf;
12210 ASCEEP_CONFIG *eep_config;
12211 PortAddr iop_base;
12212 ushort chksum;
12213 ushort warn_code;
12214 ushort cfg_msw, cfg_lsw;
12215 int i;
12216 int write_eep = 0;
12218 iop_base = asc_dvc->iop_base;
12219 warn_code = 0;
12220 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
12221 AscStopQueueExe(iop_base);
12222 if ((AscStopChip(iop_base) == FALSE) ||
12223 (AscGetChipScsiCtrl(iop_base) != 0)) {
12224 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
12225 AscResetChipAndScsiBus(asc_dvc);
12226 DvcSleepMilliSecond((ASC_DCNT)
12227 ((ushort) asc_dvc->scsi_reset_wait * 1000));
12229 if (AscIsChipHalted(iop_base) == FALSE) {
12230 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
12231 return (warn_code);
12233 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
12234 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
12235 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
12236 return (warn_code);
12238 eep_config = (ASCEEP_CONFIG *) &eep_config_buf;
12239 cfg_msw = AscGetChipCfgMsw(iop_base);
12240 cfg_lsw = AscGetChipCfgLsw(iop_base);
12241 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12242 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
12243 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12244 AscSetChipCfgMsw(iop_base, cfg_msw);
12246 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
12247 ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
12248 if (chksum == 0) {
12249 chksum = 0xaa55;
12251 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12252 warn_code |= ASC_WARN_AUTO_CONFIG;
12253 if (asc_dvc->cfg->chip_version == 3) {
12254 if (eep_config->cfg_lsw != cfg_lsw) {
12255 warn_code |= ASC_WARN_EEPROM_RECOVER;
12256 eep_config->cfg_lsw = AscGetChipCfgLsw(iop_base);
12258 if (eep_config->cfg_msw != cfg_msw) {
12259 warn_code |= ASC_WARN_EEPROM_RECOVER;
12260 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
12264 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
12265 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
12266 ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
12267 eep_config->chksum);
12268 if (chksum != eep_config->chksum) {
12269 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
12270 ASC_CHIP_VER_PCI_ULTRA_3050 )
12272 ASC_DBG(1,
12273 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
12274 eep_config->init_sdtr = 0xFF;
12275 eep_config->disc_enable = 0xFF;
12276 eep_config->start_motor = 0xFF;
12277 eep_config->use_cmd_qng = 0;
12278 eep_config->max_total_qng = 0xF0;
12279 eep_config->max_tag_qng = 0x20;
12280 eep_config->cntl = 0xBFFF;
12281 ASC_EEP_SET_CHIP_ID(eep_config, 7);
12282 eep_config->no_scam = 0;
12283 eep_config->adapter_info[0] = 0;
12284 eep_config->adapter_info[1] = 0;
12285 eep_config->adapter_info[2] = 0;
12286 eep_config->adapter_info[3] = 0;
12287 eep_config->adapter_info[4] = 0;
12288 /* Indicate EEPROM-less board. */
12289 eep_config->adapter_info[5] = 0xBB;
12290 } else {
12291 ASC_PRINT(
12292 "AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
12293 write_eep = 1;
12294 warn_code |= ASC_WARN_EEPROM_CHKSUM;
12297 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
12298 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
12299 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
12300 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
12301 asc_dvc->start_motor = eep_config->start_motor;
12302 asc_dvc->dvc_cntl = eep_config->cntl;
12303 asc_dvc->no_scam = eep_config->no_scam;
12304 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
12305 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
12306 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
12307 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
12308 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
12309 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
12310 if (!AscTestExternalLram(asc_dvc)) {
12311 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA)) {
12312 eep_config->max_total_qng = ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
12313 eep_config->max_tag_qng = ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
12314 } else {
12315 eep_config->cfg_msw |= 0x0800;
12316 cfg_msw |= 0x0800;
12317 AscSetChipCfgMsw(iop_base, cfg_msw);
12318 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
12319 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
12321 } else {
12323 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
12324 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
12326 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
12327 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
12329 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
12330 eep_config->max_tag_qng = eep_config->max_total_qng;
12332 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
12333 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
12335 asc_dvc->max_total_qng = eep_config->max_total_qng;
12336 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
12337 eep_config->use_cmd_qng) {
12338 eep_config->disc_enable = eep_config->use_cmd_qng;
12339 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12341 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
12342 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
12344 ASC_EEP_SET_CHIP_ID(eep_config, ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
12345 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
12346 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
12347 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
12348 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
12351 for (i = 0; i <= ASC_MAX_TID; i++) {
12352 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
12353 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
12354 asc_dvc->cfg->sdtr_period_offset[i] =
12355 (uchar) (ASC_DEF_SDTR_OFFSET |
12356 (asc_dvc->host_init_sdtr_index << 4));
12358 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
12359 if (write_eep) {
12360 if ((i = AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type)) !=
12361 0) {
12362 ASC_PRINT1(
12363 "AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n", i);
12364 } else {
12365 ASC_PRINT("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
12368 return (warn_code);
12371 STATIC ushort
12372 AscInitMicroCodeVar(
12373 ASC_DVC_VAR *asc_dvc
12376 int i;
12377 ushort warn_code;
12378 PortAddr iop_base;
12379 ASC_PADDR phy_addr;
12380 ASC_DCNT phy_size;
12382 iop_base = asc_dvc->iop_base;
12383 warn_code = 0;
12384 for (i = 0; i <= ASC_MAX_TID; i++) {
12385 AscPutMCodeInitSDTRAtID(iop_base, i,
12386 asc_dvc->cfg->sdtr_period_offset[i]
12390 AscInitQLinkVar(asc_dvc);
12391 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
12392 asc_dvc->cfg->disc_enable);
12393 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
12394 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
12396 /* Align overrun buffer on an 8 byte boundary. */
12397 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
12398 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
12399 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
12400 (uchar *) &phy_addr, 1);
12401 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
12402 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
12403 (uchar *) &phy_size, 1);
12405 asc_dvc->cfg->mcode_date =
12406 AscReadLramWord(iop_base, (ushort) ASCV_MC_DATE_W);
12407 asc_dvc->cfg->mcode_version =
12408 AscReadLramWord(iop_base, (ushort) ASCV_MC_VER_W);
12410 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
12411 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
12412 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
12413 return (warn_code);
12415 if (AscStartChip(iop_base) != 1) {
12416 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
12417 return (warn_code);
12420 return (warn_code);
12423 STATIC int __init
12424 AscTestExternalLram(
12425 ASC_DVC_VAR *asc_dvc)
12427 PortAddr iop_base;
12428 ushort q_addr;
12429 ushort saved_word;
12430 int sta;
12432 iop_base = asc_dvc->iop_base;
12433 sta = 0;
12434 q_addr = ASC_QNO_TO_QADDR(241);
12435 saved_word = AscReadLramWord(iop_base, q_addr);
12436 AscSetChipLramAddr(iop_base, q_addr);
12437 AscSetChipLramData(iop_base, 0x55AA);
12438 DvcSleepMilliSecond(10);
12439 AscSetChipLramAddr(iop_base, q_addr);
12440 if (AscGetChipLramData(iop_base) == 0x55AA) {
12441 sta = 1;
12442 AscWriteLramWord(iop_base, q_addr, saved_word);
12444 return (sta);
12447 STATIC int __init
12448 AscWriteEEPCmdReg(
12449 PortAddr iop_base,
12450 uchar cmd_reg
12453 uchar read_back;
12454 int retry;
12456 retry = 0;
12457 while (TRUE) {
12458 AscSetChipEEPCmd(iop_base, cmd_reg);
12459 DvcSleepMilliSecond(1);
12460 read_back = AscGetChipEEPCmd(iop_base);
12461 if (read_back == cmd_reg) {
12462 return (1);
12464 if (retry++ > ASC_EEP_MAX_RETRY) {
12465 return (0);
12470 STATIC int __init
12471 AscWriteEEPDataReg(
12472 PortAddr iop_base,
12473 ushort data_reg
12476 ushort read_back;
12477 int retry;
12479 retry = 0;
12480 while (TRUE) {
12481 AscSetChipEEPData(iop_base, data_reg);
12482 DvcSleepMilliSecond(1);
12483 read_back = AscGetChipEEPData(iop_base);
12484 if (read_back == data_reg) {
12485 return (1);
12487 if (retry++ > ASC_EEP_MAX_RETRY) {
12488 return (0);
12493 STATIC void __init
12494 AscWaitEEPRead(void)
12496 DvcSleepMilliSecond(1);
12497 return;
12500 STATIC void __init
12501 AscWaitEEPWrite(void)
12503 DvcSleepMilliSecond(20);
12504 return;
12507 STATIC ushort __init
12508 AscReadEEPWord(
12509 PortAddr iop_base,
12510 uchar addr)
12512 ushort read_wval;
12513 uchar cmd_reg;
12515 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
12516 AscWaitEEPRead();
12517 cmd_reg = addr | ASC_EEP_CMD_READ;
12518 AscWriteEEPCmdReg(iop_base, cmd_reg);
12519 AscWaitEEPRead();
12520 read_wval = AscGetChipEEPData(iop_base);
12521 AscWaitEEPRead();
12522 return (read_wval);
12525 STATIC ushort __init
12526 AscWriteEEPWord(
12527 PortAddr iop_base,
12528 uchar addr,
12529 ushort word_val)
12531 ushort read_wval;
12533 read_wval = AscReadEEPWord(iop_base, addr);
12534 if (read_wval != word_val) {
12535 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
12536 AscWaitEEPRead();
12537 AscWriteEEPDataReg(iop_base, word_val);
12538 AscWaitEEPRead();
12539 AscWriteEEPCmdReg(iop_base,
12540 (uchar) ((uchar) ASC_EEP_CMD_WRITE | addr));
12541 AscWaitEEPWrite();
12542 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
12543 AscWaitEEPRead();
12544 return (AscReadEEPWord(iop_base, addr));
12546 return (read_wval);
12549 STATIC ushort __init
12550 AscGetEEPConfig(
12551 PortAddr iop_base,
12552 ASCEEP_CONFIG * cfg_buf, ushort bus_type)
12554 ushort wval;
12555 ushort sum;
12556 ushort *wbuf;
12557 int cfg_beg;
12558 int cfg_end;
12559 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
12560 int s_addr;
12562 wbuf = (ushort *) cfg_buf;
12563 sum = 0;
12564 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
12565 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12566 *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
12567 sum += *wbuf;
12569 if (bus_type & ASC_IS_VL) {
12570 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
12571 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
12572 } else {
12573 cfg_beg = ASC_EEP_DVC_CFG_BEG;
12574 cfg_end = ASC_EEP_MAX_DVC_ADDR;
12576 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
12577 wval = AscReadEEPWord( iop_base, ( uchar )s_addr ) ;
12578 if (s_addr <= uchar_end_in_config) {
12580 * Swap all char fields - must unswap bytes already swapped
12581 * by AscReadEEPWord().
12583 *wbuf = le16_to_cpu(wval);
12584 } else {
12585 /* Don't swap word field at the end - cntl field. */
12586 *wbuf = wval;
12588 sum += wval; /* Checksum treats all EEPROM data as words. */
12591 * Read the checksum word which will be compared against 'sum'
12592 * by the caller. Word field already swapped.
12594 *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
12595 return (sum);
12598 STATIC int __init
12599 AscSetEEPConfigOnce(
12600 PortAddr iop_base,
12601 ASCEEP_CONFIG * cfg_buf, ushort bus_type)
12603 int n_error;
12604 ushort *wbuf;
12605 ushort word;
12606 ushort sum;
12607 int s_addr;
12608 int cfg_beg;
12609 int cfg_end;
12610 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
12613 wbuf = (ushort *) cfg_buf;
12614 n_error = 0;
12615 sum = 0;
12616 /* Write two config words; AscWriteEEPWord() will swap bytes. */
12617 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12618 sum += *wbuf;
12619 if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
12620 n_error++;
12623 if (bus_type & ASC_IS_VL) {
12624 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
12625 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
12626 } else {
12627 cfg_beg = ASC_EEP_DVC_CFG_BEG;
12628 cfg_end = ASC_EEP_MAX_DVC_ADDR;
12630 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
12631 if (s_addr <= uchar_end_in_config) {
12633 * This is a char field. Swap char fields before they are
12634 * swapped again by AscWriteEEPWord().
12636 word = cpu_to_le16(*wbuf);
12637 if (word != AscWriteEEPWord( iop_base, (uchar) s_addr, word)) {
12638 n_error++;
12640 } else {
12641 /* Don't swap word field at the end - cntl field. */
12642 if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
12643 n_error++;
12646 sum += *wbuf; /* Checksum calculated from word values. */
12648 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
12649 *wbuf = sum;
12650 if (sum != AscWriteEEPWord(iop_base, (uchar) s_addr, sum)) {
12651 n_error++;
12654 /* Read EEPROM back again. */
12655 wbuf = (ushort *) cfg_buf;
12657 * Read two config words; Byte-swapping done by AscReadEEPWord().
12659 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12660 if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
12661 n_error++;
12664 if (bus_type & ASC_IS_VL) {
12665 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
12666 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
12667 } else {
12668 cfg_beg = ASC_EEP_DVC_CFG_BEG;
12669 cfg_end = ASC_EEP_MAX_DVC_ADDR;
12671 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
12672 if (s_addr <= uchar_end_in_config) {
12674 * Swap all char fields. Must unswap bytes already swapped
12675 * by AscReadEEPWord().
12677 word = le16_to_cpu(AscReadEEPWord(iop_base, (uchar) s_addr));
12678 } else {
12679 /* Don't swap word field at the end - cntl field. */
12680 word = AscReadEEPWord(iop_base, (uchar) s_addr);
12682 if (*wbuf != word) {
12683 n_error++;
12686 /* Read checksum; Byte swapping not needed. */
12687 if (AscReadEEPWord(iop_base, (uchar) s_addr) != sum) {
12688 n_error++;
12690 return (n_error);
12693 STATIC int __init
12694 AscSetEEPConfig(
12695 PortAddr iop_base,
12696 ASCEEP_CONFIG * cfg_buf, ushort bus_type
12699 int retry;
12700 int n_error;
12702 retry = 0;
12703 while (TRUE) {
12704 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
12705 bus_type)) == 0) {
12706 break;
12708 if (++retry > ASC_EEP_MAX_RETRY) {
12709 break;
12712 return (n_error);
12715 STATIC void
12716 AscAsyncFix(
12717 ASC_DVC_VAR *asc_dvc,
12718 uchar tid_no,
12719 ASC_SCSI_INQUIRY *inq)
12721 uchar dvc_type;
12722 ASC_SCSI_BIT_ID_TYPE tid_bits;
12724 dvc_type = ASC_INQ_DVC_TYPE(inq);
12725 tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
12727 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN)
12729 if (!(asc_dvc->init_sdtr & tid_bits))
12731 if ((dvc_type == TYPE_ROM) &&
12732 (AscCompareString((uchar *) inq->vendor_id,
12733 (uchar *) "HP ", 3) == 0))
12735 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
12737 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
12738 if ((dvc_type == TYPE_PROCESSOR) ||
12739 (dvc_type == TYPE_SCANNER) ||
12740 (dvc_type == TYPE_ROM) ||
12741 (dvc_type == TYPE_TAPE))
12743 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
12746 if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
12748 AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no,
12749 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
12753 return;
12756 STATIC int
12757 AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
12759 if ((inq->add_len >= 32) &&
12760 (AscCompareString((uchar *) inq->vendor_id,
12761 (uchar *) "QUANTUM XP34301", 15) == 0) &&
12762 (AscCompareString((uchar *) inq->product_rev_level,
12763 (uchar *) "1071", 4) == 0))
12765 return 0;
12767 return 1;
12770 STATIC void
12771 AscInquiryHandling(ASC_DVC_VAR *asc_dvc,
12772 uchar tid_no, ASC_SCSI_INQUIRY *inq)
12774 ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
12775 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
12777 orig_init_sdtr = asc_dvc->init_sdtr;
12778 orig_use_tagged_qng = asc_dvc->use_tagged_qng;
12780 asc_dvc->init_sdtr &= ~tid_bit;
12781 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
12782 asc_dvc->use_tagged_qng &= ~tid_bit;
12784 if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) {
12785 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) {
12786 asc_dvc->init_sdtr |= tid_bit;
12788 if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) &&
12789 ASC_INQ_CMD_QUEUE(inq)) {
12790 if (AscTagQueuingSafe(inq)) {
12791 asc_dvc->use_tagged_qng |= tid_bit;
12792 asc_dvc->cfg->can_tagged_qng |= tid_bit;
12796 if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
12797 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
12798 asc_dvc->cfg->disc_enable);
12799 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
12800 asc_dvc->use_tagged_qng);
12801 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
12802 asc_dvc->cfg->can_tagged_qng);
12804 asc_dvc->max_dvc_qng[tid_no] =
12805 asc_dvc->cfg->max_tag_qng[tid_no];
12806 AscWriteLramByte(asc_dvc->iop_base,
12807 (ushort) (ASCV_MAX_DVC_QNG_BEG + tid_no),
12808 asc_dvc->max_dvc_qng[tid_no]);
12810 if (orig_init_sdtr != asc_dvc->init_sdtr) {
12811 AscAsyncFix(asc_dvc, tid_no, inq);
12813 return;
12816 STATIC int
12817 AscCompareString(
12818 uchar *str1,
12819 uchar *str2,
12820 int len
12823 int i;
12824 int diff;
12826 for (i = 0; i < len; i++) {
12827 diff = (int) (str1[i] - str2[i]);
12828 if (diff != 0)
12829 return (diff);
12831 return (0);
12834 STATIC uchar
12835 AscReadLramByte(
12836 PortAddr iop_base,
12837 ushort addr
12840 uchar byte_data;
12841 ushort word_data;
12843 if (isodd_word(addr)) {
12844 AscSetChipLramAddr(iop_base, addr - 1);
12845 word_data = AscGetChipLramData(iop_base);
12846 byte_data = (uchar) ((word_data >> 8) & 0xFF);
12847 } else {
12848 AscSetChipLramAddr(iop_base, addr);
12849 word_data = AscGetChipLramData(iop_base);
12850 byte_data = (uchar) (word_data & 0xFF);
12852 return (byte_data);
12854 STATIC ushort
12855 AscReadLramWord(
12856 PortAddr iop_base,
12857 ushort addr
12860 ushort word_data;
12862 AscSetChipLramAddr(iop_base, addr);
12863 word_data = AscGetChipLramData(iop_base);
12864 return (word_data);
12867 #if CC_VERY_LONG_SG_LIST
12868 STATIC ASC_DCNT
12869 AscReadLramDWord(
12870 PortAddr iop_base,
12871 ushort addr
12874 ushort val_low, val_high;
12875 ASC_DCNT dword_data;
12877 AscSetChipLramAddr(iop_base, addr);
12878 val_low = AscGetChipLramData(iop_base);
12879 val_high = AscGetChipLramData(iop_base);
12880 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
12881 return (dword_data);
12883 #endif /* CC_VERY_LONG_SG_LIST */
12885 STATIC void
12886 AscWriteLramWord(
12887 PortAddr iop_base,
12888 ushort addr,
12889 ushort word_val
12892 AscSetChipLramAddr(iop_base, addr);
12893 AscSetChipLramData(iop_base, word_val);
12894 return;
12897 STATIC void
12898 AscWriteLramByte(
12899 PortAddr iop_base,
12900 ushort addr,
12901 uchar byte_val
12904 ushort word_data;
12906 if (isodd_word(addr)) {
12907 addr--;
12908 word_data = AscReadLramWord(iop_base, addr);
12909 word_data &= 0x00FF;
12910 word_data |= (((ushort) byte_val << 8) & 0xFF00);
12911 } else {
12912 word_data = AscReadLramWord(iop_base, addr);
12913 word_data &= 0xFF00;
12914 word_data |= ((ushort) byte_val & 0x00FF);
12916 AscWriteLramWord(iop_base, addr, word_data);
12917 return;
12921 * Copy 2 bytes to LRAM.
12923 * The source data is assumed to be in little-endian order in memory
12924 * and is maintained in little-endian order when written to LRAM.
12926 STATIC void
12927 AscMemWordCopyPtrToLram(
12928 PortAddr iop_base,
12929 ushort s_addr,
12930 uchar *s_buffer,
12931 int words
12934 int i;
12936 AscSetChipLramAddr(iop_base, s_addr);
12937 for (i = 0; i < 2 * words; i += 2) {
12939 * On a little-endian system the second argument below
12940 * produces a little-endian ushort which is written to
12941 * LRAM in little-endian order. On a big-endian system
12942 * the second argument produces a big-endian ushort which
12943 * is "transparently" byte-swapped by outpw() and written
12944 * in little-endian order to LRAM.
12946 outpw(iop_base + IOP_RAM_DATA,
12947 ((ushort) s_buffer[i + 1] << 8) | s_buffer[i]);
12949 return;
12953 * Copy 4 bytes to LRAM.
12955 * The source data is assumed to be in little-endian order in memory
12956 * and is maintained in little-endian order when writen to LRAM.
12958 STATIC void
12959 AscMemDWordCopyPtrToLram(
12960 PortAddr iop_base,
12961 ushort s_addr,
12962 uchar *s_buffer,
12963 int dwords
12966 int i;
12968 AscSetChipLramAddr(iop_base, s_addr);
12969 for (i = 0; i < 4 * dwords; i += 4) {
12970 outpw(iop_base + IOP_RAM_DATA,
12971 ((ushort) s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
12972 outpw(iop_base + IOP_RAM_DATA,
12973 ((ushort) s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
12975 return;
12979 * Copy 2 bytes from LRAM.
12981 * The source data is assumed to be in little-endian order in LRAM
12982 * and is maintained in little-endian order when written to memory.
12984 STATIC void
12985 AscMemWordCopyPtrFromLram(
12986 PortAddr iop_base,
12987 ushort s_addr,
12988 uchar *d_buffer,
12989 int words
12992 int i;
12993 ushort word;
12995 AscSetChipLramAddr(iop_base, s_addr);
12996 for (i = 0; i < 2 * words; i += 2) {
12997 word = inpw(iop_base + IOP_RAM_DATA);
12998 d_buffer[i] = word & 0xff;
12999 d_buffer[i + 1] = (word >> 8) & 0xff;
13001 return;
13004 STATIC ASC_DCNT
13005 AscMemSumLramWord(
13006 PortAddr iop_base,
13007 ushort s_addr,
13008 int words
13011 ASC_DCNT sum;
13012 int i;
13014 sum = 0L;
13015 for (i = 0; i < words; i++, s_addr += 2) {
13016 sum += AscReadLramWord(iop_base, s_addr);
13018 return (sum);
13021 STATIC void
13022 AscMemWordSetLram(
13023 PortAddr iop_base,
13024 ushort s_addr,
13025 ushort set_wval,
13026 int words
13029 int i;
13031 AscSetChipLramAddr(iop_base, s_addr);
13032 for (i = 0; i < words; i++) {
13033 AscSetChipLramData(iop_base, set_wval);
13035 return;
13040 * --- Adv Library Functions
13043 /* a_mcode.h */
13045 /* Microcode buffer is kept after initialization for error recovery. */
13046 STATIC unsigned char _adv_asc3550_buf[] = {
13047 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc, 0x01, 0x00, 0x48, 0xe4,
13048 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7,
13049 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6,
13050 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00, 0x00, 0xec, 0x85, 0xf0,
13051 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00,
13052 0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80,
13053 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea,
13054 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00,
13055 0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54,
13056 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00, 0x3e, 0x00, 0x80, 0x00,
13057 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01,
13058 0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55,
13059 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
13060 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15,
13061 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0,
13062 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01,
13063 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c,
13064 0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0,
13065 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00,
13066 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10,
13067 0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15,
13068 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45,
13069 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6,
13070 0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa,
13071 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00, 0x9e, 0x00, 0xa8, 0x00,
13072 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01,
13073 0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08,
13074 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x06, 0x12,
13075 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17,
13076 0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47,
13077 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55, 0x14, 0x56, 0x77, 0x57,
13078 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe,
13079 0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff,
13080 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, 0x00, 0xfe, 0x57, 0x24,
13081 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08,
13082 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f,
13083 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xcf,
13084 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe,
13085 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe,
13086 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b, 0x02, 0xfe, 0xd4, 0x0c,
13087 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6,
13088 0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02,
13089 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02, 0xfe, 0x46, 0xf0, 0xfe,
13090 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44,
13091 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18,
13092 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9,
13093 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e,
13094 0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd,
13095 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, 0x1c, 0x17, 0x06,
13096 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe,
13097 0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f,
13098 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe, 0x69, 0x10, 0x17, 0x06,
13099 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe,
13100 0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40,
13101 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0x99, 0x01,
13102 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02,
13103 0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b,
13104 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0, 0xfe, 0x56, 0x03, 0xfe,
13105 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe,
13106 0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04,
13107 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40, 0x01, 0x0e, 0xac, 0x75,
13108 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe,
13109 0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4,
13110 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe, 0x0a, 0xf0, 0xfe, 0x7a,
13111 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe,
13112 0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c,
13113 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3, 0x0a, 0xca, 0x01, 0x0e,
13114 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f,
13115 0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f,
13116 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2b, 0xff, 0x02,
13117 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5,
13118 0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
13119 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d, 0xfe, 0x2a, 0x13, 0x2f,
13120 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86,
13121 0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12,
13122 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22,
13123 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29,
13124 0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4,
13125 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a, 0xfe, 0x70, 0x12, 0x49,
13126 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31,
13127 0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12,
13128 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05, 0x11, 0xfe, 0xe3, 0x00,
13129 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24,
13130 0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08,
13131 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01, 0x86, 0x24, 0x06, 0x12,
13132 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92,
13133 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe,
13134 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13, 0x47, 0x01, 0xa7, 0x26,
13135 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14,
13136 0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c,
13137 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x14,
13138 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57,
13139 0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04,
13140 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68, 0x06, 0x11, 0x9a, 0x01,
13141 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72,
13142 0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe,
13143 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07, 0x8d, 0x81, 0x02, 0x22,
13144 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00,
13145 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32,
13146 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15, 0xfe, 0x1b, 0x00, 0x01,
13147 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01,
13148 0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d,
13149 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12,
13150 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d,
13151 0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02,
13152 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x77, 0xfe, 0xca,
13153 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12,
13154 0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1,
13155 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f, 0x40, 0x12, 0x58, 0x01,
13156 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe,
13157 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe,
13158 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a, 0xfe, 0x2a, 0x12, 0xfe,
13159 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe,
13160 0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe,
13161 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x39, 0x18, 0x3a,
13162 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48,
13163 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80,
13164 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x7a, 0x08, 0x8d,
13165 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06,
13166 0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c,
13167 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe, 0x52, 0x12, 0xfe, 0x2c,
13168 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10,
13169 0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe,
13170 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xb5, 0xfe,
13171 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d,
13172 0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33,
13173 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a, 0xfe, 0x74, 0x18, 0x1c,
13174 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27,
13175 0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe,
13176 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc, 0xfe, 0x83, 0x80, 0xfe,
13177 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59,
13178 0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf,
13179 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e, 0x79, 0x56, 0x68, 0x57,
13180 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b,
13181 0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39,
13182 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x10, 0x58, 0xfe,
13183 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09,
13184 0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe,
13185 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08, 0x11, 0x9b, 0x09, 0x04,
13186 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe,
13187 0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12,
13188 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9, 0x14, 0x7a, 0x01, 0x33,
13189 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf,
13190 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10,
13191 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x84, 0x05, 0xcb, 0x1c,
13192 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a,
13193 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca,
13194 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe, 0x22, 0x00, 0x02, 0x5a,
13195 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe,
13196 0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10,
13197 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00, 0x2a, 0x13, 0xfe, 0x4e,
13198 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73,
13199 0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48,
13200 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xdb, 0x10, 0x11, 0xfe,
13201 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8,
13202 0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42,
13203 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c, 0x09, 0x04, 0x0b, 0xfe,
13204 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6,
13205 0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01,
13206 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x02, 0x29,
13207 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b,
13208 0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe,
13209 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01, 0xe8, 0x59, 0x11, 0x2d,
13210 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e,
13211 0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe,
13212 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d,
13213 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe,
13214 0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00,
13215 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa, 0xab, 0x70, 0x05, 0x6b,
13216 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01,
13217 0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01,
13218 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e, 0x1d, 0xfe, 0xce, 0x45,
13219 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe,
13220 0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d,
13221 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe,
13222 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee,
13223 0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e,
13224 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12, 0xce, 0x1e, 0x2d, 0x47,
13225 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe,
13226 0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02,
13227 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
13228 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea,
13229 0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01,
13230 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01,
13231 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e,
13232 0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24,
13233 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57,
13234 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe,
13235 0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04,
13236 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xe1,
13237 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c,
13238 0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d,
13239 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01, 0xe8, 0x11, 0xfe, 0xe9,
13240 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14,
13241 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe,
13242 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80, 0x40, 0x12, 0x20, 0x63,
13243 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac,
13244 0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe,
13245 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x24, 0x69, 0x12, 0xc9,
13246 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91,
13247 0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe,
13248 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c, 0x46, 0x1e, 0x20, 0xed,
13249 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c,
13250 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d,
13251 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46, 0xfa, 0xef, 0xfe, 0x42,
13252 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0,
13253 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10,
13254 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e, 0x10, 0x07, 0x7e, 0x45,
13255 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97,
13256 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe,
13257 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b, 0xfe, 0x48, 0x12, 0x07,
13258 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07,
13259 0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe,
13260 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b, 0x01, 0x08, 0x8c, 0x43,
13261 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b,
13262 0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04,
13263 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe, 0xc6, 0x10, 0x1e, 0x58,
13264 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23,
13265 0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1,
13266 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0xfe,
13267 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57,
13268 0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
13269 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e, 0x58, 0xfe, 0x1f, 0x40,
13270 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44,
13271 0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39,
13272 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06, 0x12, 0xcd, 0x02, 0x5b,
13273 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21,
13274 0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe,
13275 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51,
13276 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32,
13277 0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01,
13278 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44, 0x01, 0x08, 0x1f, 0xa2,
13279 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49,
13280 0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda,
13281 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1, 0x05, 0xc6, 0x28, 0x84,
13282 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
13283 0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02,
13284 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06, 0x21, 0x44, 0x01, 0xfe,
13285 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b,
13286 0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05,
13287 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xd8, 0x14, 0x02, 0x5c,
13288 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72,
13289 0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01,
13290 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0xfe, 0xff, 0x7f,
13291 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c,
13292 0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
13293 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58, 0x03, 0x0a, 0x50, 0x01,
13294 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4,
13295 0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27,
13296 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe,
13297 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60,
13298 0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14,
13299 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe, 0xcc, 0x12, 0x49, 0x04,
13300 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13,
13301 0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83,
13302 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c, 0x13, 0x06, 0xfe, 0x56,
13303 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93,
13304 0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4,
13305 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90, 0x01, 0xba, 0xfe, 0x4e,
13306 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe,
13307 0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c,
13308 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba, 0xfe, 0x9c, 0x14, 0xb7,
13309 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7,
13310 0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe,
13311 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x0b, 0x01,
13312 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03,
13313 0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08,
13314 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89, 0x4a, 0x01, 0x08, 0x03,
13315 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00,
13316 0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe,
13317 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd, 0x01, 0x43, 0x1e, 0xcd,
13318 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10,
13319 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88,
13320 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3, 0x88, 0x03, 0x0a, 0x42,
13321 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2,
13322 0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17,
13323 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe,
13324 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe,
13325 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10,
13326 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58, 0x05, 0xfe, 0x66, 0x01,
13327 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66,
13328 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6,
13329 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17, 0x10, 0x71, 0xfe, 0x83,
13330 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe,
13331 0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
13332 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71, 0xfe, 0x30, 0xbc, 0xfe,
13333 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a,
13334 0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02,
13335 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc, 0xfe, 0x1d, 0xf7, 0x4f,
13336 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58,
13337 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63,
13338 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14, 0x06, 0x37, 0x95, 0xa9,
13339 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d,
13340 0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c,
13341 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x3c, 0x8a, 0x0a,
13342 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc,
13343 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f,
13344 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xf6, 0xfe, 0xd6, 0xf0,
13345 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76,
13346 0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f,
13347 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68, 0xc8, 0xfe, 0x48, 0x55,
13348 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0,
13349 0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42,
13350 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01, 0x0e, 0x73, 0x75, 0x03,
13351 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b,
13352 0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b,
13353 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05, 0xfe, 0x94, 0x00, 0xfe,
13354 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e,
13355 0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe,
13356 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1b, 0xfe, 0x5a,
13357 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07,
13358 0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14,
13359 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9, 0x03, 0x25, 0xfe, 0xca,
13360 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00,
13363 STATIC unsigned short _adv_asc3550_size =
13364 sizeof(_adv_asc3550_buf); /* 0x13AD */
13365 STATIC ADV_DCNT _adv_asc3550_chksum =
13366 0x04D52DDDUL; /* Expanded little-endian checksum. */
13368 /* Microcode buffer is kept after initialization for error recovery. */
13369 STATIC unsigned char _adv_asc38C0800_buf[] = {
13370 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4, 0x01, 0x00, 0x48, 0xe4,
13371 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6,
13372 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0,
13373 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0, 0x18, 0xf4, 0x08, 0x00,
13374 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0,
13375 0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00,
13376 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13, 0xba, 0x13, 0x18, 0x40,
13377 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01,
13378 0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
13379 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12, 0x08, 0x12, 0x02, 0x4a,
13380 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa,
13381 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
13382 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d, 0x06, 0x13, 0x4c, 0x1c,
13383 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00,
13384 0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44,
13385 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa, 0x05, 0x00, 0x34, 0x00,
13386 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f,
13387 0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54,
13388 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0,
13389 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00,
13390 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03,
13391 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13, 0x12, 0x13, 0x24, 0x14,
13392 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44,
13393 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55,
13394 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0, 0x04, 0xf8,
13395 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00,
13396 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01,
13397 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08, 0x68, 0x08, 0x69, 0x08,
13398 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10,
13399 0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14,
13400 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18, 0xca, 0x18, 0xe6, 0x19,
13401 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe,
13402 0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff,
13403 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, 0x00, 0xfe, 0x57, 0x24,
13404 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08,
13405 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11,
13406 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xd6,
13407 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe,
13408 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe,
13409 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d, 0x02, 0xfe, 0xc8, 0x0d,
13410 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6,
13411 0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02,
13412 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02, 0xfe, 0x46, 0xf0, 0xfe,
13413 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44,
13414 0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14,
13415 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9,
13416 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8,
13417 0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd,
13418 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, 0x1c, 0x18, 0x06,
13419 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe,
13420 0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10,
13421 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe, 0x69, 0x10, 0x18, 0x06,
13422 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe,
13423 0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
13424 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x09,
13425 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
13426 0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe,
13427 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x40, 0x1c, 0x1c,
13428 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0,
13429 0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02,
13430 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13, 0x21, 0x22, 0xa3, 0xb7,
13431 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9,
13432 0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27,
13433 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe, 0x06, 0xf0, 0xfe, 0xc8,
13434 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe,
13435 0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19,
13436 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x74, 0x01, 0xaf, 0x8c,
13437 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79,
13438 0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02,
13439 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d, 0xfe, 0x3c, 0x04, 0x3b,
13440 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b,
13441 0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe,
13442 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0x4f, 0x79, 0x2a,
13443 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32,
13444 0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe,
13445 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x08, 0x13, 0x32, 0x07,
13446 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d,
13447 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6,
13448 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36, 0x02, 0x2b, 0xfe, 0x42,
13449 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe,
13450 0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c,
13451 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28, 0x17, 0xfe, 0x90, 0x05,
13452 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe,
13453 0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48,
13454 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0x12, 0xfe, 0xe3, 0x00,
13455 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25,
13456 0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02,
13457 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2, 0x08, 0x53, 0x05, 0xcb,
13458 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22,
13459 0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36,
13460 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb, 0x03, 0x5c, 0x28, 0xfe,
13461 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02,
13462 0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe,
13463 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62, 0x12, 0x03, 0x45, 0x28,
13464 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc,
13465 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2,
13466 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01, 0xfe, 0xcc, 0x15, 0x1d,
13467 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45,
13468 0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb,
13469 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07, 0xfe, 0x06, 0xf0, 0xfe,
13470 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b,
13471 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01,
13472 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38, 0x12, 0x08, 0x05, 0x1a,
13473 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
13474 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe,
13475 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b, 0xfe, 0x09, 0x6f, 0xba,
13476 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c,
13477 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01,
13478 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
13479 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07,
13480 0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe,
13481 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b, 0x37, 0x01, 0xb3, 0xb8,
13482 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51,
13483 0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c,
13484 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d, 0x14, 0x3e, 0xfe, 0x4a,
13485 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14,
13486 0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe,
13487 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f,
13488 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c,
13489 0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e,
13490 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe, 0x9a, 0x08, 0xc6, 0xfe,
13491 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24,
13492 0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12,
13493 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e, 0x1c, 0x02, 0xfe, 0x18,
13494 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa,
13495 0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7,
13496 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18, 0xfe, 0xf1, 0x18, 0xfe,
13497 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95,
13498 0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5,
13499 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18, 0x0b, 0xb6, 0xfe, 0xbf,
13500 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2,
13501 0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5,
13502 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15, 0x9d, 0x01, 0x36, 0x10,
13503 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19,
13504 0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe,
13505 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0x08, 0x05,
13506 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c,
13507 0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49,
13508 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18, 0x8f, 0xfe, 0xe3, 0x54,
13509 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b,
13510 0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b,
13511 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00, 0xad, 0xfe, 0x01, 0x59,
13512 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3,
13513 0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b,
13514 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63, 0x02, 0x4a, 0x08, 0x05,
13515 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1,
13516 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a,
13517 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29, 0x61, 0x0c, 0x7f, 0x14,
13518 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c,
13519 0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef,
13520 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40, 0xe4, 0x08, 0x05, 0x1f,
13521 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f,
13522 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05,
13523 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19, 0x81, 0x50, 0xfe, 0x10,
13524 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6,
13525 0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c,
13526 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7, 0x08, 0x05, 0x0a, 0xfe,
13527 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e,
13528 0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed,
13529 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe, 0x00, 0xff, 0x35, 0xfe,
13530 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03,
13531 0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe,
13532 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0,
13533 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00,
13534 0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0,
13535 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea, 0x0b, 0x10, 0x58, 0xfe,
13536 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f,
13537 0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34,
13538 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20, 0x0c, 0x1c, 0x34, 0x94,
13539 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10,
13540 0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33,
13541 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24, 0x33, 0x31, 0xdf, 0xbc,
13542 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d,
13543 0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28,
13544 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x44, 0xfe, 0x28, 0x00,
13545 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f,
13546 0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10,
13547 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xac,
13548 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01,
13549 0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08,
13550 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05, 0x1a, 0xfe, 0x58, 0x12,
13551 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe,
13552 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10,
13553 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10, 0xfe, 0x13, 0x00, 0xfe,
13554 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5,
13555 0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe,
13556 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0, 0xb4, 0x15, 0xfe, 0x31,
13557 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44,
13558 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75,
13559 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x44, 0x48,
13560 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09,
13561 0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d,
13562 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0xce, 0x47, 0xfe, 0xad,
13563 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13,
13564 0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06,
13565 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe, 0x3a, 0x01, 0x56, 0xfe,
13566 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05,
13567 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe,
13568 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13, 0x15, 0x1a, 0x39, 0xa0,
13569 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01,
13570 0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12,
13571 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12, 0x22, 0x9f, 0xb7, 0x13,
13572 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9,
13573 0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc,
13574 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21, 0xfe, 0x00, 0xcc, 0x04,
13575 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07,
13576 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe,
13577 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x0a, 0xfe, 0x3c, 0x50,
13578 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b,
13579 0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01,
13580 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01,
13581 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01,
13582 0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79,
13583 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00,
13585 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09,
13586 0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52,
13587 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc, 0x0f, 0x44, 0x11, 0x0f,
13588 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20,
13589 0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
13590 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x04, 0x42,
13591 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01,
13592 0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f,
13593 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45,
13594 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09,
13595 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14,
13596 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d, 0xfe, 0x01, 0xec, 0xa2,
13597 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe,
13598 0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07,
13599 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17, 0xfe, 0x32, 0x12, 0x07,
13600 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12,
13601 0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d,
13602 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d, 0x32, 0x07, 0xa6, 0xfe,
13603 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12,
13604 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03,
13605 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21, 0x0c, 0x7f, 0x0c, 0x80,
13606 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55,
13607 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f,
13608 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40, 0x88, 0x9b, 0x2e, 0x9c,
13609 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14,
13610 0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61,
13611 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50,
13612 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40,
13613 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d,
13614 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23, 0x72, 0x01, 0xaf, 0x1e,
13615 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe,
13616 0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19,
13617 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31,
13618 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d,
13619 0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8,
13620 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53, 0x05, 0x1f, 0x35, 0xa9,
13621 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c,
13622 0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35,
13623 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x03, 0x5c, 0xc1, 0x0c,
13624 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c,
13625 0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1,
13626 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a, 0xf4, 0x06, 0xea, 0x32,
13627 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89,
13628 0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13,
13629 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0, 0x13, 0x1c, 0xfe, 0xd0,
13630 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02,
13631 0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f,
13632 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04,
13633 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52,
13634 0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03,
13635 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52, 0xfe, 0x00, 0x7d, 0xfe,
13636 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f,
13637 0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01,
13638 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33,
13639 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59,
13640 0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee,
13641 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c, 0x30, 0xfe, 0x78, 0x10,
13642 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00,
13643 0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00,
13644 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28, 0x10, 0x69, 0x06, 0xfe,
13645 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06,
13646 0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe,
13647 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4, 0x9e, 0xfe, 0xf3, 0x10,
13648 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
13649 0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
13650 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d, 0xf4, 0x00, 0xe9, 0x91,
13651 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01,
13652 0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76,
13653 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x19, 0x01, 0x0b,
13654 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76,
13655 0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8,
13656 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01,
13657 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00,
13658 0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06,
13659 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e, 0x07, 0x11, 0xae, 0x09,
13660 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80,
13661 0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e,
13662 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x4c,
13663 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87,
13664 0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24,
13665 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4, 0x17, 0xad, 0x9a, 0x1b,
13666 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10,
13667 0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe,
13668 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c,
13669 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17,
13670 0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75,
13671 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x2e, 0x97, 0xfe, 0x5a,
13672 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
13673 0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe,
13674 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0xcb, 0x97, 0xfe, 0x92,
13675 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02,
13676 0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d,
13677 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x9a, 0x5b, 0x41, 0xfe,
13678 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd,
13679 0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39,
13680 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04, 0xfe, 0x7e, 0x18, 0x1e,
13681 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10,
13682 0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09,
13683 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc,
13684 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c,
13685 0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14,
13686 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c, 0xe7, 0x0a, 0x10, 0xfe,
13687 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37,
13688 0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b,
13689 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77, 0x13, 0xa3, 0x04, 0x09,
13690 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8,
13691 0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09,
13692 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe, 0x1c, 0x19, 0x03, 0xfe,
13693 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19,
13694 0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b,
13695 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe, 0x08, 0x10, 0x03, 0xfe,
13696 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7,
13697 0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00,
13698 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19, 0x04, 0x07, 0x7e, 0xfe,
13699 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a,
13700 0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07,
13701 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59, 0xa9, 0xb8, 0x04, 0x15,
13702 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c,
13703 0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0,
13704 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
13707 STATIC unsigned short _adv_asc38C0800_size =
13708 sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
13709 STATIC ADV_DCNT _adv_asc38C0800_chksum =
13710 0x050D3FD8UL; /* Expanded little-endian checksum. */
13712 /* Microcode buffer is kept after initialization for error recovery. */
13713 STATIC unsigned char _adv_asc38C1600_buf[] = {
13714 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0, 0x18, 0xe4, 0x01, 0x00,
13715 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f,
13716 0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0,
13717 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00, 0x98, 0x57, 0x01, 0xe6,
13718 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0,
13719 0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0,
13720 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01, 0x06, 0x13, 0x0c, 0x1c,
13721 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80,
13722 0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea,
13723 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x04, 0x13, 0xbb, 0x55,
13724 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00,
13725 0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c,
13726 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01,
13727 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01,
13728 0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48,
13729 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x06, 0x00,
13730 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c,
13731 0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0,
13732 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00,
13733 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09,
13734 0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16,
13735 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
13736 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00,
13737 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c,
13738 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x42, 0x1d, 0x08, 0x44,
13739 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59,
13740 0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8,
13741 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0xa8, 0x00, 0xaa, 0x00,
13742 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01,
13743 0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d,
13744 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10, 0xf3, 0x10, 0x06, 0x12,
13745 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe,
13746 0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff,
13747 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, 0x00, 0xfe, 0x57, 0x24,
13748 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08,
13749 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13,
13750 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xe8,
13751 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe,
13752 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe,
13753 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d, 0x05, 0xfe, 0x08, 0x0f,
13754 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe,
13755 0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90,
13756 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8, 0x02, 0xfe, 0x46, 0xf0,
13757 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe,
13758 0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07,
13759 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02, 0x1c, 0xf5, 0xfe, 0x1e,
13760 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01,
13761 0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe,
13762 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, 0x1c, 0x1c,
13763 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02,
13764 0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01,
13765 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09, 0x1a, 0x31, 0xfe, 0x69,
13766 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c,
13767 0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51,
13768 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00,
13769 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54,
13770 0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30,
13771 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0, 0xfe, 0xe4, 0x01, 0xfe,
13772 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66,
13773 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f,
13774 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05, 0x70, 0x37, 0xfe, 0x48,
13775 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20,
13776 0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe,
13777 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32, 0x15, 0xfe, 0xe4, 0x00,
13778 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe,
13779 0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b,
13780 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xfe, 0x46, 0x1c,
13781 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75,
13782 0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77,
13783 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02,
13784 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04,
13785 0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01,
13786 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25, 0xee, 0xfe, 0x4c, 0x44,
13787 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d,
13788 0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe,
13789 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10, 0x13, 0x34, 0xfe, 0x4c,
13790 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06,
13791 0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f,
13792 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f, 0xfe, 0xa4, 0x0e, 0x05,
13793 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b,
13794 0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46,
13795 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04, 0xfe, 0x87, 0x83, 0xfe,
13796 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20,
13797 0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06,
13798 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda, 0x05, 0xd0, 0x54, 0x01,
13799 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff,
13800 0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe,
13801 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01, 0x38, 0xfe, 0x4a, 0xf0,
13802 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e,
13803 0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0,
13804 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe, 0x1c, 0x00, 0x4d, 0x01,
13805 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12,
13806 0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42,
13807 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13, 0x03, 0xb6, 0x1e, 0xfe,
13808 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a,
13809 0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68,
13810 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x03, 0x9a, 0x1e, 0xfe,
13811 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06,
13812 0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00,
13813 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17, 0xfe, 0xea, 0x06, 0x01,
13814 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15,
13815 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae,
13816 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a, 0x1e, 0xfe, 0x1a, 0x12,
13817 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80,
13818 0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6,
13819 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x17, 0xfe,
13820 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01,
13821 0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05,
13822 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0x9c, 0x32, 0x5f,
13823 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe,
13824 0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29,
13825 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14,
13826 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe,
13827 0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13,
13828 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
13829 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe,
13830 0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c,
13831 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x53, 0x63, 0x4e,
13832 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0,
13833 0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c,
13834 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe, 0x1e, 0xfe, 0x99, 0x58,
13835 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c,
13836 0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a,
13837 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40, 0x01, 0x0c, 0x61, 0x65,
13838 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50,
13839 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e,
13840 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e, 0x01, 0xfe, 0xfe, 0x1e,
13841 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06,
13842 0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b,
13843 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04, 0xfe, 0x9f, 0x83, 0x33,
13844 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6,
13845 0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e,
13846 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90, 0x04, 0xfe, 0xc0, 0x93,
13847 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c,
13848 0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
13849 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
13850 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a,
13851 0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41,
13852 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07, 0xfe, 0x14, 0x12, 0x01,
13853 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe,
13854 0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe,
13855 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe, 0x92, 0x10, 0xc4, 0xf6,
13856 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b,
13857 0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0,
13858 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07, 0x1b, 0xbf, 0xd4, 0x5b,
13859 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f,
13860 0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74,
13861 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78, 0x0f, 0x4d, 0x01, 0xfe,
13862 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2,
13863 0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21,
13864 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe, 0x83, 0x83, 0xfe, 0xc9,
13865 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84,
13866 0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b,
13867 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0x10,
13868 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64,
13869 0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64,
13870 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97, 0x10, 0x98, 0x91, 0x6c,
13871 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01,
13872 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58,
13873 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x01, 0x0c,
13874 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04,
13875 0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe,
13876 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb, 0x01, 0x0c, 0x06, 0x0d,
13877 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d,
13878 0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e,
13879 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41,
13880 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00,
13881 0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51,
13882 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe, 0x76, 0x10, 0xac, 0xfe,
13883 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe,
13884 0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92,
13885 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2, 0x0c, 0xfe, 0x3e, 0x10,
13886 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe,
13887 0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94,
13888 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3, 0xfe, 0xcc, 0xf0, 0xef,
13889 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
13890 0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
13891 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32, 0x2f, 0xfe, 0x3e, 0x0d,
13892 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f,
13893 0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99,
13894 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8, 0x9c, 0x2f, 0xfe, 0x8c,
13895 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70,
13896 0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13,
13897 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b, 0xfe, 0xda, 0x0e, 0x0a,
13898 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4,
13899 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85,
13900 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe, 0xcc, 0x10, 0x01, 0xa7,
13901 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe,
13902 0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2,
13903 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x40, 0x15,
13904 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01,
13905 0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe,
13906 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe,
13907 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44,
13908 0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19,
13909 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19, 0xfe, 0x41, 0x00, 0xa2,
13910 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04,
13911 0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c,
13912 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01, 0xfe, 0xd4, 0x11, 0x05,
13913 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51,
13914 0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56,
13915 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01, 0x0c, 0x06, 0x28, 0xfe,
13916 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe,
13917 0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe,
13918 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x05,
13919 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c,
13920 0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b,
13921 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe, 0xf0, 0x1a, 0x03, 0xfe,
13922 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00,
13923 0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b,
13924 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02, 0xea, 0xe7, 0x53, 0x92,
13925 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23,
13926 0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e,
13927 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02, 0x26, 0x02, 0x21, 0x96,
13928 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10,
13929 0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe,
13930 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe, 0x00, 0xcc, 0x02, 0xfe,
13931 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80,
13932 0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80,
13933 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe, 0x1d, 0x80, 0x04, 0xfe,
13934 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14,
13935 0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4,
13936 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09, 0x56, 0xfb, 0x01, 0xfe,
13937 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15,
13938 0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e,
13939 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe, 0x96, 0x90, 0x04, 0xfe,
13940 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06,
13941 0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01,
13942 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40, 0x21, 0x2c, 0xfe, 0x00,
13943 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe,
13944 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00,
13945 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10, 0x66, 0x10, 0x55, 0x10,
13946 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88,
13947 0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe,
13948 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c,
13949 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe,
13950 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47,
13951 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01, 0xa7, 0x90, 0x34, 0x60,
13952 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34,
13953 0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
13954 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a,
13955 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe,
13956 0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e,
13957 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01, 0xf4, 0xfe, 0xdd, 0x10,
13958 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe,
13959 0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23,
13960 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09, 0x24, 0xfe, 0x12, 0x12,
13961 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32,
13962 0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43,
13963 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80, 0x13, 0x01, 0x0c, 0x06,
13964 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe,
13965 0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10,
13966 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49, 0x88, 0x20, 0x6e, 0x01,
13967 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa,
13968 0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe,
13969 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe, 0xe5,
13970 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01,
13971 0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50,
13972 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50, 0x03, 0x68, 0x3b,
13973 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2,
13974 0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25,
13975 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01, 0xa6, 0x23, 0x3f, 0x1b,
13976 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31,
13977 0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01,
13978 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0,
13979 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05,
13980 0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08,
13981 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03, 0xb6, 0x1e, 0x83, 0x01,
13982 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01,
13983 0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82,
13984 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e, 0x05, 0x72, 0xfe, 0xc0,
13985 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17,
13986 0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd,
13987 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe, 0xe8, 0x14, 0x01, 0xa6,
13988 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43,
13989 0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73,
13990 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd, 0x09,
13991 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8,
13992 0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72,
13993 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0xc0, 0x19, 0x05,
13994 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26,
13995 0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32,
13996 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0xfe, 0xff,
13997 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad,
13998 0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
13999 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e, 0x02, 0x13, 0x58, 0xff,
14000 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01,
14001 0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54,
14002 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07, 0x7c, 0x3a, 0x0b, 0x0e,
14003 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00,
14004 0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe,
14005 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77, 0x02, 0x01, 0xc6, 0xfe,
14006 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08,
14007 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe,
14008 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12, 0x48, 0xfe, 0x08, 0x17,
14009 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07,
14010 0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55,
14011 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x1c, 0x63, 0x13,
14012 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80,
14013 0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60,
14014 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8, 0x00, 0x1c, 0x95, 0x13,
14015 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96,
14016 0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b,
14017 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x49,
14018 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe,
14019 0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13,
14020 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xbe, 0xfe, 0x03,
14021 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16,
14022 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9,
14023 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27,
14024 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24,
14025 0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e,
14026 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10, 0xfe, 0x40, 0x5a, 0x23,
14027 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa,
14028 0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
14029 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe, 0x43, 0x48, 0x2d, 0x93,
14030 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4,
14031 0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0,
14032 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa, 0x18, 0x45, 0xfe, 0x1c,
14033 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4,
14034 0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01,
14035 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe, 0x7e, 0x01, 0xfe, 0xc8,
14036 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01,
14037 0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14,
14038 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14,
14039 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07,
14040 0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
14041 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01, 0x08, 0x02, 0x50, 0x02,
14042 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08,
14043 0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe,
14044 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17, 0x74, 0x5f, 0xcc, 0x01,
14045 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00,
14046 0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f,
14047 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13, 0x16, 0xfe, 0x64, 0x1a,
14048 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02,
14049 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01,
14050 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa, 0xfe, 0x80, 0xe7, 0x1a,
14051 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18,
14052 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80,
14053 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x0a,
14054 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
14055 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3,
14056 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe, 0xf4, 0x1a, 0xfe, 0xfa,
14057 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03,
14058 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07,
14059 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x24, 0xb1, 0xfe,
14060 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c,
14061 0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1,
14062 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe, 0xaf, 0x19, 0xfe, 0x98,
14063 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f,
14064 0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04,
14065 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a, 0x7c, 0x12, 0xfe, 0x0f,
14066 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b,
14067 0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe,
14068 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee, 0x1b, 0xfe, 0x36, 0x14,
14069 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a,
14070 0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45,
14071 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe, 0x39, 0xf0, 0x75, 0x26,
14072 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe,
14073 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13,
14074 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe,
14075 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb,
14076 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01,
14077 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14, 0x56,
14078 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15,
14079 0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80,
14080 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90,
14081 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20,
14082 0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44,
14083 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09, 0x1a, 0xa4, 0x0a, 0x67,
14084 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52,
14085 0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b,
14086 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10, 0xfe, 0x4e, 0xe4, 0xfe,
14087 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03,
14088 0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1,
14089 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe,
14090 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a,
14091 0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8,
14092 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe, 0x1a, 0x10, 0x09, 0x0d,
14093 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42,
14094 0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08,
14095 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e, 0xfe, 0x82, 0xf0, 0xfe,
14096 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18,
14097 0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82,
14098 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86, 0x83, 0x33, 0x0b, 0x0e,
14099 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04,
14100 0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80,
14101 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04, 0xfe, 0x99, 0x83, 0xfe,
14102 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47,
14103 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
14104 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x08, 0x90, 0x04,
14105 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79,
14106 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
14107 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x3c, 0x90, 0x04,
14108 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83,
14109 0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
14112 STATIC unsigned short _adv_asc38C1600_size =
14113 sizeof(_adv_asc38C1600_buf); /* 0x1673 */
14114 STATIC ADV_DCNT _adv_asc38C1600_chksum =
14115 0x0604EF77UL; /* Expanded little-endian checksum. */
14117 /* a_init.c */
14119 * EEPROM Configuration.
14121 * All drivers should use this structure to set the default EEPROM
14122 * configuration. The BIOS now uses this structure when it is built.
14123 * Additional structure information can be found in a_condor.h where
14124 * the structure is defined.
14126 * The *_Field_IsChar structs are needed to correct for endianness.
14127 * These values are read from the board 16 bits at a time directly
14128 * into the structs. Because some fields are char, the values will be
14129 * in the wrong order. The *_Field_IsChar tells when to flip the
14130 * bytes. Data read and written to PCI memory is automatically swapped
14131 * on big-endian platforms so char fields read as words are actually being
14132 * unswapped on big-endian platforms.
14134 STATIC ADVEEP_3550_CONFIG
14135 Default_3550_EEPROM_Config __initdata = {
14136 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
14137 0x0000, /* cfg_msw */
14138 0xFFFF, /* disc_enable */
14139 0xFFFF, /* wdtr_able */
14140 0xFFFF, /* sdtr_able */
14141 0xFFFF, /* start_motor */
14142 0xFFFF, /* tagqng_able */
14143 0xFFFF, /* bios_scan */
14144 0, /* scam_tolerant */
14145 7, /* adapter_scsi_id */
14146 0, /* bios_boot_delay */
14147 3, /* scsi_reset_delay */
14148 0, /* bios_id_lun */
14149 0, /* termination */
14150 0, /* reserved1 */
14151 0xFFE7, /* bios_ctrl */
14152 0xFFFF, /* ultra_able */
14153 0, /* reserved2 */
14154 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
14155 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
14156 0, /* dvc_cntl */
14157 0, /* bug_fix */
14158 0, /* serial_number_word1 */
14159 0, /* serial_number_word2 */
14160 0, /* serial_number_word3 */
14161 0, /* check_sum */
14162 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* oem_name[16] */
14163 0, /* dvc_err_code */
14164 0, /* adv_err_code */
14165 0, /* adv_err_addr */
14166 0, /* saved_dvc_err_code */
14167 0, /* saved_adv_err_code */
14168 0, /* saved_adv_err_addr */
14169 0 /* num_of_err */
14172 STATIC ADVEEP_3550_CONFIG
14173 ADVEEP_3550_Config_Field_IsChar __initdata = {
14174 0, /* cfg_lsw */
14175 0, /* cfg_msw */
14176 0, /* -disc_enable */
14177 0, /* wdtr_able */
14178 0, /* sdtr_able */
14179 0, /* start_motor */
14180 0, /* tagqng_able */
14181 0, /* bios_scan */
14182 0, /* scam_tolerant */
14183 1, /* adapter_scsi_id */
14184 1, /* bios_boot_delay */
14185 1, /* scsi_reset_delay */
14186 1, /* bios_id_lun */
14187 1, /* termination */
14188 1, /* reserved1 */
14189 0, /* bios_ctrl */
14190 0, /* ultra_able */
14191 0, /* reserved2 */
14192 1, /* max_host_qng */
14193 1, /* max_dvc_qng */
14194 0, /* dvc_cntl */
14195 0, /* bug_fix */
14196 0, /* serial_number_word1 */
14197 0, /* serial_number_word2 */
14198 0, /* serial_number_word3 */
14199 0, /* check_sum */
14200 { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* oem_name[16] */
14201 0, /* dvc_err_code */
14202 0, /* adv_err_code */
14203 0, /* adv_err_addr */
14204 0, /* saved_dvc_err_code */
14205 0, /* saved_adv_err_code */
14206 0, /* saved_adv_err_addr */
14207 0 /* num_of_err */
14210 STATIC ADVEEP_38C0800_CONFIG
14211 Default_38C0800_EEPROM_Config __initdata = {
14212 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
14213 0x0000, /* 01 cfg_msw */
14214 0xFFFF, /* 02 disc_enable */
14215 0xFFFF, /* 03 wdtr_able */
14216 0x4444, /* 04 sdtr_speed1 */
14217 0xFFFF, /* 05 start_motor */
14218 0xFFFF, /* 06 tagqng_able */
14219 0xFFFF, /* 07 bios_scan */
14220 0, /* 08 scam_tolerant */
14221 7, /* 09 adapter_scsi_id */
14222 0, /* bios_boot_delay */
14223 3, /* 10 scsi_reset_delay */
14224 0, /* bios_id_lun */
14225 0, /* 11 termination_se */
14226 0, /* termination_lvd */
14227 0xFFE7, /* 12 bios_ctrl */
14228 0x4444, /* 13 sdtr_speed2 */
14229 0x4444, /* 14 sdtr_speed3 */
14230 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
14231 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
14232 0, /* 16 dvc_cntl */
14233 0x4444, /* 17 sdtr_speed4 */
14234 0, /* 18 serial_number_word1 */
14235 0, /* 19 serial_number_word2 */
14236 0, /* 20 serial_number_word3 */
14237 0, /* 21 check_sum */
14238 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */
14239 0, /* 30 dvc_err_code */
14240 0, /* 31 adv_err_code */
14241 0, /* 32 adv_err_addr */
14242 0, /* 33 saved_dvc_err_code */
14243 0, /* 34 saved_adv_err_code */
14244 0, /* 35 saved_adv_err_addr */
14245 0, /* 36 reserved */
14246 0, /* 37 reserved */
14247 0, /* 38 reserved */
14248 0, /* 39 reserved */
14249 0, /* 40 reserved */
14250 0, /* 41 reserved */
14251 0, /* 42 reserved */
14252 0, /* 43 reserved */
14253 0, /* 44 reserved */
14254 0, /* 45 reserved */
14255 0, /* 46 reserved */
14256 0, /* 47 reserved */
14257 0, /* 48 reserved */
14258 0, /* 49 reserved */
14259 0, /* 50 reserved */
14260 0, /* 51 reserved */
14261 0, /* 52 reserved */
14262 0, /* 53 reserved */
14263 0, /* 54 reserved */
14264 0, /* 55 reserved */
14265 0, /* 56 cisptr_lsw */
14266 0, /* 57 cisprt_msw */
14267 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
14268 PCI_DEVICE_ID_38C0800_REV1, /* 59 subsysid */
14269 0, /* 60 reserved */
14270 0, /* 61 reserved */
14271 0, /* 62 reserved */
14272 0 /* 63 reserved */
14275 STATIC ADVEEP_38C0800_CONFIG
14276 ADVEEP_38C0800_Config_Field_IsChar __initdata = {
14277 0, /* 00 cfg_lsw */
14278 0, /* 01 cfg_msw */
14279 0, /* 02 disc_enable */
14280 0, /* 03 wdtr_able */
14281 0, /* 04 sdtr_speed1 */
14282 0, /* 05 start_motor */
14283 0, /* 06 tagqng_able */
14284 0, /* 07 bios_scan */
14285 0, /* 08 scam_tolerant */
14286 1, /* 09 adapter_scsi_id */
14287 1, /* bios_boot_delay */
14288 1, /* 10 scsi_reset_delay */
14289 1, /* bios_id_lun */
14290 1, /* 11 termination_se */
14291 1, /* termination_lvd */
14292 0, /* 12 bios_ctrl */
14293 0, /* 13 sdtr_speed2 */
14294 0, /* 14 sdtr_speed3 */
14295 1, /* 15 max_host_qng */
14296 1, /* max_dvc_qng */
14297 0, /* 16 dvc_cntl */
14298 0, /* 17 sdtr_speed4 */
14299 0, /* 18 serial_number_word1 */
14300 0, /* 19 serial_number_word2 */
14301 0, /* 20 serial_number_word3 */
14302 0, /* 21 check_sum */
14303 { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* 22-29 oem_name[16] */
14304 0, /* 30 dvc_err_code */
14305 0, /* 31 adv_err_code */
14306 0, /* 32 adv_err_addr */
14307 0, /* 33 saved_dvc_err_code */
14308 0, /* 34 saved_adv_err_code */
14309 0, /* 35 saved_adv_err_addr */
14310 0, /* 36 reserved */
14311 0, /* 37 reserved */
14312 0, /* 38 reserved */
14313 0, /* 39 reserved */
14314 0, /* 40 reserved */
14315 0, /* 41 reserved */
14316 0, /* 42 reserved */
14317 0, /* 43 reserved */
14318 0, /* 44 reserved */
14319 0, /* 45 reserved */
14320 0, /* 46 reserved */
14321 0, /* 47 reserved */
14322 0, /* 48 reserved */
14323 0, /* 49 reserved */
14324 0, /* 50 reserved */
14325 0, /* 51 reserved */
14326 0, /* 52 reserved */
14327 0, /* 53 reserved */
14328 0, /* 54 reserved */
14329 0, /* 55 reserved */
14330 0, /* 56 cisptr_lsw */
14331 0, /* 57 cisprt_msw */
14332 0, /* 58 subsysvid */
14333 0, /* 59 subsysid */
14334 0, /* 60 reserved */
14335 0, /* 61 reserved */
14336 0, /* 62 reserved */
14337 0 /* 63 reserved */
14340 STATIC ADVEEP_38C1600_CONFIG
14341 Default_38C1600_EEPROM_Config __initdata = {
14342 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
14343 0x0000, /* 01 cfg_msw */
14344 0xFFFF, /* 02 disc_enable */
14345 0xFFFF, /* 03 wdtr_able */
14346 0x5555, /* 04 sdtr_speed1 */
14347 0xFFFF, /* 05 start_motor */
14348 0xFFFF, /* 06 tagqng_able */
14349 0xFFFF, /* 07 bios_scan */
14350 0, /* 08 scam_tolerant */
14351 7, /* 09 adapter_scsi_id */
14352 0, /* bios_boot_delay */
14353 3, /* 10 scsi_reset_delay */
14354 0, /* bios_id_lun */
14355 0, /* 11 termination_se */
14356 0, /* termination_lvd */
14357 0xFFE7, /* 12 bios_ctrl */
14358 0x5555, /* 13 sdtr_speed2 */
14359 0x5555, /* 14 sdtr_speed3 */
14360 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
14361 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
14362 0, /* 16 dvc_cntl */
14363 0x5555, /* 17 sdtr_speed4 */
14364 0, /* 18 serial_number_word1 */
14365 0, /* 19 serial_number_word2 */
14366 0, /* 20 serial_number_word3 */
14367 0, /* 21 check_sum */
14368 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */
14369 0, /* 30 dvc_err_code */
14370 0, /* 31 adv_err_code */
14371 0, /* 32 adv_err_addr */
14372 0, /* 33 saved_dvc_err_code */
14373 0, /* 34 saved_adv_err_code */
14374 0, /* 35 saved_adv_err_addr */
14375 0, /* 36 reserved */
14376 0, /* 37 reserved */
14377 0, /* 38 reserved */
14378 0, /* 39 reserved */
14379 0, /* 40 reserved */
14380 0, /* 41 reserved */
14381 0, /* 42 reserved */
14382 0, /* 43 reserved */
14383 0, /* 44 reserved */
14384 0, /* 45 reserved */
14385 0, /* 46 reserved */
14386 0, /* 47 reserved */
14387 0, /* 48 reserved */
14388 0, /* 49 reserved */
14389 0, /* 50 reserved */
14390 0, /* 51 reserved */
14391 0, /* 52 reserved */
14392 0, /* 53 reserved */
14393 0, /* 54 reserved */
14394 0, /* 55 reserved */
14395 0, /* 56 cisptr_lsw */
14396 0, /* 57 cisprt_msw */
14397 PCI_VENDOR_ID_ASP, /* 58 subsysvid */
14398 PCI_DEVICE_ID_38C1600_REV1, /* 59 subsysid */
14399 0, /* 60 reserved */
14400 0, /* 61 reserved */
14401 0, /* 62 reserved */
14402 0 /* 63 reserved */
14405 STATIC ADVEEP_38C1600_CONFIG
14406 ADVEEP_38C1600_Config_Field_IsChar __initdata = {
14407 0, /* 00 cfg_lsw */
14408 0, /* 01 cfg_msw */
14409 0, /* 02 disc_enable */
14410 0, /* 03 wdtr_able */
14411 0, /* 04 sdtr_speed1 */
14412 0, /* 05 start_motor */
14413 0, /* 06 tagqng_able */
14414 0, /* 07 bios_scan */
14415 0, /* 08 scam_tolerant */
14416 1, /* 09 adapter_scsi_id */
14417 1, /* bios_boot_delay */
14418 1, /* 10 scsi_reset_delay */
14419 1, /* bios_id_lun */
14420 1, /* 11 termination_se */
14421 1, /* termination_lvd */
14422 0, /* 12 bios_ctrl */
14423 0, /* 13 sdtr_speed2 */
14424 0, /* 14 sdtr_speed3 */
14425 1, /* 15 max_host_qng */
14426 1, /* max_dvc_qng */
14427 0, /* 16 dvc_cntl */
14428 0, /* 17 sdtr_speed4 */
14429 0, /* 18 serial_number_word1 */
14430 0, /* 19 serial_number_word2 */
14431 0, /* 20 serial_number_word3 */
14432 0, /* 21 check_sum */
14433 { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* 22-29 oem_name[16] */
14434 0, /* 30 dvc_err_code */
14435 0, /* 31 adv_err_code */
14436 0, /* 32 adv_err_addr */
14437 0, /* 33 saved_dvc_err_code */
14438 0, /* 34 saved_adv_err_code */
14439 0, /* 35 saved_adv_err_addr */
14440 0, /* 36 reserved */
14441 0, /* 37 reserved */
14442 0, /* 38 reserved */
14443 0, /* 39 reserved */
14444 0, /* 40 reserved */
14445 0, /* 41 reserved */
14446 0, /* 42 reserved */
14447 0, /* 43 reserved */
14448 0, /* 44 reserved */
14449 0, /* 45 reserved */
14450 0, /* 46 reserved */
14451 0, /* 47 reserved */
14452 0, /* 48 reserved */
14453 0, /* 49 reserved */
14454 0, /* 50 reserved */
14455 0, /* 51 reserved */
14456 0, /* 52 reserved */
14457 0, /* 53 reserved */
14458 0, /* 54 reserved */
14459 0, /* 55 reserved */
14460 0, /* 56 cisptr_lsw */
14461 0, /* 57 cisprt_msw */
14462 0, /* 58 subsysvid */
14463 0, /* 59 subsysid */
14464 0, /* 60 reserved */
14465 0, /* 61 reserved */
14466 0, /* 62 reserved */
14467 0 /* 63 reserved */
14471 * Initialize the ADV_DVC_VAR structure.
14473 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14475 * For a non-fatal error return a warning code. If there are no warnings
14476 * then 0 is returned.
14478 STATIC int __init
14479 AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
14481 ushort warn_code;
14482 AdvPortAddr iop_base;
14483 uchar pci_cmd_reg;
14484 int status;
14486 warn_code = 0;
14487 asc_dvc->err_code = 0;
14488 iop_base = asc_dvc->iop_base;
14491 * PCI Command Register
14493 * Note: AscPCICmdRegBits_BusMastering definition (0x0007) includes
14494 * I/O Space Control, Memory Space Control and Bus Master Control bits.
14497 if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
14498 AscPCIConfigCommandRegister))
14499 & AscPCICmdRegBits_BusMastering)
14500 != AscPCICmdRegBits_BusMastering)
14502 pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
14504 DvcAdvWritePCIConfigByte(asc_dvc,
14505 AscPCIConfigCommandRegister, pci_cmd_reg);
14507 if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister))
14508 & AscPCICmdRegBits_BusMastering)
14509 != AscPCICmdRegBits_BusMastering)
14511 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14516 * PCI Latency Timer
14518 * If the "latency timer" register is 0x20 or above, then we don't need
14519 * to change it. Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
14520 * comes up less than 0x20).
14522 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
14523 DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer, 0x20);
14524 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20)
14526 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14531 * Save the state of the PCI Configuration Command Register
14532 * "Parity Error Response Control" Bit. If the bit is clear (0),
14533 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
14534 * DMA parity errors.
14536 asc_dvc->cfg->control_flag = 0;
14537 if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
14538 & AscPCICmdRegBits_ParErrRespCtrl)) == 0)
14540 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
14543 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
14544 ADV_LIB_VERSION_MINOR;
14545 asc_dvc->cfg->chip_version =
14546 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
14548 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
14549 (ushort) AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
14550 (ushort) ADV_CHIP_ID_BYTE);
14552 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
14553 (ushort) AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
14554 (ushort) ADV_CHIP_ID_WORD);
14557 * Reset the chip to start and allow register writes.
14559 if (AdvFindSignature(iop_base) == 0)
14561 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
14562 return ADV_ERROR;
14564 else {
14566 * The caller must set 'chip_type' to a valid setting.
14568 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
14569 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
14570 asc_dvc->chip_type != ADV_CHIP_ASC38C1600)
14572 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14573 return ADV_ERROR;
14577 * Reset Chip.
14579 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14580 ADV_CTRL_REG_CMD_RESET);
14581 DvcSleepMilliSecond(100);
14582 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14583 ADV_CTRL_REG_CMD_WR_IO_REG);
14585 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
14587 if ((status = AdvInitFrom38C1600EEP(asc_dvc)) == ADV_ERROR)
14589 return ADV_ERROR;
14591 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
14593 if ((status = AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR)
14595 return ADV_ERROR;
14597 } else
14599 if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR)
14601 return ADV_ERROR;
14604 warn_code |= status;
14607 return warn_code;
14611 * Initialize the ASC-3550.
14613 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14615 * For a non-fatal error return a warning code. If there are no warnings
14616 * then 0 is returned.
14618 * Needed after initialization for error recovery.
14620 STATIC int
14621 AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
14623 AdvPortAddr iop_base;
14624 ushort warn_code;
14625 ADV_DCNT sum;
14626 int begin_addr;
14627 int end_addr;
14628 ushort code_sum;
14629 int word;
14630 int j;
14631 int adv_asc3550_expanded_size;
14632 ADV_CARR_T *carrp;
14633 ADV_DCNT contig_len;
14634 ADV_SDCNT buf_size;
14635 ADV_PADDR carr_paddr;
14636 int i;
14637 ushort scsi_cfg1;
14638 uchar tid;
14639 ushort bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
14640 ushort wdtr_able = 0, sdtr_able, tagqng_able;
14641 uchar max_cmd[ADV_MAX_TID + 1];
14643 /* If there is already an error, don't continue. */
14644 if (asc_dvc->err_code != 0)
14646 return ADV_ERROR;
14650 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
14652 if (asc_dvc->chip_type != ADV_CHIP_ASC3550)
14654 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14655 return ADV_ERROR;
14658 warn_code = 0;
14659 iop_base = asc_dvc->iop_base;
14662 * Save the RISC memory BIOS region before writing the microcode.
14663 * The BIOS may already be loaded and using its RISC LRAM region
14664 * so its region must be saved and restored.
14666 * Note: This code makes the assumption, which is currently true,
14667 * that a chip reset does not clear RISC LRAM.
14669 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
14671 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
14675 * Save current per TID negotiated values.
14677 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
14679 ushort bios_version, major, minor;
14681 bios_version = bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM)/2];
14682 major = (bios_version >> 12) & 0xF;
14683 minor = (bios_version >> 8) & 0xF;
14684 if (major < 3 || (major == 3 && minor == 1))
14686 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
14687 AdvReadWordLram(iop_base, 0x120, wdtr_able);
14688 } else
14690 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14693 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14694 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14695 for (tid = 0; tid <= ADV_MAX_TID; tid++)
14697 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14698 max_cmd[tid]);
14702 * Load the Microcode
14704 * Write the microcode image to RISC memory starting at address 0.
14706 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14707 /* Assume the following compressed format of the microcode buffer:
14709 * 254 word (508 byte) table indexed by byte code followed
14710 * by the following byte codes:
14712 * 1-Byte Code:
14713 * 00: Emit word 0 in table.
14714 * 01: Emit word 1 in table.
14716 * FD: Emit word 253 in table.
14718 * Multi-Byte Code:
14719 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14720 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14722 word = 0;
14723 for (i = 253 * 2; i < _adv_asc3550_size; i++)
14725 if (_adv_asc3550_buf[i] == 0xff)
14727 for (j = 0; j < _adv_asc3550_buf[i + 1]; j++)
14729 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14730 _adv_asc3550_buf[i + 3] << 8) |
14731 _adv_asc3550_buf[i + 2]));
14732 word++;
14734 i += 3;
14735 } else if (_adv_asc3550_buf[i] == 0xfe)
14737 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14738 _adv_asc3550_buf[i + 2] << 8) |
14739 _adv_asc3550_buf[i + 1]));
14740 i += 2;
14741 word++;
14742 } else
14744 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14745 _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) |
14746 _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
14747 word++;
14752 * Set 'word' for later use to clear the rest of memory and save
14753 * the expanded mcode size.
14755 word *= 2;
14756 adv_asc3550_expanded_size = word;
14759 * Clear the rest of ASC-3550 Internal RAM (8KB).
14761 for (; word < ADV_3550_MEMSIZE; word += 2)
14763 AdvWriteWordAutoIncLram(iop_base, 0);
14767 * Verify the microcode checksum.
14769 sum = 0;
14770 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14772 for (word = 0; word < adv_asc3550_expanded_size; word += 2)
14774 sum += AdvReadWordAutoIncLram(iop_base);
14777 if (sum != _adv_asc3550_chksum)
14779 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14780 return ADV_ERROR;
14784 * Restore the RISC memory BIOS region.
14786 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
14788 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
14792 * Calculate and write the microcode code checksum to the microcode
14793 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14795 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14796 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14797 code_sum = 0;
14798 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14799 for (word = begin_addr; word < end_addr; word += 2)
14801 code_sum += AdvReadWordAutoIncLram(iop_base);
14803 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14806 * Read and save microcode version and date.
14808 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
14809 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
14812 * Set the chip type to indicate the ASC3550.
14814 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
14817 * If the PCI Configuration Command Register "Parity Error Response
14818 * Control" Bit was clear (0), then set the microcode variable
14819 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14820 * to ignore DMA parity errors.
14822 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
14824 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14825 word |= CONTROL_FLAG_IGNORE_PERR;
14826 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14830 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
14831 * threshold of 128 bytes. This register is only accessible to the host.
14833 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14834 START_CTL_EMFU | READ_CMD_MRM);
14837 * Microcode operating variables for WDTR, SDTR, and command tag
14838 * queuing will be set in AdvInquiryHandling() based on what a
14839 * device reports it is capable of in Inquiry byte 7.
14841 * If SCSI Bus Resets have been disabled, then directly set
14842 * SDTR and WDTR from the EEPROM configuration. This will allow
14843 * the BIOS and warm boot to work without a SCSI bus hang on
14844 * the Inquiry caused by host and target mismatched DTR values.
14845 * Without the SCSI Bus Reset, before an Inquiry a device can't
14846 * be assumed to be in Asynchronous, Narrow mode.
14848 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
14850 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
14851 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
14855 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
14856 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
14857 * bitmask. These values determine the maximum SDTR speed negotiated
14858 * with a device.
14860 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14861 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14862 * without determining here whether the device supports SDTR.
14864 * 4-bit speed SDTR speed name
14865 * =========== ===============
14866 * 0000b (0x0) SDTR disabled
14867 * 0001b (0x1) 5 Mhz
14868 * 0010b (0x2) 10 Mhz
14869 * 0011b (0x3) 20 Mhz (Ultra)
14870 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
14871 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
14872 * 0110b (0x6) Undefined
14874 * 1111b (0xF) Undefined
14876 word = 0;
14877 for (tid = 0; tid <= ADV_MAX_TID; tid++)
14879 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able)
14881 /* Set Ultra speed for TID 'tid'. */
14882 word |= (0x3 << (4 * (tid % 4)));
14883 } else
14885 /* Set Fast speed for TID 'tid'. */
14886 word |= (0x2 << (4 * (tid % 4)));
14888 if (tid == 3) /* Check if done with sdtr_speed1. */
14890 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
14891 word = 0;
14892 } else if (tid == 7) /* Check if done with sdtr_speed2. */
14894 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
14895 word = 0;
14896 } else if (tid == 11) /* Check if done with sdtr_speed3. */
14898 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
14899 word = 0;
14900 } else if (tid == 15) /* Check if done with sdtr_speed4. */
14902 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
14903 /* End of loop. */
14908 * Set microcode operating variable for the disconnect per TID bitmask.
14910 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
14913 * Set SCSI_CFG0 Microcode Default Value.
14915 * The microcode will set the SCSI_CFG0 register using this value
14916 * after it is started below.
14918 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14919 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14920 asc_dvc->chip_scsi_id);
14923 * Determine SCSI_CFG1 Microcode Default Value.
14925 * The microcode will set the SCSI_CFG1 register using this value
14926 * after it is started below.
14929 /* Read current SCSI_CFG1 Register value. */
14930 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14933 * If all three connectors are in use, return an error.
14935 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
14936 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0)
14938 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
14939 return ADV_ERROR;
14943 * If the internal narrow cable is reversed all of the SCSI_CTRL
14944 * register signals will be set. Check for and return an error if
14945 * this condition is found.
14947 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
14949 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14950 return ADV_ERROR;
14954 * If this is a differential board and a single-ended device
14955 * is attached to one of the connectors, return an error.
14957 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0)
14959 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
14960 return ADV_ERROR;
14964 * If automatic termination control is enabled, then set the
14965 * termination value based on a table listed in a_condor.h.
14967 * If manual termination was specified with an EEPROM setting
14968 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
14969 * is ready to be 'ored' into SCSI_CFG1.
14971 if (asc_dvc->cfg->termination == 0)
14974 * The software always controls termination by setting TERM_CTL_SEL.
14975 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
14977 asc_dvc->cfg->termination |= TERM_CTL_SEL;
14979 switch(scsi_cfg1 & CABLE_DETECT)
14981 /* TERM_CTL_H: on, TERM_CTL_L: on */
14982 case 0x3: case 0x7: case 0xB: case 0xD: case 0xE: case 0xF:
14983 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
14984 break;
14986 /* TERM_CTL_H: on, TERM_CTL_L: off */
14987 case 0x1: case 0x5: case 0x9: case 0xA: case 0xC:
14988 asc_dvc->cfg->termination |= TERM_CTL_H;
14989 break;
14991 /* TERM_CTL_H: off, TERM_CTL_L: off */
14992 case 0x2: case 0x6:
14993 break;
14998 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
15000 scsi_cfg1 &= ~TERM_CTL;
15003 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
15004 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
15005 * referenced, because the hardware internally inverts
15006 * the Termination High and Low bits if TERM_POL is set.
15008 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
15011 * Set SCSI_CFG1 Microcode Default Value
15013 * Set filter value and possibly modified termination control
15014 * bits in the Microcode SCSI_CFG1 Register Value.
15016 * The microcode will set the SCSI_CFG1 register using this value
15017 * after it is started below.
15019 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
15020 FLTR_DISABLE | scsi_cfg1);
15023 * Set MEM_CFG Microcode Default Value
15025 * The microcode will set the MEM_CFG register using this value
15026 * after it is started below.
15028 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15029 * are defined.
15031 * ASC-3550 has 8KB internal memory.
15033 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15034 BIOS_EN | RAM_SZ_8KB);
15037 * Set SEL_MASK Microcode Default Value
15039 * The microcode will set the SEL_MASK register using this value
15040 * after it is started below.
15042 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15043 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15046 * Build carrier freelist.
15048 * Driver must have already allocated memory and set 'carrier_buf'.
15050 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15052 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15053 asc_dvc->carr_freelist = NULL;
15054 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
15056 buf_size = ADV_CARRIER_BUFSIZE;
15057 } else
15059 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15062 do {
15064 * Get physical address of the carrier 'carrp'.
15066 contig_len = sizeof(ADV_CARR_T);
15067 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
15068 (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
15070 buf_size -= sizeof(ADV_CARR_T);
15073 * If the current carrier is not physically contiguous, then
15074 * maybe there was a page crossing. Try the next carrier aligned
15075 * start address.
15077 if (contig_len < sizeof(ADV_CARR_T))
15079 carrp++;
15080 continue;
15083 carrp->carr_pa = carr_paddr;
15084 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15087 * Insert the carrier at the beginning of the freelist.
15089 carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15090 asc_dvc->carr_freelist = carrp;
15092 carrp++;
15094 while (buf_size > 0);
15097 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15100 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
15102 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15103 return ADV_ERROR;
15105 asc_dvc->carr_freelist = (ADV_CARR_T *)
15106 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15109 * The first command issued will be placed in the stopper carrier.
15111 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15114 * Set RISC ICQ physical address start value.
15116 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15119 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15121 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
15123 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15124 return ADV_ERROR;
15126 asc_dvc->carr_freelist = (ADV_CARR_T *)
15127 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15130 * The first command completed by the RISC will be placed in
15131 * the stopper.
15133 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15134 * completed the RISC will set the ASC_RQ_STOPPER bit.
15136 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15139 * Set RISC IRQ physical address start value.
15141 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15142 asc_dvc->carr_pending_cnt = 0;
15144 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15145 (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
15147 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15148 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15150 /* finally, finally, gentlemen, start your engine */
15151 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15154 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15155 * Resets should be performed. The RISC has to be running
15156 * to issue a SCSI Bus Reset.
15158 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
15161 * If the BIOS Signature is present in memory, restore the
15162 * BIOS Handshake Configuration Table and do not perform
15163 * a SCSI Bus Reset.
15165 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
15168 * Restore per TID negotiated values.
15170 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15171 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15172 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15173 for (tid = 0; tid <= ADV_MAX_TID; tid++)
15175 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15176 max_cmd[tid]);
15178 } else
15180 if (AdvResetSB(asc_dvc) != ADV_TRUE)
15182 warn_code = ASC_WARN_BUSRESET_ERROR;
15187 return warn_code;
15191 * Initialize the ASC-38C0800.
15193 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15195 * For a non-fatal error return a warning code. If there are no warnings
15196 * then 0 is returned.
15198 * Needed after initialization for error recovery.
15200 STATIC int
15201 AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
15203 AdvPortAddr iop_base;
15204 ushort warn_code;
15205 ADV_DCNT sum;
15206 int begin_addr;
15207 int end_addr;
15208 ushort code_sum;
15209 int word;
15210 int j;
15211 int adv_asc38C0800_expanded_size;
15212 ADV_CARR_T *carrp;
15213 ADV_DCNT contig_len;
15214 ADV_SDCNT buf_size;
15215 ADV_PADDR carr_paddr;
15216 int i;
15217 ushort scsi_cfg1;
15218 uchar byte;
15219 uchar tid;
15220 ushort bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
15221 ushort wdtr_able, sdtr_able, tagqng_able;
15222 uchar max_cmd[ADV_MAX_TID + 1];
15224 /* If there is already an error, don't continue. */
15225 if (asc_dvc->err_code != 0)
15227 return ADV_ERROR;
15231 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
15233 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800)
15235 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
15236 return ADV_ERROR;
15239 warn_code = 0;
15240 iop_base = asc_dvc->iop_base;
15243 * Save the RISC memory BIOS region before writing the microcode.
15244 * The BIOS may already be loaded and using its RISC LRAM region
15245 * so its region must be saved and restored.
15247 * Note: This code makes the assumption, which is currently true,
15248 * that a chip reset does not clear RISC LRAM.
15250 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15252 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15256 * Save current per TID negotiated values.
15258 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15259 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15260 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15261 for (tid = 0; tid <= ADV_MAX_TID; tid++)
15263 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15264 max_cmd[tid]);
15268 * RAM BIST (RAM Built-In Self Test)
15270 * Address : I/O base + offset 0x38h register (byte).
15271 * Function: Bit 7-6(RW) : RAM mode
15272 * Normal Mode : 0x00
15273 * Pre-test Mode : 0x40
15274 * RAM Test Mode : 0x80
15275 * Bit 5 : unused
15276 * Bit 4(RO) : Done bit
15277 * Bit 3-0(RO) : Status
15278 * Host Error : 0x08
15279 * Int_RAM Error : 0x04
15280 * RISC Error : 0x02
15281 * SCSI Error : 0x01
15282 * No Error : 0x00
15284 * Note: RAM BIST code should be put right here, before loading the
15285 * microcode and after saving the RISC memory BIOS region.
15289 * LRAM Pre-test
15291 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15292 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15293 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15294 * to NORMAL_MODE, return an error too.
15296 for (i = 0; i < 2; i++)
15298 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15299 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15300 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15301 if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE)
15303 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15304 return ADV_ERROR;
15307 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15308 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15309 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15310 != NORMAL_VALUE)
15312 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15313 return ADV_ERROR;
15318 * LRAM Test - It takes about 1.5 ms to run through the test.
15320 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15321 * If Done bit not set or Status not 0, save register byte, set the
15322 * err_code, and return an error.
15324 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15325 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
15327 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15328 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0)
15330 /* Get here if Done bit not set or Status not 0. */
15331 asc_dvc->bist_err_code = byte; /* for BIOS display message */
15332 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15333 return ADV_ERROR;
15336 /* We need to reset back to normal mode after LRAM test passes. */
15337 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15340 * Load the Microcode
15342 * Write the microcode image to RISC memory starting at address 0.
15345 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15347 /* Assume the following compressed format of the microcode buffer:
15349 * 254 word (508 byte) table indexed by byte code followed
15350 * by the following byte codes:
15352 * 1-Byte Code:
15353 * 00: Emit word 0 in table.
15354 * 01: Emit word 1 in table.
15356 * FD: Emit word 253 in table.
15358 * Multi-Byte Code:
15359 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15360 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15362 word = 0;
15363 for (i = 253 * 2; i < _adv_asc38C0800_size; i++)
15365 if (_adv_asc38C0800_buf[i] == 0xff)
15367 for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++)
15369 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15370 _adv_asc38C0800_buf[i + 3] << 8) |
15371 _adv_asc38C0800_buf[i + 2]));
15372 word++;
15374 i += 3;
15375 } else if (_adv_asc38C0800_buf[i] == 0xfe)
15377 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15378 _adv_asc38C0800_buf[i + 2] << 8) |
15379 _adv_asc38C0800_buf[i + 1]));
15380 i += 2;
15381 word++;
15382 } else
15384 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15385 _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) |
15386 _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
15387 word++;
15392 * Set 'word' for later use to clear the rest of memory and save
15393 * the expanded mcode size.
15395 word *= 2;
15396 adv_asc38C0800_expanded_size = word;
15399 * Clear the rest of ASC-38C0800 Internal RAM (16KB).
15401 for (; word < ADV_38C0800_MEMSIZE; word += 2)
15403 AdvWriteWordAutoIncLram(iop_base, 0);
15407 * Verify the microcode checksum.
15409 sum = 0;
15410 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15412 for (word = 0; word < adv_asc38C0800_expanded_size; word += 2)
15414 sum += AdvReadWordAutoIncLram(iop_base);
15416 ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
15418 ASC_DBG2(1,
15419 "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
15420 (ulong) sum, (ulong) _adv_asc38C0800_chksum);
15422 if (sum != _adv_asc38C0800_chksum)
15424 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15425 return ADV_ERROR;
15429 * Restore the RISC memory BIOS region.
15431 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15433 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15437 * Calculate and write the microcode code checksum to the microcode
15438 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15440 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15441 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15442 code_sum = 0;
15443 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15444 for (word = begin_addr; word < end_addr; word += 2)
15446 code_sum += AdvReadWordAutoIncLram(iop_base);
15448 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15451 * Read microcode version and date.
15453 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
15454 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
15457 * Set the chip type to indicate the ASC38C0800.
15459 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
15462 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15463 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15464 * cable detection and then we are able to read C_DET[3:0].
15466 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15467 * Microcode Default Value' section below.
15469 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15470 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV);
15473 * If the PCI Configuration Command Register "Parity Error Response
15474 * Control" Bit was clear (0), then set the microcode variable
15475 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15476 * to ignore DMA parity errors.
15478 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
15480 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15481 word |= CONTROL_FLAG_IGNORE_PERR;
15482 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15486 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
15487 * bits for the default FIFO threshold.
15489 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
15491 * For DMA Errata #4 set the BC_THRESH_ENB bit.
15493 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15494 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
15497 * Microcode operating variables for WDTR, SDTR, and command tag
15498 * queuing will be set in AdvInquiryHandling() based on what a
15499 * device reports it is capable of in Inquiry byte 7.
15501 * If SCSI Bus Resets have been disabled, then directly set
15502 * SDTR and WDTR from the EEPROM configuration. This will allow
15503 * the BIOS and warm boot to work without a SCSI bus hang on
15504 * the Inquiry caused by host and target mismatched DTR values.
15505 * Without the SCSI Bus Reset, before an Inquiry a device can't
15506 * be assumed to be in Asynchronous, Narrow mode.
15508 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
15510 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
15511 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
15515 * Set microcode operating variables for DISC and SDTR_SPEED1,
15516 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15517 * configuration values.
15519 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15520 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15521 * without determining here whether the device supports SDTR.
15523 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
15524 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15525 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15526 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15527 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15530 * Set SCSI_CFG0 Microcode Default Value.
15532 * The microcode will set the SCSI_CFG0 register using this value
15533 * after it is started below.
15535 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15536 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15537 asc_dvc->chip_scsi_id);
15540 * Determine SCSI_CFG1 Microcode Default Value.
15542 * The microcode will set the SCSI_CFG1 register using this value
15543 * after it is started below.
15546 /* Read current SCSI_CFG1 Register value. */
15547 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15550 * If the internal narrow cable is reversed all of the SCSI_CTRL
15551 * register signals will be set. Check for and return an error if
15552 * this condition is found.
15554 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
15556 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15557 return ADV_ERROR;
15561 * All kind of combinations of devices attached to one of four connectors
15562 * are acceptable except HVD device attached. For example, LVD device can
15563 * be attached to SE connector while SE device attached to LVD connector.
15564 * If LVD device attached to SE connector, it only runs up to Ultra speed.
15566 * If an HVD device is attached to one of LVD connectors, return an error.
15567 * However, there is no way to detect HVD device attached to SE connectors.
15569 if (scsi_cfg1 & HVD)
15571 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15572 return ADV_ERROR;
15576 * If either SE or LVD automatic termination control is enabled, then
15577 * set the termination value based on a table listed in a_condor.h.
15579 * If manual termination was specified with an EEPROM setting then
15580 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
15581 * be 'ored' into SCSI_CFG1.
15583 if ((asc_dvc->cfg->termination & TERM_SE) == 0)
15585 /* SE automatic termination control is enabled. */
15586 switch(scsi_cfg1 & C_DET_SE)
15588 /* TERM_SE_HI: on, TERM_SE_LO: on */
15589 case 0x1: case 0x2: case 0x3:
15590 asc_dvc->cfg->termination |= TERM_SE;
15591 break;
15593 /* TERM_SE_HI: on, TERM_SE_LO: off */
15594 case 0x0:
15595 asc_dvc->cfg->termination |= TERM_SE_HI;
15596 break;
15600 if ((asc_dvc->cfg->termination & TERM_LVD) == 0)
15602 /* LVD automatic termination control is enabled. */
15603 switch(scsi_cfg1 & C_DET_LVD)
15605 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
15606 case 0x4: case 0x8: case 0xC:
15607 asc_dvc->cfg->termination |= TERM_LVD;
15608 break;
15610 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
15611 case 0x0:
15612 break;
15617 * Clear any set TERM_SE and TERM_LVD bits.
15619 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
15622 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
15624 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
15627 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
15628 * and set possibly modified termination control bits in the Microcode
15629 * SCSI_CFG1 Register Value.
15631 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
15634 * Set SCSI_CFG1 Microcode Default Value
15636 * Set possibly modified termination control and reset DIS_TERM_DRV
15637 * bits in the Microcode SCSI_CFG1 Register Value.
15639 * The microcode will set the SCSI_CFG1 register using this value
15640 * after it is started below.
15642 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15645 * Set MEM_CFG Microcode Default Value
15647 * The microcode will set the MEM_CFG register using this value
15648 * after it is started below.
15650 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15651 * are defined.
15653 * ASC-38C0800 has 16KB internal memory.
15655 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15656 BIOS_EN | RAM_SZ_16KB);
15659 * Set SEL_MASK Microcode Default Value
15661 * The microcode will set the SEL_MASK register using this value
15662 * after it is started below.
15664 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15665 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15668 * Build the carrier freelist.
15670 * Driver must have already allocated memory and set 'carrier_buf'.
15672 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15674 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15675 asc_dvc->carr_freelist = NULL;
15676 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
15678 buf_size = ADV_CARRIER_BUFSIZE;
15679 } else
15681 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15684 do {
15686 * Get physical address for the carrier 'carrp'.
15688 contig_len = sizeof(ADV_CARR_T);
15689 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
15690 (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
15692 buf_size -= sizeof(ADV_CARR_T);
15695 * If the current carrier is not physically contiguous, then
15696 * maybe there was a page crossing. Try the next carrier aligned
15697 * start address.
15699 if (contig_len < sizeof(ADV_CARR_T))
15701 carrp++;
15702 continue;
15705 carrp->carr_pa = carr_paddr;
15706 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15709 * Insert the carrier at the beginning of the freelist.
15711 carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15712 asc_dvc->carr_freelist = carrp;
15714 carrp++;
15716 while (buf_size > 0);
15719 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15722 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
15724 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15725 return ADV_ERROR;
15727 asc_dvc->carr_freelist = (ADV_CARR_T *)
15728 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15731 * The first command issued will be placed in the stopper carrier.
15733 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15736 * Set RISC ICQ physical address start value.
15737 * carr_pa is LE, must be native before write
15739 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15742 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15744 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
15746 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15747 return ADV_ERROR;
15749 asc_dvc->carr_freelist = (ADV_CARR_T *)
15750 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15753 * The first command completed by the RISC will be placed in
15754 * the stopper.
15756 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15757 * completed the RISC will set the ASC_RQ_STOPPER bit.
15759 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15762 * Set RISC IRQ physical address start value.
15764 * carr_pa is LE, must be native before write *
15766 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15767 asc_dvc->carr_pending_cnt = 0;
15769 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15770 (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
15772 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15773 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15775 /* finally, finally, gentlemen, start your engine */
15776 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15779 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15780 * Resets should be performed. The RISC has to be running
15781 * to issue a SCSI Bus Reset.
15783 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
15786 * If the BIOS Signature is present in memory, restore the
15787 * BIOS Handshake Configuration Table and do not perform
15788 * a SCSI Bus Reset.
15790 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
15793 * Restore per TID negotiated values.
15795 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15796 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15797 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15798 for (tid = 0; tid <= ADV_MAX_TID; tid++)
15800 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15801 max_cmd[tid]);
15803 } else
15805 if (AdvResetSB(asc_dvc) != ADV_TRUE)
15807 warn_code = ASC_WARN_BUSRESET_ERROR;
15812 return warn_code;
15816 * Initialize the ASC-38C1600.
15818 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
15820 * For a non-fatal error return a warning code. If there are no warnings
15821 * then 0 is returned.
15823 * Needed after initialization for error recovery.
15825 STATIC int
15826 AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
15828 AdvPortAddr iop_base;
15829 ushort warn_code;
15830 ADV_DCNT sum;
15831 int begin_addr;
15832 int end_addr;
15833 ushort code_sum;
15834 long word;
15835 int j;
15836 int adv_asc38C1600_expanded_size;
15837 ADV_CARR_T *carrp;
15838 ADV_DCNT contig_len;
15839 ADV_SDCNT buf_size;
15840 ADV_PADDR carr_paddr;
15841 int i;
15842 ushort scsi_cfg1;
15843 uchar byte;
15844 uchar tid;
15845 ushort bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
15846 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
15847 uchar max_cmd[ASC_MAX_TID + 1];
15849 /* If there is already an error, don't continue. */
15850 if (asc_dvc->err_code != 0)
15852 return ADV_ERROR;
15856 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
15858 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600)
15860 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
15861 return ADV_ERROR;
15864 warn_code = 0;
15865 iop_base = asc_dvc->iop_base;
15868 * Save the RISC memory BIOS region before writing the microcode.
15869 * The BIOS may already be loaded and using its RISC LRAM region
15870 * so its region must be saved and restored.
15872 * Note: This code makes the assumption, which is currently true,
15873 * that a chip reset does not clear RISC LRAM.
15875 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15877 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15881 * Save current per TID negotiated values.
15883 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15884 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15885 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15886 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15887 for (tid = 0; tid <= ASC_MAX_TID; tid++)
15889 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15890 max_cmd[tid]);
15894 * RAM BIST (Built-In Self Test)
15896 * Address : I/O base + offset 0x38h register (byte).
15897 * Function: Bit 7-6(RW) : RAM mode
15898 * Normal Mode : 0x00
15899 * Pre-test Mode : 0x40
15900 * RAM Test Mode : 0x80
15901 * Bit 5 : unused
15902 * Bit 4(RO) : Done bit
15903 * Bit 3-0(RO) : Status
15904 * Host Error : 0x08
15905 * Int_RAM Error : 0x04
15906 * RISC Error : 0x02
15907 * SCSI Error : 0x01
15908 * No Error : 0x00
15910 * Note: RAM BIST code should be put right here, before loading the
15911 * microcode and after saving the RISC memory BIOS region.
15915 * LRAM Pre-test
15917 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15918 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15919 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15920 * to NORMAL_MODE, return an error too.
15922 for (i = 0; i < 2; i++)
15924 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15925 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15926 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15927 if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE)
15929 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15930 return ADV_ERROR;
15933 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15934 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15935 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15936 != NORMAL_VALUE)
15938 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15939 return ADV_ERROR;
15944 * LRAM Test - It takes about 1.5 ms to run through the test.
15946 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15947 * If Done bit not set or Status not 0, save register byte, set the
15948 * err_code, and return an error.
15950 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15951 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
15953 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15954 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0)
15956 /* Get here if Done bit not set or Status not 0. */
15957 asc_dvc->bist_err_code = byte; /* for BIOS display message */
15958 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15959 return ADV_ERROR;
15962 /* We need to reset back to normal mode after LRAM test passes. */
15963 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15966 * Load the Microcode
15968 * Write the microcode image to RISC memory starting at address 0.
15971 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15974 * Assume the following compressed format of the microcode buffer:
15976 * 254 word (508 byte) table indexed by byte code followed
15977 * by the following byte codes:
15979 * 1-Byte Code:
15980 * 00: Emit word 0 in table.
15981 * 01: Emit word 1 in table.
15983 * FD: Emit word 253 in table.
15985 * Multi-Byte Code:
15986 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15987 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15989 word = 0;
15990 for (i = 253 * 2; i < _adv_asc38C1600_size; i++)
15992 if (_adv_asc38C1600_buf[i] == 0xff)
15994 for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++)
15996 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15997 _adv_asc38C1600_buf[i + 3] << 8) |
15998 _adv_asc38C1600_buf[i + 2]));
15999 word++;
16001 i += 3;
16002 } else if (_adv_asc38C1600_buf[i] == 0xfe)
16004 AdvWriteWordAutoIncLram(iop_base, (((ushort)
16005 _adv_asc38C1600_buf[i + 2] << 8) |
16006 _adv_asc38C1600_buf[i + 1]));
16007 i += 2;
16008 word++;
16009 } else
16011 AdvWriteWordAutoIncLram(iop_base, (((ushort)
16012 _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) |
16013 _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
16014 word++;
16019 * Set 'word' for later use to clear the rest of memory and save
16020 * the expanded mcode size.
16022 word *= 2;
16023 adv_asc38C1600_expanded_size = word;
16026 * Clear the rest of ASC-38C1600 Internal RAM (32KB).
16028 for (; word < ADV_38C1600_MEMSIZE; word += 2)
16030 AdvWriteWordAutoIncLram(iop_base, 0);
16034 * Verify the microcode checksum.
16036 sum = 0;
16037 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
16039 for (word = 0; word < adv_asc38C1600_expanded_size; word += 2)
16041 sum += AdvReadWordAutoIncLram(iop_base);
16044 if (sum != _adv_asc38C1600_chksum)
16046 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
16047 return ADV_ERROR;
16051 * Restore the RISC memory BIOS region.
16053 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
16055 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
16059 * Calculate and write the microcode code checksum to the microcode
16060 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
16062 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
16063 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
16064 code_sum = 0;
16065 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
16066 for (word = begin_addr; word < end_addr; word += 2)
16068 code_sum += AdvReadWordAutoIncLram(iop_base);
16070 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
16073 * Read microcode version and date.
16075 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
16076 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
16079 * Set the chip type to indicate the ASC38C1600.
16081 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
16084 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
16085 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
16086 * cable detection and then we are able to read C_DET[3:0].
16088 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
16089 * Microcode Default Value' section below.
16091 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
16092 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV);
16095 * If the PCI Configuration Command Register "Parity Error Response
16096 * Control" Bit was clear (0), then set the microcode variable
16097 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
16098 * to ignore DMA parity errors.
16100 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
16102 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16103 word |= CONTROL_FLAG_IGNORE_PERR;
16104 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16108 * If the BIOS control flag AIPP (Asynchronous Information
16109 * Phase Protection) disable bit is not set, then set the firmware
16110 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
16111 * AIPP checking and encoding.
16113 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0)
16115 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16116 word |= CONTROL_FLAG_ENABLE_AIPP;
16117 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16121 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
16122 * and START_CTL_TH [3:2].
16124 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
16125 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
16128 * Microcode operating variables for WDTR, SDTR, and command tag
16129 * queuing will be set in AdvInquiryHandling() based on what a
16130 * device reports it is capable of in Inquiry byte 7.
16132 * If SCSI Bus Resets have been disabled, then directly set
16133 * SDTR and WDTR from the EEPROM configuration. This will allow
16134 * the BIOS and warm boot to work without a SCSI bus hang on
16135 * the Inquiry caused by host and target mismatched DTR values.
16136 * Without the SCSI Bus Reset, before an Inquiry a device can't
16137 * be assumed to be in Asynchronous, Narrow mode.
16139 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
16141 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
16142 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
16146 * Set microcode operating variables for DISC and SDTR_SPEED1,
16147 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
16148 * configuration values.
16150 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
16151 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
16152 * without determining here whether the device supports SDTR.
16154 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
16155 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
16156 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
16157 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
16158 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
16161 * Set SCSI_CFG0 Microcode Default Value.
16163 * The microcode will set the SCSI_CFG0 register using this value
16164 * after it is started below.
16166 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
16167 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
16168 asc_dvc->chip_scsi_id);
16171 * Calculate SCSI_CFG1 Microcode Default Value.
16173 * The microcode will set the SCSI_CFG1 register using this value
16174 * after it is started below.
16176 * Each ASC-38C1600 function has only two cable detect bits.
16177 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
16179 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
16182 * If the cable is reversed all of the SCSI_CTRL register signals
16183 * will be set. Check for and return an error if this condition is
16184 * found.
16186 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
16188 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
16189 return ADV_ERROR;
16193 * Each ASC-38C1600 function has two connectors. Only an HVD device
16194 * can not be connected to either connector. An LVD device or SE device
16195 * may be connected to either connecor. If an SE device is connected,
16196 * then at most Ultra speed (20 Mhz) can be used on both connectors.
16198 * If an HVD device is attached, return an error.
16200 if (scsi_cfg1 & HVD)
16202 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
16203 return ADV_ERROR;
16207 * Each function in the ASC-38C1600 uses only the SE cable detect and
16208 * termination because there are two connectors for each function. Each
16209 * function may use either LVD or SE mode. Corresponding the SE automatic
16210 * termination control EEPROM bits are used for each function. Each
16211 * function has its own EEPROM. If SE automatic control is enabled for
16212 * the function, then set the termination value based on a table listed
16213 * in a_condor.h.
16215 * If manual termination is specified in the EEPROM for the function,
16216 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
16217 * ready to be 'ored' into SCSI_CFG1.
16219 if ((asc_dvc->cfg->termination & TERM_SE) == 0)
16221 /* SE automatic termination control is enabled. */
16222 switch(scsi_cfg1 & C_DET_SE)
16224 /* TERM_SE_HI: on, TERM_SE_LO: on */
16225 case 0x1: case 0x2: case 0x3:
16226 asc_dvc->cfg->termination |= TERM_SE;
16227 break;
16229 case 0x0:
16230 if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0)
16232 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
16234 else
16236 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
16237 asc_dvc->cfg->termination |= TERM_SE_HI;
16239 break;
16244 * Clear any set TERM_SE bits.
16246 scsi_cfg1 &= ~TERM_SE;
16249 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
16251 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
16254 * Clear Big Endian and Terminator Polarity bits and set possibly
16255 * modified termination control bits in the Microcode SCSI_CFG1
16256 * Register Value.
16258 * Big Endian bit is not used even on big endian machines.
16260 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
16263 * Set SCSI_CFG1 Microcode Default Value
16265 * Set possibly modified termination control bits in the Microcode
16266 * SCSI_CFG1 Register Value.
16268 * The microcode will set the SCSI_CFG1 register using this value
16269 * after it is started below.
16271 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
16274 * Set MEM_CFG Microcode Default Value
16276 * The microcode will set the MEM_CFG register using this value
16277 * after it is started below.
16279 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
16280 * are defined.
16282 * ASC-38C1600 has 32KB internal memory.
16284 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
16285 * out a special 16K Adv Library and Microcode version. After the issue
16286 * resolved, we should turn back to the 32K support. Both a_condor.h and
16287 * mcode.sas files also need to be updated.
16289 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
16290 * BIOS_EN | RAM_SZ_32KB);
16292 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, BIOS_EN | RAM_SZ_16KB);
16295 * Set SEL_MASK Microcode Default Value
16297 * The microcode will set the SEL_MASK register using this value
16298 * after it is started below.
16300 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
16301 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
16304 * Build the carrier freelist.
16306 * Driver must have already allocated memory and set 'carrier_buf'.
16309 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
16311 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
16312 asc_dvc->carr_freelist = NULL;
16313 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
16315 buf_size = ADV_CARRIER_BUFSIZE;
16316 } else
16318 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
16321 do {
16323 * Get physical address for the carrier 'carrp'.
16325 contig_len = sizeof(ADV_CARR_T);
16326 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
16327 (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
16329 buf_size -= sizeof(ADV_CARR_T);
16332 * If the current carrier is not physically contiguous, then
16333 * maybe there was a page crossing. Try the next carrier aligned
16334 * start address.
16336 if (contig_len < sizeof(ADV_CARR_T))
16338 carrp++;
16339 continue;
16342 carrp->carr_pa = carr_paddr;
16343 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
16346 * Insert the carrier at the beginning of the freelist.
16348 carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
16349 asc_dvc->carr_freelist = carrp;
16351 carrp++;
16353 while (buf_size > 0);
16356 * Set-up the Host->RISC Initiator Command Queue (ICQ).
16358 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
16360 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16361 return ADV_ERROR;
16363 asc_dvc->carr_freelist = (ADV_CARR_T *)
16364 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
16367 * The first command issued will be placed in the stopper carrier.
16369 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16372 * Set RISC ICQ physical address start value. Initialize the
16373 * COMMA register to the same value otherwise the RISC will
16374 * prematurely detect a command is available.
16376 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
16377 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
16378 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
16381 * Set-up the RISC->Host Initiator Response Queue (IRQ).
16383 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
16385 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16386 return ADV_ERROR;
16388 asc_dvc->carr_freelist = (ADV_CARR_T *)
16389 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
16392 * The first command completed by the RISC will be placed in
16393 * the stopper.
16395 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
16396 * completed the RISC will set the ASC_RQ_STOPPER bit.
16398 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16401 * Set RISC IRQ physical address start value.
16403 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
16404 asc_dvc->carr_pending_cnt = 0;
16406 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
16407 (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
16408 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
16409 AdvWriteWordRegister(iop_base, IOPW_PC, word);
16411 /* finally, finally, gentlemen, start your engine */
16412 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
16415 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
16416 * Resets should be performed. The RISC has to be running
16417 * to issue a SCSI Bus Reset.
16419 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
16422 * If the BIOS Signature is present in memory, restore the
16423 * per TID microcode operating variables.
16425 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
16428 * Restore per TID negotiated values.
16430 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16431 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16432 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16433 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16434 for (tid = 0; tid <= ASC_MAX_TID; tid++)
16436 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16437 max_cmd[tid]);
16439 } else
16441 if (AdvResetSB(asc_dvc) != ADV_TRUE)
16443 warn_code = ASC_WARN_BUSRESET_ERROR;
16448 return warn_code;
16452 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16453 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16454 * all of this is done.
16456 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16458 * For a non-fatal error return a warning code. If there are no warnings
16459 * then 0 is returned.
16461 * Note: Chip is stopped on entry.
16463 STATIC int __init
16464 AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
16466 AdvPortAddr iop_base;
16467 ushort warn_code;
16468 ADVEEP_3550_CONFIG eep_config;
16469 int i;
16471 iop_base = asc_dvc->iop_base;
16473 warn_code = 0;
16476 * Read the board's EEPROM configuration.
16478 * Set default values if a bad checksum is found.
16480 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16482 warn_code |= ASC_WARN_EEPROM_CHKSUM;
16485 * Set EEPROM default values.
16487 for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++)
16489 *((uchar *) &eep_config + i) =
16490 *((uchar *) &Default_3550_EEPROM_Config + i);
16494 * Assume the 6 byte board serial number that was read
16495 * from EEPROM is correct even if the EEPROM checksum
16496 * failed.
16498 eep_config.serial_number_word3 =
16499 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16501 eep_config.serial_number_word2 =
16502 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16504 eep_config.serial_number_word1 =
16505 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16507 AdvSet3550EEPConfig(iop_base, &eep_config);
16510 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16511 * EEPROM configuration that was read.
16513 * This is the mapping of EEPROM fields to Adv Library fields.
16515 asc_dvc->wdtr_able = eep_config.wdtr_able;
16516 asc_dvc->sdtr_able = eep_config.sdtr_able;
16517 asc_dvc->ultra_able = eep_config.ultra_able;
16518 asc_dvc->tagqng_able = eep_config.tagqng_able;
16519 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16520 asc_dvc->max_host_qng = eep_config.max_host_qng;
16521 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16522 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16523 asc_dvc->start_motor = eep_config.start_motor;
16524 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16525 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16526 asc_dvc->no_scam = eep_config.scam_tolerant;
16527 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16528 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16529 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16532 * Set the host maximum queuing (max. 253, min. 16) and the per device
16533 * maximum queuing (max. 63, min. 4).
16535 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
16537 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16538 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
16540 /* If the value is zero, assume it is uninitialized. */
16541 if (eep_config.max_host_qng == 0)
16543 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16544 } else
16546 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16550 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
16552 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16553 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
16555 /* If the value is zero, assume it is uninitialized. */
16556 if (eep_config.max_dvc_qng == 0)
16558 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16559 } else
16561 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16566 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16567 * set 'max_dvc_qng' to 'max_host_qng'.
16569 if (eep_config.max_dvc_qng > eep_config.max_host_qng)
16571 eep_config.max_dvc_qng = eep_config.max_host_qng;
16575 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16576 * values based on possibly adjusted EEPROM values.
16578 asc_dvc->max_host_qng = eep_config.max_host_qng;
16579 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16583 * If the EEPROM 'termination' field is set to automatic (0), then set
16584 * the ADV_DVC_CFG 'termination' field to automatic also.
16586 * If the termination is specified with a non-zero 'termination'
16587 * value check that a legal value is set and set the ADV_DVC_CFG
16588 * 'termination' field appropriately.
16590 if (eep_config.termination == 0)
16592 asc_dvc->cfg->termination = 0; /* auto termination */
16593 } else
16595 /* Enable manual control with low off / high off. */
16596 if (eep_config.termination == 1)
16598 asc_dvc->cfg->termination = TERM_CTL_SEL;
16600 /* Enable manual control with low off / high on. */
16601 } else if (eep_config.termination == 2)
16603 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
16605 /* Enable manual control with low on / high on. */
16606 } else if (eep_config.termination == 3)
16608 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
16609 } else
16612 * The EEPROM 'termination' field contains a bad value. Use
16613 * automatic termination instead.
16615 asc_dvc->cfg->termination = 0;
16616 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16620 return warn_code;
16624 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16625 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16626 * all of this is done.
16628 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16630 * For a non-fatal error return a warning code. If there are no warnings
16631 * then 0 is returned.
16633 * Note: Chip is stopped on entry.
16635 STATIC int __init
16636 AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
16638 AdvPortAddr iop_base;
16639 ushort warn_code;
16640 ADVEEP_38C0800_CONFIG eep_config;
16641 int i;
16642 uchar tid, termination;
16643 ushort sdtr_speed = 0;
16645 iop_base = asc_dvc->iop_base;
16647 warn_code = 0;
16650 * Read the board's EEPROM configuration.
16652 * Set default values if a bad checksum is found.
16654 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16656 warn_code |= ASC_WARN_EEPROM_CHKSUM;
16659 * Set EEPROM default values.
16661 for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++)
16663 *((uchar *) &eep_config + i) =
16664 *((uchar *) &Default_38C0800_EEPROM_Config + i);
16668 * Assume the 6 byte board serial number that was read
16669 * from EEPROM is correct even if the EEPROM checksum
16670 * failed.
16672 eep_config.serial_number_word3 =
16673 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16675 eep_config.serial_number_word2 =
16676 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16678 eep_config.serial_number_word1 =
16679 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16681 AdvSet38C0800EEPConfig(iop_base, &eep_config);
16684 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
16685 * EEPROM configuration that was read.
16687 * This is the mapping of EEPROM fields to Adv Library fields.
16689 asc_dvc->wdtr_able = eep_config.wdtr_able;
16690 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16691 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16692 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16693 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16694 asc_dvc->tagqng_able = eep_config.tagqng_able;
16695 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16696 asc_dvc->max_host_qng = eep_config.max_host_qng;
16697 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16698 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16699 asc_dvc->start_motor = eep_config.start_motor;
16700 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16701 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16702 asc_dvc->no_scam = eep_config.scam_tolerant;
16703 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16704 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16705 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16708 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16709 * are set, then set an 'sdtr_able' bit for it.
16711 asc_dvc->sdtr_able = 0;
16712 for (tid = 0; tid <= ADV_MAX_TID; tid++)
16714 if (tid == 0)
16716 sdtr_speed = asc_dvc->sdtr_speed1;
16717 } else if (tid == 4)
16719 sdtr_speed = asc_dvc->sdtr_speed2;
16720 } else if (tid == 8)
16722 sdtr_speed = asc_dvc->sdtr_speed3;
16723 } else if (tid == 12)
16725 sdtr_speed = asc_dvc->sdtr_speed4;
16727 if (sdtr_speed & ADV_MAX_TID)
16729 asc_dvc->sdtr_able |= (1 << tid);
16731 sdtr_speed >>= 4;
16735 * Set the host maximum queuing (max. 253, min. 16) and the per device
16736 * maximum queuing (max. 63, min. 4).
16738 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
16740 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16741 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
16743 /* If the value is zero, assume it is uninitialized. */
16744 if (eep_config.max_host_qng == 0)
16746 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16747 } else
16749 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16753 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
16755 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16756 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
16758 /* If the value is zero, assume it is uninitialized. */
16759 if (eep_config.max_dvc_qng == 0)
16761 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16762 } else
16764 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16769 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16770 * set 'max_dvc_qng' to 'max_host_qng'.
16772 if (eep_config.max_dvc_qng > eep_config.max_host_qng)
16774 eep_config.max_dvc_qng = eep_config.max_host_qng;
16778 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16779 * values based on possibly adjusted EEPROM values.
16781 asc_dvc->max_host_qng = eep_config.max_host_qng;
16782 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16785 * If the EEPROM 'termination' field is set to automatic (0), then set
16786 * the ADV_DVC_CFG 'termination' field to automatic also.
16788 * If the termination is specified with a non-zero 'termination'
16789 * value check that a legal value is set and set the ADV_DVC_CFG
16790 * 'termination' field appropriately.
16792 if (eep_config.termination_se == 0)
16794 termination = 0; /* auto termination for SE */
16795 } else
16797 /* Enable manual control with low off / high off. */
16798 if (eep_config.termination_se == 1)
16800 termination = 0;
16802 /* Enable manual control with low off / high on. */
16803 } else if (eep_config.termination_se == 2)
16805 termination = TERM_SE_HI;
16807 /* Enable manual control with low on / high on. */
16808 } else if (eep_config.termination_se == 3)
16810 termination = TERM_SE;
16811 } else
16814 * The EEPROM 'termination_se' field contains a bad value.
16815 * Use automatic termination instead.
16817 termination = 0;
16818 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16822 if (eep_config.termination_lvd == 0)
16824 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
16825 } else
16827 /* Enable manual control with low off / high off. */
16828 if (eep_config.termination_lvd == 1)
16830 asc_dvc->cfg->termination = termination;
16832 /* Enable manual control with low off / high on. */
16833 } else if (eep_config.termination_lvd == 2)
16835 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16837 /* Enable manual control with low on / high on. */
16838 } else if (eep_config.termination_lvd == 3)
16840 asc_dvc->cfg->termination =
16841 termination | TERM_LVD;
16842 } else
16845 * The EEPROM 'termination_lvd' field contains a bad value.
16846 * Use automatic termination instead.
16848 asc_dvc->cfg->termination = termination;
16849 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16853 return warn_code;
16857 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
16858 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
16859 * all of this is done.
16861 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
16863 * For a non-fatal error return a warning code. If there are no warnings
16864 * then 0 is returned.
16866 * Note: Chip is stopped on entry.
16868 STATIC int __init
16869 AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
16871 AdvPortAddr iop_base;
16872 ushort warn_code;
16873 ADVEEP_38C1600_CONFIG eep_config;
16874 int i;
16875 uchar tid, termination;
16876 ushort sdtr_speed = 0;
16878 iop_base = asc_dvc->iop_base;
16880 warn_code = 0;
16883 * Read the board's EEPROM configuration.
16885 * Set default values if a bad checksum is found.
16887 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16889 warn_code |= ASC_WARN_EEPROM_CHKSUM;
16892 * Set EEPROM default values.
16894 for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++)
16896 if (i == 1 && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) != 0)
16899 * Set Function 1 EEPROM Word 0 MSB
16901 * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11)
16902 * EEPROM bits.
16904 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and
16905 * old Mac system booting problem. The Expansion ROM must
16906 * be disabled in Function 1 for these systems.
16909 *((uchar *) &eep_config + i) =
16910 ((*((uchar *) &Default_38C1600_EEPROM_Config + i)) &
16911 (~(((ADV_EEPROM_BIOS_ENABLE | ADV_EEPROM_INTAB) >> 8) &
16912 0xFF)));
16915 * Set the INTAB (bit 11) if the GPIO 0 input indicates
16916 * the Function 1 interrupt line is wired to INTA.
16918 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
16919 * 1 - Function 1 interrupt line wired to INT A.
16920 * 0 - Function 1 interrupt line wired to INT B.
16922 * Note: Adapter boards always have Function 0 wired to INTA.
16923 * Put all 5 GPIO bits in input mode and then read
16924 * their input values.
16926 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
16927 if (AdvReadByteRegister(iop_base, IOPB_GPIO_DATA) & 0x01)
16929 /* Function 1 interrupt wired to INTA; Set EEPROM bit. */
16930 *((uchar *) &eep_config + i) |=
16931 ((ADV_EEPROM_INTAB >> 8) & 0xFF);
16934 else
16936 *((uchar *) &eep_config + i) =
16937 *((uchar *) &Default_38C1600_EEPROM_Config + i);
16942 * Assume the 6 byte board serial number that was read
16943 * from EEPROM is correct even if the EEPROM checksum
16944 * failed.
16946 eep_config.serial_number_word3 =
16947 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16949 eep_config.serial_number_word2 =
16950 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16952 eep_config.serial_number_word1 =
16953 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16955 AdvSet38C1600EEPConfig(iop_base, &eep_config);
16959 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16960 * EEPROM configuration that was read.
16962 * This is the mapping of EEPROM fields to Adv Library fields.
16964 asc_dvc->wdtr_able = eep_config.wdtr_able;
16965 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16966 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16967 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16968 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16969 asc_dvc->ppr_able = 0;
16970 asc_dvc->tagqng_able = eep_config.tagqng_able;
16971 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16972 asc_dvc->max_host_qng = eep_config.max_host_qng;
16973 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16974 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
16975 asc_dvc->start_motor = eep_config.start_motor;
16976 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16977 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16978 asc_dvc->no_scam = eep_config.scam_tolerant;
16981 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16982 * are set, then set an 'sdtr_able' bit for it.
16984 asc_dvc->sdtr_able = 0;
16985 for (tid = 0; tid <= ASC_MAX_TID; tid++)
16987 if (tid == 0)
16989 sdtr_speed = asc_dvc->sdtr_speed1;
16990 } else if (tid == 4)
16992 sdtr_speed = asc_dvc->sdtr_speed2;
16993 } else if (tid == 8)
16995 sdtr_speed = asc_dvc->sdtr_speed3;
16996 } else if (tid == 12)
16998 sdtr_speed = asc_dvc->sdtr_speed4;
17000 if (sdtr_speed & ASC_MAX_TID)
17002 asc_dvc->sdtr_able |= (1 << tid);
17004 sdtr_speed >>= 4;
17008 * Set the host maximum queuing (max. 253, min. 16) and the per device
17009 * maximum queuing (max. 63, min. 4).
17011 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
17013 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17014 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
17016 /* If the value is zero, assume it is uninitialized. */
17017 if (eep_config.max_host_qng == 0)
17019 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17020 } else
17022 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
17026 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
17028 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17029 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
17031 /* If the value is zero, assume it is uninitialized. */
17032 if (eep_config.max_dvc_qng == 0)
17034 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17035 } else
17037 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
17042 * If 'max_dvc_qng' is greater than 'max_host_qng', then
17043 * set 'max_dvc_qng' to 'max_host_qng'.
17045 if (eep_config.max_dvc_qng > eep_config.max_host_qng)
17047 eep_config.max_dvc_qng = eep_config.max_host_qng;
17051 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
17052 * values based on possibly adjusted EEPROM values.
17054 asc_dvc->max_host_qng = eep_config.max_host_qng;
17055 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
17058 * If the EEPROM 'termination' field is set to automatic (0), then set
17059 * the ASC_DVC_CFG 'termination' field to automatic also.
17061 * If the termination is specified with a non-zero 'termination'
17062 * value check that a legal value is set and set the ASC_DVC_CFG
17063 * 'termination' field appropriately.
17065 if (eep_config.termination_se == 0)
17067 termination = 0; /* auto termination for SE */
17068 } else
17070 /* Enable manual control with low off / high off. */
17071 if (eep_config.termination_se == 1)
17073 termination = 0;
17075 /* Enable manual control with low off / high on. */
17076 } else if (eep_config.termination_se == 2)
17078 termination = TERM_SE_HI;
17080 /* Enable manual control with low on / high on. */
17081 } else if (eep_config.termination_se == 3)
17083 termination = TERM_SE;
17084 } else
17087 * The EEPROM 'termination_se' field contains a bad value.
17088 * Use automatic termination instead.
17090 termination = 0;
17091 warn_code |= ASC_WARN_EEPROM_TERMINATION;
17095 if (eep_config.termination_lvd == 0)
17097 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
17098 } else
17100 /* Enable manual control with low off / high off. */
17101 if (eep_config.termination_lvd == 1)
17103 asc_dvc->cfg->termination = termination;
17105 /* Enable manual control with low off / high on. */
17106 } else if (eep_config.termination_lvd == 2)
17108 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
17110 /* Enable manual control with low on / high on. */
17111 } else if (eep_config.termination_lvd == 3)
17113 asc_dvc->cfg->termination =
17114 termination | TERM_LVD;
17115 } else
17118 * The EEPROM 'termination_lvd' field contains a bad value.
17119 * Use automatic termination instead.
17121 asc_dvc->cfg->termination = termination;
17122 warn_code |= ASC_WARN_EEPROM_TERMINATION;
17126 return warn_code;
17130 * Read EEPROM configuration into the specified buffer.
17132 * Return a checksum based on the EEPROM configuration read.
17134 STATIC ushort __init
17135 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
17137 ushort wval, chksum;
17138 ushort *wbuf;
17139 int eep_addr;
17140 ushort *charfields;
17142 charfields = (ushort *) &ADVEEP_3550_Config_Field_IsChar;
17143 wbuf = (ushort *) cfg_buf;
17144 chksum = 0;
17146 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17147 eep_addr < ADV_EEP_DVC_CFG_END;
17148 eep_addr++, wbuf++)
17150 wval = AdvReadEEPWord(iop_base, eep_addr);
17151 chksum += wval; /* Checksum is calculated from word values. */
17152 if (*charfields++) {
17153 *wbuf = le16_to_cpu(wval);
17154 } else {
17155 *wbuf = wval;
17158 /* Read checksum word. */
17159 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17160 wbuf++; charfields++;
17162 /* Read rest of EEPROM not covered by the checksum. */
17163 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17164 eep_addr < ADV_EEP_MAX_WORD_ADDR;
17165 eep_addr++, wbuf++)
17167 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17168 if (*charfields++) {
17169 *wbuf = le16_to_cpu(*wbuf);
17172 return chksum;
17176 * Read EEPROM configuration into the specified buffer.
17178 * Return a checksum based on the EEPROM configuration read.
17180 STATIC ushort __init
17181 AdvGet38C0800EEPConfig(AdvPortAddr iop_base,
17182 ADVEEP_38C0800_CONFIG *cfg_buf)
17184 ushort wval, chksum;
17185 ushort *wbuf;
17186 int eep_addr;
17187 ushort *charfields;
17189 charfields = (ushort *) &ADVEEP_38C0800_Config_Field_IsChar;
17190 wbuf = (ushort *) cfg_buf;
17191 chksum = 0;
17193 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17194 eep_addr < ADV_EEP_DVC_CFG_END;
17195 eep_addr++, wbuf++)
17197 wval = AdvReadEEPWord(iop_base, eep_addr);
17198 chksum += wval; /* Checksum is calculated from word values. */
17199 if (*charfields++) {
17200 *wbuf = le16_to_cpu(wval);
17201 } else {
17202 *wbuf = wval;
17205 /* Read checksum word. */
17206 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17207 wbuf++; charfields++;
17209 /* Read rest of EEPROM not covered by the checksum. */
17210 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17211 eep_addr < ADV_EEP_MAX_WORD_ADDR;
17212 eep_addr++, wbuf++)
17214 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17215 if (*charfields++) {
17216 *wbuf = le16_to_cpu(*wbuf);
17219 return chksum;
17223 * Read EEPROM configuration into the specified buffer.
17225 * Return a checksum based on the EEPROM configuration read.
17227 STATIC ushort __init
17228 AdvGet38C1600EEPConfig(AdvPortAddr iop_base,
17229 ADVEEP_38C1600_CONFIG *cfg_buf)
17231 ushort wval, chksum;
17232 ushort *wbuf;
17233 int eep_addr;
17234 ushort *charfields;
17236 charfields = (ushort*) &ADVEEP_38C1600_Config_Field_IsChar;
17237 wbuf = (ushort *) cfg_buf;
17238 chksum = 0;
17240 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17241 eep_addr < ADV_EEP_DVC_CFG_END;
17242 eep_addr++, wbuf++)
17244 wval = AdvReadEEPWord(iop_base, eep_addr);
17245 chksum += wval; /* Checksum is calculated from word values. */
17246 if (*charfields++) {
17247 *wbuf = le16_to_cpu(wval);
17248 } else {
17249 *wbuf = wval;
17252 /* Read checksum word. */
17253 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17254 wbuf++; charfields++;
17256 /* Read rest of EEPROM not covered by the checksum. */
17257 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17258 eep_addr < ADV_EEP_MAX_WORD_ADDR;
17259 eep_addr++, wbuf++)
17261 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17262 if (*charfields++) {
17263 *wbuf = le16_to_cpu(*wbuf);
17266 return chksum;
17270 * Read the EEPROM from specified location
17272 STATIC ushort __init
17273 AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
17275 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
17276 ASC_EEP_CMD_READ | eep_word_addr);
17277 AdvWaitEEPCmd(iop_base);
17278 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
17282 * Wait for EEPROM command to complete
17284 STATIC void __init
17285 AdvWaitEEPCmd(AdvPortAddr iop_base)
17287 int eep_delay_ms;
17289 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++)
17291 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE)
17293 break;
17295 DvcSleepMilliSecond(1);
17297 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == 0)
17299 ASC_ASSERT(0);
17301 return;
17305 * Write the EEPROM from 'cfg_buf'.
17307 void __init
17308 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
17310 ushort *wbuf;
17311 ushort addr, chksum;
17312 ushort *charfields;
17314 wbuf = (ushort *) cfg_buf;
17315 charfields = (ushort *) &ADVEEP_3550_Config_Field_IsChar;
17316 chksum = 0;
17318 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17319 AdvWaitEEPCmd(iop_base);
17322 * Write EEPROM from word 0 to word 20.
17324 for (addr = ADV_EEP_DVC_CFG_BEGIN;
17325 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17327 ushort word;
17329 if (*charfields++) {
17330 word = cpu_to_le16(*wbuf);
17331 } else {
17332 word = *wbuf;
17334 chksum += *wbuf; /* Checksum is calculated from word values. */
17335 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17336 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17337 AdvWaitEEPCmd(iop_base);
17338 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17342 * Write EEPROM checksum at word 21.
17344 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17345 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17346 AdvWaitEEPCmd(iop_base);
17347 wbuf++; charfields++;
17350 * Write EEPROM OEM name at words 22 to 29.
17352 for (addr = ADV_EEP_DVC_CTL_BEGIN;
17353 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17355 ushort word;
17357 if (*charfields++) {
17358 word = cpu_to_le16(*wbuf);
17359 } else {
17360 word = *wbuf;
17362 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17363 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17364 AdvWaitEEPCmd(iop_base);
17366 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17367 AdvWaitEEPCmd(iop_base);
17368 return;
17372 * Write the EEPROM from 'cfg_buf'.
17374 void __init
17375 AdvSet38C0800EEPConfig(AdvPortAddr iop_base,
17376 ADVEEP_38C0800_CONFIG *cfg_buf)
17378 ushort *wbuf;
17379 ushort *charfields;
17380 ushort addr, chksum;
17382 wbuf = (ushort *) cfg_buf;
17383 charfields = (ushort *) &ADVEEP_38C0800_Config_Field_IsChar;
17384 chksum = 0;
17386 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17387 AdvWaitEEPCmd(iop_base);
17390 * Write EEPROM from word 0 to word 20.
17392 for (addr = ADV_EEP_DVC_CFG_BEGIN;
17393 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17395 ushort word;
17397 if (*charfields++) {
17398 word = cpu_to_le16(*wbuf);
17399 } else {
17400 word = *wbuf;
17402 chksum += *wbuf; /* Checksum is calculated from word values. */
17403 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17404 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17405 AdvWaitEEPCmd(iop_base);
17406 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17410 * Write EEPROM checksum at word 21.
17412 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17413 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17414 AdvWaitEEPCmd(iop_base);
17415 wbuf++; charfields++;
17418 * Write EEPROM OEM name at words 22 to 29.
17420 for (addr = ADV_EEP_DVC_CTL_BEGIN;
17421 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17423 ushort word;
17425 if (*charfields++) {
17426 word = cpu_to_le16(*wbuf);
17427 } else {
17428 word = *wbuf;
17430 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17431 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17432 AdvWaitEEPCmd(iop_base);
17434 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17435 AdvWaitEEPCmd(iop_base);
17436 return;
17440 * Write the EEPROM from 'cfg_buf'.
17442 void __init
17443 AdvSet38C1600EEPConfig(AdvPortAddr iop_base,
17444 ADVEEP_38C1600_CONFIG *cfg_buf)
17446 ushort *wbuf;
17447 ushort *charfields;
17448 ushort addr, chksum;
17450 wbuf = (ushort *) cfg_buf;
17451 charfields = (ushort *) &ADVEEP_38C1600_Config_Field_IsChar;
17452 chksum = 0;
17454 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17455 AdvWaitEEPCmd(iop_base);
17458 * Write EEPROM from word 0 to word 20.
17460 for (addr = ADV_EEP_DVC_CFG_BEGIN;
17461 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17463 ushort word;
17465 if (*charfields++) {
17466 word = cpu_to_le16(*wbuf);
17467 } else {
17468 word = *wbuf;
17470 chksum += *wbuf; /* Checksum is calculated from word values. */
17471 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17472 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17473 AdvWaitEEPCmd(iop_base);
17474 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17478 * Write EEPROM checksum at word 21.
17480 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17481 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17482 AdvWaitEEPCmd(iop_base);
17483 wbuf++; charfields++;
17486 * Write EEPROM OEM name at words 22 to 29.
17488 for (addr = ADV_EEP_DVC_CTL_BEGIN;
17489 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17491 ushort word;
17493 if (*charfields++) {
17494 word = cpu_to_le16(*wbuf);
17495 } else {
17496 word = *wbuf;
17498 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17499 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17500 AdvWaitEEPCmd(iop_base);
17502 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17503 AdvWaitEEPCmd(iop_base);
17504 return;
17507 /* a_advlib.c */
17509 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
17511 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
17512 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
17513 * RISC to notify it a new command is ready to be executed.
17515 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
17516 * set to SCSI_MAX_RETRY.
17518 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
17519 * for DMA addresses or math operations are byte swapped to little-endian
17520 * order.
17522 * Return:
17523 * ADV_SUCCESS(1) - The request was successfully queued.
17524 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
17525 * request completes.
17526 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
17527 * host IC error.
17529 STATIC int
17530 AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc,
17531 ADV_SCSI_REQ_Q *scsiq)
17533 ulong last_int_level;
17534 AdvPortAddr iop_base;
17535 ADV_DCNT req_size;
17536 ADV_PADDR req_paddr;
17537 ADV_CARR_T *new_carrp;
17539 ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
17542 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
17544 if (scsiq->target_id > ADV_MAX_TID)
17546 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
17547 scsiq->done_status = QD_WITH_ERROR;
17548 return ADV_ERROR;
17551 iop_base = asc_dvc->iop_base;
17553 last_int_level = DvcEnterCritical();
17556 * Allocate a carrier ensuring at least one carrier always
17557 * remains on the freelist and initialize fields.
17559 if ((new_carrp = asc_dvc->carr_freelist) == NULL)
17561 DvcLeaveCritical(last_int_level);
17562 return ADV_BUSY;
17564 asc_dvc->carr_freelist = (ADV_CARR_T *)
17565 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
17566 asc_dvc->carr_pending_cnt++;
17569 * Set the carrier to be a stopper by setting 'next_vpa'
17570 * to the stopper value. The current stopper will be changed
17571 * below to point to the new stopper.
17573 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
17576 * Clear the ADV_SCSI_REQ_Q done flag.
17578 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
17580 req_size = sizeof(ADV_SCSI_REQ_Q);
17581 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *) scsiq,
17582 (ADV_SDCNT *) &req_size, ADV_IS_SCSIQ_FLAG);
17584 ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
17585 ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
17587 /* Wait for assertion before making little-endian */
17588 req_paddr = cpu_to_le32(req_paddr);
17590 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
17591 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
17592 scsiq->scsiq_rptr = req_paddr;
17594 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
17596 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
17597 * order during initialization.
17599 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
17602 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
17603 * the microcode. The newly allocated stopper will become the new
17604 * stopper.
17606 asc_dvc->icq_sp->areq_vpa = req_paddr;
17609 * Set the 'next_vpa' pointer for the old stopper to be the
17610 * physical address of the new stopper. The RISC can only
17611 * follow physical addresses.
17613 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
17616 * Set the host adapter stopper pointer to point to the new carrier.
17618 asc_dvc->icq_sp = new_carrp;
17620 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17621 asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
17624 * Tickle the RISC to tell it to read its Command Queue Head pointer.
17626 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
17627 if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
17630 * Clear the tickle value. In the ASC-3550 the RISC flag
17631 * command 'clr_tickle_a' does not work unless the host
17632 * value is cleared.
17634 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17636 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17639 * Notify the RISC a carrier is ready by writing the physical
17640 * address of the new carrier stopper to the COMMA register.
17642 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
17643 le32_to_cpu(new_carrp->carr_pa));
17646 DvcLeaveCritical(last_int_level);
17648 return ADV_SUCCESS;
17652 * Reset SCSI Bus and purge all outstanding requests.
17654 * Return Value:
17655 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
17656 * ADV_FALSE(0) - Microcode command failed.
17657 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
17658 * may be hung which requires driver recovery.
17660 STATIC int
17661 AdvResetSB(ADV_DVC_VAR *asc_dvc)
17663 int status;
17666 * Send the SCSI Bus Reset idle start idle command which asserts
17667 * the SCSI Bus Reset signal.
17669 status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_START, 0L);
17670 if (status != ADV_TRUE)
17672 return status;
17676 * Delay for the specified SCSI Bus Reset hold time.
17678 * The hold time delay is done on the host because the RISC has no
17679 * microsecond accurate timer.
17681 DvcDelayMicroSecond(asc_dvc, (ushort) ASC_SCSI_RESET_HOLD_TIME_US);
17684 * Send the SCSI Bus Reset end idle command which de-asserts
17685 * the SCSI Bus Reset signal and purges any pending requests.
17687 status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_END, 0L);
17688 if (status != ADV_TRUE)
17690 return status;
17693 DvcSleepMilliSecond((ADV_DCNT) asc_dvc->scsi_reset_wait * 1000);
17695 return status;
17699 * Reset chip and SCSI Bus.
17701 * Return Value:
17702 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
17703 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
17705 STATIC int
17706 AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
17708 int status;
17709 ushort wdtr_able, sdtr_able, tagqng_able;
17710 ushort ppr_able = 0;
17711 uchar tid, max_cmd[ADV_MAX_TID + 1];
17712 AdvPortAddr iop_base;
17713 ushort bios_sig;
17715 iop_base = asc_dvc->iop_base;
17718 * Save current per TID negotiated values.
17720 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17721 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17722 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17724 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17726 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17727 for (tid = 0; tid <= ADV_MAX_TID; tid++)
17729 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17730 max_cmd[tid]);
17734 * Force the AdvInitAsc3550/38C0800Driver() function to
17735 * perform a SCSI Bus Reset by clearing the BIOS signature word.
17736 * The initialization functions assumes a SCSI Bus Reset is not
17737 * needed if the BIOS signature word is present.
17739 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17740 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
17743 * Stop chip and reset it.
17745 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
17746 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
17747 DvcSleepMilliSecond(100);
17748 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG);
17751 * Reset Adv Library error code, if any, and try
17752 * re-initializing the chip.
17754 asc_dvc->err_code = 0;
17755 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17757 status = AdvInitAsc38C1600Driver(asc_dvc);
17759 else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
17761 status = AdvInitAsc38C0800Driver(asc_dvc);
17762 } else
17764 status = AdvInitAsc3550Driver(asc_dvc);
17767 /* Translate initialization return value to status value. */
17768 if (status == 0)
17770 status = ADV_TRUE;
17771 } else
17773 status = ADV_FALSE;
17777 * Restore the BIOS signature word.
17779 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17782 * Restore per TID negotiated values.
17784 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17785 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17786 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17788 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17790 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17791 for (tid = 0; tid <= ADV_MAX_TID; tid++)
17793 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17794 max_cmd[tid]);
17797 return status;
17801 * Adv Library Interrupt Service Routine
17803 * This function is called by a driver's interrupt service routine.
17804 * The function disables and re-enables interrupts.
17806 * When a microcode idle command is completed, the ADV_DVC_VAR
17807 * 'idle_cmd_done' field is set to ADV_TRUE.
17809 * Note: AdvISR() can be called when interrupts are disabled or even
17810 * when there is no hardware interrupt condition present. It will
17811 * always check for completed idle commands and microcode requests.
17812 * This is an important feature that shouldn't be changed because it
17813 * allows commands to be completed from polling mode loops.
17815 * Return:
17816 * ADV_TRUE(1) - interrupt was pending
17817 * ADV_FALSE(0) - no interrupt was pending
17819 STATIC int
17820 AdvISR(ADV_DVC_VAR *asc_dvc)
17822 AdvPortAddr iop_base;
17823 uchar int_stat;
17824 ushort target_bit;
17825 ADV_CARR_T *free_carrp;
17826 ADV_VADDR irq_next_vpa;
17827 int flags;
17828 ADV_SCSI_REQ_Q *scsiq;
17830 flags = DvcEnterCritical();
17832 iop_base = asc_dvc->iop_base;
17834 /* Reading the register clears the interrupt. */
17835 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
17837 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
17838 ADV_INTR_STATUS_INTRC)) == 0)
17840 DvcLeaveCritical(flags);
17841 return ADV_FALSE;
17845 * Notify the driver of an asynchronous microcode condition by
17846 * calling the ADV_DVC_VAR.async_callback function. The function
17847 * is passed the microcode ASC_MC_INTRB_CODE byte value.
17849 if (int_stat & ADV_INTR_STATUS_INTRB)
17851 uchar intrb_code;
17853 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
17855 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17856 asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
17858 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
17859 asc_dvc->carr_pending_cnt != 0)
17861 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
17862 if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
17864 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17869 if (asc_dvc->async_callback != 0)
17871 (*asc_dvc->async_callback)(asc_dvc, intrb_code);
17876 * Check if the IRQ stopper carrier contains a completed request.
17878 while (((irq_next_vpa =
17879 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0)
17882 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
17883 * The RISC will have set 'areq_vpa' to a virtual address.
17885 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
17886 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
17887 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
17888 * in AdvExeScsiQueue().
17890 scsiq = (ADV_SCSI_REQ_Q *)
17891 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
17894 * Request finished with good status and the queue was not
17895 * DMAed to host memory by the firmware. Set all status fields
17896 * to indicate good status.
17898 if ((irq_next_vpa & ASC_RQ_GOOD) != 0)
17900 scsiq->done_status = QD_NO_ERROR;
17901 scsiq->host_status = scsiq->scsi_status = 0;
17902 scsiq->data_cnt = 0L;
17906 * Advance the stopper pointer to the next carrier
17907 * ignoring the lower four bits. Free the previous
17908 * stopper carrier.
17910 free_carrp = asc_dvc->irq_sp;
17911 asc_dvc->irq_sp = (ADV_CARR_T *)
17912 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
17914 free_carrp->next_vpa =
17915 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
17916 asc_dvc->carr_freelist = free_carrp;
17917 asc_dvc->carr_pending_cnt--;
17919 ASC_ASSERT(scsiq != NULL);
17920 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
17923 * Clear request microcode control flag.
17925 scsiq->cntl = 0;
17928 * If the command that completed was a SCSI INQUIRY and
17929 * LUN 0 was sent the command, then process the INQUIRY
17930 * command information for the device.
17932 * Note: If data returned were either VPD or CmdDt data,
17933 * don't process the INQUIRY command information for
17934 * the device, otherwise may erroneously set *_able bits.
17936 if (scsiq->done_status == QD_NO_ERROR &&
17937 scsiq->cdb[0] == INQUIRY &&
17938 scsiq->target_lun == 0 &&
17939 (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
17940 == ADV_INQ_RTN_STD_INQUIRY_DATA)
17942 AdvInquiryHandling(asc_dvc, scsiq);
17946 * Notify the driver of the completed request by passing
17947 * the ADV_SCSI_REQ_Q pointer to its callback function.
17949 scsiq->a_flag |= ADV_SCSIQ_DONE;
17950 (*asc_dvc->isr_callback)(asc_dvc, scsiq);
17952 * Note: After the driver callback function is called, 'scsiq'
17953 * can no longer be referenced.
17955 * Fall through and continue processing other completed
17956 * requests...
17960 * Disable interrupts again in case the driver inadvertently
17961 * enabled interrupts in its callback function.
17963 * The DvcEnterCritical() return value is ignored, because
17964 * the 'flags' saved when AdvISR() was first entered will be
17965 * used to restore the interrupt flag on exit.
17967 (void) DvcEnterCritical();
17969 DvcLeaveCritical(flags);
17970 return ADV_TRUE;
17974 * Send an idle command to the chip and wait for completion.
17976 * Command completion is polled for once per microsecond.
17978 * The function can be called from anywhere including an interrupt handler.
17979 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
17980 * functions to prevent reentrancy.
17982 * Return Values:
17983 * ADV_TRUE - command completed successfully
17984 * ADV_FALSE - command failed
17985 * ADV_ERROR - command timed out
17987 STATIC int
17988 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
17989 ushort idle_cmd,
17990 ADV_DCNT idle_cmd_parameter)
17992 ulong last_int_level;
17993 int result;
17994 ADV_DCNT i, j;
17995 AdvPortAddr iop_base;
17997 last_int_level = DvcEnterCritical();
17999 iop_base = asc_dvc->iop_base;
18002 * Clear the idle command status which is set by the microcode
18003 * to a non-zero value to indicate when the command is completed.
18004 * The non-zero result is one of the IDLE_CMD_STATUS_* values
18005 * defined in a_advlib.h.
18007 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort) 0);
18010 * Write the idle command value after the idle command parameter
18011 * has been written to avoid a race condition. If the order is not
18012 * followed, the microcode may process the idle command before the
18013 * parameters have been written to LRAM.
18015 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
18016 cpu_to_le32(idle_cmd_parameter));
18017 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
18020 * Tickle the RISC to tell it to process the idle command.
18022 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
18023 if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
18026 * Clear the tickle value. In the ASC-3550 the RISC flag
18027 * command 'clr_tickle_b' does not work unless the host
18028 * value is cleared.
18030 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
18033 /* Wait for up to 100 millisecond for the idle command to timeout. */
18034 for (i = 0; i < SCSI_WAIT_100_MSEC; i++)
18036 /* Poll once each microsecond for command completion. */
18037 for (j = 0; j < SCSI_US_PER_MSEC; j++)
18039 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, result);
18040 if (result != 0)
18042 DvcLeaveCritical(last_int_level);
18043 return result;
18045 DvcDelayMicroSecond(asc_dvc, (ushort) 1);
18049 ASC_ASSERT(0); /* The idle command should never timeout. */
18050 DvcLeaveCritical(last_int_level);
18051 return ADV_ERROR;
18055 * Inquiry Information Byte 7 Handling
18057 * Handle SCSI Inquiry Command information for a device by setting
18058 * microcode operating variables that affect WDTR, SDTR, and Tag
18059 * Queuing.
18061 STATIC void
18062 AdvInquiryHandling(
18063 ADV_DVC_VAR *asc_dvc,
18064 ADV_SCSI_REQ_Q *scsiq)
18066 AdvPortAddr iop_base;
18067 uchar tid;
18068 ADV_SCSI_INQUIRY *inq;
18069 ushort tidmask;
18070 ushort cfg_word;
18073 * AdvInquiryHandling() requires up to INQUIRY information Byte 7
18074 * to be available.
18076 * If less than 8 bytes of INQUIRY information were requested or less
18077 * than 8 bytes were transferred, then return. cdb[4] is the request
18078 * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
18079 * microcode to the transfer residual count.
18082 if (scsiq->cdb[4] < 8 ||
18083 (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8)
18085 return;
18088 iop_base = asc_dvc->iop_base;
18089 tid = scsiq->target_id;
18091 inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr;
18094 * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
18096 if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2)
18098 return;
18099 } else
18102 * INQUIRY Byte 7 Handling
18104 * Use a device's INQUIRY byte 7 to determine whether it
18105 * supports WDTR, SDTR, and Tag Queuing. If the feature
18106 * is enabled in the EEPROM and the device supports the
18107 * feature, then enable it in the microcode.
18110 tidmask = ADV_TID_TO_TIDMASK(tid);
18113 * Wide Transfers
18115 * If the EEPROM enabled WDTR for the device and the device
18116 * supports wide bus (16 bit) transfers, then turn on the
18117 * device's 'wdtr_able' bit and write the new value to the
18118 * microcode.
18120 if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq))
18122 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
18123 if ((cfg_word & tidmask) == 0)
18125 cfg_word |= tidmask;
18126 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
18129 * Clear the microcode "SDTR negotiation" and "WDTR
18130 * negotiation" done indicators for the target to cause
18131 * it to negotiate with the new setting set above.
18132 * WDTR when accepted causes the target to enter
18133 * asynchronous mode, so SDTR must be negotiated.
18135 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18136 cfg_word &= ~tidmask;
18137 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18138 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
18139 cfg_word &= ~tidmask;
18140 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
18145 * Synchronous Transfers
18147 * If the EEPROM enabled SDTR for the device and the device
18148 * supports synchronous transfers, then turn on the device's
18149 * 'sdtr_able' bit. Write the new value to the microcode.
18151 if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq))
18153 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
18154 if ((cfg_word & tidmask) == 0)
18156 cfg_word |= tidmask;
18157 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
18160 * Clear the microcode "SDTR negotiation" done indicator
18161 * for the target to cause it to negotiate with the new
18162 * setting set above.
18164 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18165 cfg_word &= ~tidmask;
18166 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18170 * If the Inquiry data included enough space for the SPI-3
18171 * Clocking field, then check if DT mode is supported.
18173 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 &&
18174 (scsiq->cdb[4] >= 57 ||
18175 (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57))
18178 * PPR (Parallel Protocol Request) Capable
18180 * If the device supports DT mode, then it must be PPR capable.
18181 * The PPR message will be used in place of the SDTR and WDTR
18182 * messages to negotiate synchronous speed and offset, transfer
18183 * width, and protocol options.
18185 if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY)
18187 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, asc_dvc->ppr_able);
18188 asc_dvc->ppr_able |= tidmask;
18189 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, asc_dvc->ppr_able);
18194 * If the EEPROM enabled Tag Queuing for the device and the
18195 * device supports Tag Queueing, then turn on the device's
18196 * 'tagqng_enable' bit in the microcode and set the microcode
18197 * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
18198 * value.
18200 * Tag Queuing is disabled for the BIOS which runs in polled
18201 * mode and would see no benefit from Tag Queuing. Also by
18202 * disabling Tag Queuing in the BIOS devices with Tag Queuing
18203 * bugs will at least work with the BIOS.
18205 if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq))
18207 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
18208 cfg_word |= tidmask;
18209 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
18211 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
18212 asc_dvc->max_dvc_qng);
18216 MODULE_LICENSE("Dual BSD/GPL");
18218 /* PCI Devices supported by this driver */
18219 static struct pci_device_id advansys_pci_tbl[] __devinitdata = {
18220 { PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A,
18221 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18222 { PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940,
18223 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18224 { PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940U,
18225 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18226 { PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_ABP940UW,
18227 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18228 { PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C0800_REV1,
18229 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18230 { PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_38C1600_REV1,
18231 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
18234 MODULE_DEVICE_TABLE(pci, advansys_pci_tbl);