[PATCH] irq-flags: IA64: Use the new IRQF_ constants
[linux-2.6/linux-loongson.git] / drivers / scsi / advansys.c
blob537136457ea02b022b1c3c4633f7f264051c0063
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 SA_SHIRQ 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 SA_INTERRUPT
508 flag set to allow IRQ sharing with drivers that do not set
509 the SA_INTERRUPT 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_VENDORID 0x10CD
892 #define ASC_PCI_DEVICEID_1200A 0x1100
893 #define ASC_PCI_DEVICEID_1200B 0x1200
894 #define ASC_PCI_DEVICEID_ULTRA 0x1300
895 #define ASC_PCI_REVISION_3150 0x02
896 #define ASC_PCI_REVISION_3050 0x03
898 #define ASC_DVCLIB_CALL_DONE (1)
899 #define ASC_DVCLIB_CALL_FAILED (0)
900 #define ASC_DVCLIB_CALL_ERROR (-1)
903 * Enable CC_VERY_LONG_SG_LIST to support up to 64K element SG lists.
904 * The SRB structure will have to be changed and the ASC_SRB2SCSIQ()
905 * macro re-defined to be able to obtain a ASC_SCSI_Q pointer from the
906 * SRB structure.
908 #define CC_VERY_LONG_SG_LIST 0
909 #define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr)
911 #define PortAddr unsigned short /* port address size */
912 #define inp(port) inb(port)
913 #define outp(port, byte) outb((byte), (port))
915 #define inpw(port) inw(port)
916 #define outpw(port, word) outw((word), (port))
918 #define ASC_MAX_SG_QUEUE 7
919 #define ASC_MAX_SG_LIST 255
921 #define ASC_CS_TYPE unsigned short
923 #define ASC_IS_ISA (0x0001)
924 #define ASC_IS_ISAPNP (0x0081)
925 #define ASC_IS_EISA (0x0002)
926 #define ASC_IS_PCI (0x0004)
927 #define ASC_IS_PCI_ULTRA (0x0104)
928 #define ASC_IS_PCMCIA (0x0008)
929 #define ASC_IS_MCA (0x0020)
930 #define ASC_IS_VL (0x0040)
931 #define ASC_ISA_PNP_PORT_ADDR (0x279)
932 #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
933 #define ASC_IS_WIDESCSI_16 (0x0100)
934 #define ASC_IS_WIDESCSI_32 (0x0200)
935 #define ASC_IS_BIG_ENDIAN (0x8000)
936 #define ASC_CHIP_MIN_VER_VL (0x01)
937 #define ASC_CHIP_MAX_VER_VL (0x07)
938 #define ASC_CHIP_MIN_VER_PCI (0x09)
939 #define ASC_CHIP_MAX_VER_PCI (0x0F)
940 #define ASC_CHIP_VER_PCI_BIT (0x08)
941 #define ASC_CHIP_MIN_VER_ISA (0x11)
942 #define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
943 #define ASC_CHIP_MAX_VER_ISA (0x27)
944 #define ASC_CHIP_VER_ISA_BIT (0x30)
945 #define ASC_CHIP_VER_ISAPNP_BIT (0x20)
946 #define ASC_CHIP_VER_ASYN_BUG (0x21)
947 #define ASC_CHIP_VER_PCI 0x08
948 #define ASC_CHIP_VER_PCI_ULTRA_3150 (ASC_CHIP_VER_PCI | 0x02)
949 #define ASC_CHIP_VER_PCI_ULTRA_3050 (ASC_CHIP_VER_PCI | 0x03)
950 #define ASC_CHIP_MIN_VER_EISA (0x41)
951 #define ASC_CHIP_MAX_VER_EISA (0x47)
952 #define ASC_CHIP_VER_EISA_BIT (0x40)
953 #define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3)
954 #define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER 0x21
955 #define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER 0x0A
956 #define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL)
957 #define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
958 #define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL)
959 #define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
960 #define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL)
961 #define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
962 #define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL)
963 #define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL)
965 #define ASC_SCSI_ID_BITS 3
966 #define ASC_SCSI_TIX_TYPE uchar
967 #define ASC_ALL_DEVICE_BIT_SET 0xFF
968 #define ASC_SCSI_BIT_ID_TYPE uchar
969 #define ASC_MAX_TID 7
970 #define ASC_MAX_LUN 7
971 #define ASC_SCSI_WIDTH_BIT_SET 0xFF
972 #define ASC_MAX_SENSE_LEN 32
973 #define ASC_MIN_SENSE_LEN 14
974 #define ASC_MAX_CDB_LEN 12
975 #define ASC_SCSI_RESET_HOLD_TIME_US 60
977 #define ADV_INQ_CLOCKING_ST_ONLY 0x0
978 #define ADV_INQ_CLOCKING_DT_ONLY 0x1
979 #define ADV_INQ_CLOCKING_ST_AND_DT 0x3
982 * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data)
983 * and CmdDt (Command Support Data) field bit definitions.
985 #define ADV_INQ_RTN_VPD_AND_CMDDT 0x3
986 #define ADV_INQ_RTN_CMDDT_FOR_OP_CODE 0x2
987 #define ADV_INQ_RTN_VPD_FOR_PG_CODE 0x1
988 #define ADV_INQ_RTN_STD_INQUIRY_DATA 0x0
990 #define ASC_SCSIDIR_NOCHK 0x00
991 #define ASC_SCSIDIR_T2H 0x08
992 #define ASC_SCSIDIR_H2T 0x10
993 #define ASC_SCSIDIR_NODATA 0x18
994 #define SCSI_ASC_NOMEDIA 0x3A
995 #define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4))
996 #define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F))
997 #define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13))
998 #define PUT_CDB1(x) ((uchar)((uint)(x) >> 8))
999 #define MS_CMD_DONE 0x00
1000 #define MS_EXTEND 0x01
1001 #define MS_SDTR_LEN 0x03
1002 #define MS_SDTR_CODE 0x01
1003 #define MS_WDTR_LEN 0x02
1004 #define MS_WDTR_CODE 0x03
1005 #define MS_MDP_LEN 0x05
1006 #define MS_MDP_CODE 0x00
1009 * Inquiry data structure and bitfield macros
1011 * Only quantities of more than 1 bit are shifted, since the others are
1012 * just tested for true or false. C bitfields aren't portable between big
1013 * and little-endian platforms so they are not used.
1016 #define ASC_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f)
1017 #define ASC_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5)
1018 #define ASC_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f)
1019 #define ASC_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80)
1020 #define ASC_INQ_ANSI_VER(inq) ((inq)->ver & 0x07)
1021 #define ASC_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3)
1022 #define ASC_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6)
1023 #define ASC_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f)
1024 #define ASC_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40)
1025 #define ASC_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80)
1026 #define ASC_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01)
1027 #define ASC_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02)
1028 #define ASC_INQ_LINK_CMD(inq) ((inq)->flags & 0x08)
1029 #define ASC_INQ_SYNC(inq) ((inq)->flags & 0x10)
1030 #define ASC_INQ_WIDE16(inq) ((inq)->flags & 0x20)
1031 #define ASC_INQ_WIDE32(inq) ((inq)->flags & 0x40)
1032 #define ASC_INQ_REL_ADDR(inq) ((inq)->flags & 0x80)
1033 #define ASC_INQ_INFO_UNIT(inq) ((inq)->info & 0x01)
1034 #define ASC_INQ_QUICK_ARB(inq) ((inq)->info & 0x02)
1035 #define ASC_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2)
1037 typedef struct {
1038 uchar periph;
1039 uchar devtype;
1040 uchar ver;
1041 uchar byte3;
1042 uchar add_len;
1043 uchar res1;
1044 uchar res2;
1045 uchar flags;
1046 uchar vendor_id[8];
1047 uchar product_id[16];
1048 uchar product_rev_level[4];
1049 } ASC_SCSI_INQUIRY;
1051 #define ASC_SG_LIST_PER_Q 7
1052 #define QS_FREE 0x00
1053 #define QS_READY 0x01
1054 #define QS_DISC1 0x02
1055 #define QS_DISC2 0x04
1056 #define QS_BUSY 0x08
1057 #define QS_ABORTED 0x40
1058 #define QS_DONE 0x80
1059 #define QC_NO_CALLBACK 0x01
1060 #define QC_SG_SWAP_QUEUE 0x02
1061 #define QC_SG_HEAD 0x04
1062 #define QC_DATA_IN 0x08
1063 #define QC_DATA_OUT 0x10
1064 #define QC_URGENT 0x20
1065 #define QC_MSG_OUT 0x40
1066 #define QC_REQ_SENSE 0x80
1067 #define QCSG_SG_XFER_LIST 0x02
1068 #define QCSG_SG_XFER_MORE 0x04
1069 #define QCSG_SG_XFER_END 0x08
1070 #define QD_IN_PROGRESS 0x00
1071 #define QD_NO_ERROR 0x01
1072 #define QD_ABORTED_BY_HOST 0x02
1073 #define QD_WITH_ERROR 0x04
1074 #define QD_INVALID_REQUEST 0x80
1075 #define QD_INVALID_HOST_NUM 0x81
1076 #define QD_INVALID_DEVICE 0x82
1077 #define QD_ERR_INTERNAL 0xFF
1078 #define QHSTA_NO_ERROR 0x00
1079 #define QHSTA_M_SEL_TIMEOUT 0x11
1080 #define QHSTA_M_DATA_OVER_RUN 0x12
1081 #define QHSTA_M_DATA_UNDER_RUN 0x12
1082 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
1083 #define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
1084 #define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
1085 #define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
1086 #define QHSTA_D_HOST_ABORT_FAILED 0x23
1087 #define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
1088 #define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
1089 #define QHSTA_D_ASPI_NO_BUF_POOL 0x26
1090 #define QHSTA_M_WTM_TIMEOUT 0x41
1091 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
1092 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
1093 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
1094 #define QHSTA_M_TARGET_STATUS_BUSY 0x45
1095 #define QHSTA_M_BAD_TAG_CODE 0x46
1096 #define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
1097 #define QHSTA_M_HUNG_REQ_SCSI_BUS_RESET 0x48
1098 #define QHSTA_D_LRAM_CMP_ERROR 0x81
1099 #define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
1100 #define ASC_FLAG_SCSIQ_REQ 0x01
1101 #define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
1102 #define ASC_FLAG_BIOS_ASYNC_IO 0x04
1103 #define ASC_FLAG_SRB_LINEAR_ADDR 0x08
1104 #define ASC_FLAG_WIN16 0x10
1105 #define ASC_FLAG_WIN32 0x20
1106 #define ASC_FLAG_ISA_OVER_16MB 0x40
1107 #define ASC_FLAG_DOS_VM_CALLBACK 0x80
1108 #define ASC_TAG_FLAG_EXTRA_BYTES 0x10
1109 #define ASC_TAG_FLAG_DISABLE_DISCONNECT 0x04
1110 #define ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX 0x08
1111 #define ASC_TAG_FLAG_DISABLE_CHK_COND_INT_HOST 0x40
1112 #define ASC_SCSIQ_CPY_BEG 4
1113 #define ASC_SCSIQ_SGHD_CPY_BEG 2
1114 #define ASC_SCSIQ_B_FWD 0
1115 #define ASC_SCSIQ_B_BWD 1
1116 #define ASC_SCSIQ_B_STATUS 2
1117 #define ASC_SCSIQ_B_QNO 3
1118 #define ASC_SCSIQ_B_CNTL 4
1119 #define ASC_SCSIQ_B_SG_QUEUE_CNT 5
1120 #define ASC_SCSIQ_D_DATA_ADDR 8
1121 #define ASC_SCSIQ_D_DATA_CNT 12
1122 #define ASC_SCSIQ_B_SENSE_LEN 20
1123 #define ASC_SCSIQ_DONE_INFO_BEG 22
1124 #define ASC_SCSIQ_D_SRBPTR 22
1125 #define ASC_SCSIQ_B_TARGET_IX 26
1126 #define ASC_SCSIQ_B_CDB_LEN 28
1127 #define ASC_SCSIQ_B_TAG_CODE 29
1128 #define ASC_SCSIQ_W_VM_ID 30
1129 #define ASC_SCSIQ_DONE_STATUS 32
1130 #define ASC_SCSIQ_HOST_STATUS 33
1131 #define ASC_SCSIQ_SCSI_STATUS 34
1132 #define ASC_SCSIQ_CDB_BEG 36
1133 #define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
1134 #define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
1135 #define ASC_SCSIQ_B_FIRST_SG_WK_QP 48
1136 #define ASC_SCSIQ_B_SG_WK_QP 49
1137 #define ASC_SCSIQ_B_SG_WK_IX 50
1138 #define ASC_SCSIQ_W_ALT_DC1 52
1139 #define ASC_SCSIQ_B_LIST_CNT 6
1140 #define ASC_SCSIQ_B_CUR_LIST_CNT 7
1141 #define ASC_SGQ_B_SG_CNTL 4
1142 #define ASC_SGQ_B_SG_HEAD_QP 5
1143 #define ASC_SGQ_B_SG_LIST_CNT 6
1144 #define ASC_SGQ_B_SG_CUR_LIST_CNT 7
1145 #define ASC_SGQ_LIST_BEG 8
1146 #define ASC_DEF_SCSI1_QNG 4
1147 #define ASC_MAX_SCSI1_QNG 4
1148 #define ASC_DEF_SCSI2_QNG 16
1149 #define ASC_MAX_SCSI2_QNG 32
1150 #define ASC_TAG_CODE_MASK 0x23
1151 #define ASC_STOP_REQ_RISC_STOP 0x01
1152 #define ASC_STOP_ACK_RISC_STOP 0x03
1153 #define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
1154 #define ASC_STOP_CLEAN_UP_DISC_Q 0x20
1155 #define ASC_STOP_HOST_REQ_RISC_HALT 0x40
1156 #define ASC_TIDLUN_TO_IX(tid, lun) (ASC_SCSI_TIX_TYPE)((tid) + ((lun)<<ASC_SCSI_ID_BITS))
1157 #define ASC_TID_TO_TARGET_ID(tid) (ASC_SCSI_BIT_ID_TYPE)(0x01 << (tid))
1158 #define ASC_TIX_TO_TARGET_ID(tix) (0x01 << ((tix) & ASC_MAX_TID))
1159 #define ASC_TIX_TO_TID(tix) ((tix) & ASC_MAX_TID)
1160 #define ASC_TID_TO_TIX(tid) ((tid) & ASC_MAX_TID)
1161 #define ASC_TIX_TO_LUN(tix) (((tix) >> ASC_SCSI_ID_BITS) & ASC_MAX_LUN)
1162 #define ASC_QNO_TO_QADDR(q_no) ((ASC_QADR_BEG)+((int)(q_no) << 6))
1164 typedef struct asc_scsiq_1 {
1165 uchar status;
1166 uchar q_no;
1167 uchar cntl;
1168 uchar sg_queue_cnt;
1169 uchar target_id;
1170 uchar target_lun;
1171 ASC_PADDR data_addr;
1172 ASC_DCNT data_cnt;
1173 ASC_PADDR sense_addr;
1174 uchar sense_len;
1175 uchar extra_bytes;
1176 } ASC_SCSIQ_1;
1178 typedef struct asc_scsiq_2 {
1179 ASC_VADDR srb_ptr;
1180 uchar target_ix;
1181 uchar flag;
1182 uchar cdb_len;
1183 uchar tag_code;
1184 ushort vm_id;
1185 } ASC_SCSIQ_2;
1187 typedef struct asc_scsiq_3 {
1188 uchar done_stat;
1189 uchar host_stat;
1190 uchar scsi_stat;
1191 uchar scsi_msg;
1192 } ASC_SCSIQ_3;
1194 typedef struct asc_scsiq_4 {
1195 uchar cdb[ASC_MAX_CDB_LEN];
1196 uchar y_first_sg_list_qp;
1197 uchar y_working_sg_qp;
1198 uchar y_working_sg_ix;
1199 uchar y_res;
1200 ushort x_req_count;
1201 ushort x_reconnect_rtn;
1202 ASC_PADDR x_saved_data_addr;
1203 ASC_DCNT x_saved_data_cnt;
1204 } ASC_SCSIQ_4;
1206 typedef struct asc_q_done_info {
1207 ASC_SCSIQ_2 d2;
1208 ASC_SCSIQ_3 d3;
1209 uchar q_status;
1210 uchar q_no;
1211 uchar cntl;
1212 uchar sense_len;
1213 uchar extra_bytes;
1214 uchar res;
1215 ASC_DCNT remain_bytes;
1216 } ASC_QDONE_INFO;
1218 typedef struct asc_sg_list {
1219 ASC_PADDR addr;
1220 ASC_DCNT bytes;
1221 } ASC_SG_LIST;
1223 typedef struct asc_sg_head {
1224 ushort entry_cnt;
1225 ushort queue_cnt;
1226 ushort entry_to_copy;
1227 ushort res;
1228 ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
1229 } ASC_SG_HEAD;
1231 #define ASC_MIN_SG_LIST 2
1233 typedef struct asc_min_sg_head {
1234 ushort entry_cnt;
1235 ushort queue_cnt;
1236 ushort entry_to_copy;
1237 ushort res;
1238 ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
1239 } ASC_MIN_SG_HEAD;
1241 #define QCX_SORT (0x0001)
1242 #define QCX_COALEASE (0x0002)
1244 typedef struct asc_scsi_q {
1245 ASC_SCSIQ_1 q1;
1246 ASC_SCSIQ_2 q2;
1247 uchar *cdbptr;
1248 ASC_SG_HEAD *sg_head;
1249 ushort remain_sg_entry_cnt;
1250 ushort next_sg_index;
1251 } ASC_SCSI_Q;
1253 typedef struct asc_scsi_req_q {
1254 ASC_SCSIQ_1 r1;
1255 ASC_SCSIQ_2 r2;
1256 uchar *cdbptr;
1257 ASC_SG_HEAD *sg_head;
1258 uchar *sense_ptr;
1259 ASC_SCSIQ_3 r3;
1260 uchar cdb[ASC_MAX_CDB_LEN];
1261 uchar sense[ASC_MIN_SENSE_LEN];
1262 } ASC_SCSI_REQ_Q;
1264 typedef struct asc_scsi_bios_req_q {
1265 ASC_SCSIQ_1 r1;
1266 ASC_SCSIQ_2 r2;
1267 uchar *cdbptr;
1268 ASC_SG_HEAD *sg_head;
1269 uchar *sense_ptr;
1270 ASC_SCSIQ_3 r3;
1271 uchar cdb[ASC_MAX_CDB_LEN];
1272 uchar sense[ASC_MIN_SENSE_LEN];
1273 } ASC_SCSI_BIOS_REQ_Q;
1275 typedef struct asc_risc_q {
1276 uchar fwd;
1277 uchar bwd;
1278 ASC_SCSIQ_1 i1;
1279 ASC_SCSIQ_2 i2;
1280 ASC_SCSIQ_3 i3;
1281 ASC_SCSIQ_4 i4;
1282 } ASC_RISC_Q;
1284 typedef struct asc_sg_list_q {
1285 uchar seq_no;
1286 uchar q_no;
1287 uchar cntl;
1288 uchar sg_head_qp;
1289 uchar sg_list_cnt;
1290 uchar sg_cur_list_cnt;
1291 } ASC_SG_LIST_Q;
1293 typedef struct asc_risc_sg_list_q {
1294 uchar fwd;
1295 uchar bwd;
1296 ASC_SG_LIST_Q sg;
1297 ASC_SG_LIST sg_list[7];
1298 } ASC_RISC_SG_LIST_Q;
1300 #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL
1301 #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024
1302 #define ASCQ_ERR_NO_ERROR 0
1303 #define ASCQ_ERR_IO_NOT_FOUND 1
1304 #define ASCQ_ERR_LOCAL_MEM 2
1305 #define ASCQ_ERR_CHKSUM 3
1306 #define ASCQ_ERR_START_CHIP 4
1307 #define ASCQ_ERR_INT_TARGET_ID 5
1308 #define ASCQ_ERR_INT_LOCAL_MEM 6
1309 #define ASCQ_ERR_HALT_RISC 7
1310 #define ASCQ_ERR_GET_ASPI_ENTRY 8
1311 #define ASCQ_ERR_CLOSE_ASPI 9
1312 #define ASCQ_ERR_HOST_INQUIRY 0x0A
1313 #define ASCQ_ERR_SAVED_SRB_BAD 0x0B
1314 #define ASCQ_ERR_QCNTL_SG_LIST 0x0C
1315 #define ASCQ_ERR_Q_STATUS 0x0D
1316 #define ASCQ_ERR_WR_SCSIQ 0x0E
1317 #define ASCQ_ERR_PC_ADDR 0x0F
1318 #define ASCQ_ERR_SYN_OFFSET 0x10
1319 #define ASCQ_ERR_SYN_XFER_TIME 0x11
1320 #define ASCQ_ERR_LOCK_DMA 0x12
1321 #define ASCQ_ERR_UNLOCK_DMA 0x13
1322 #define ASCQ_ERR_VDS_CHK_INSTALL 0x14
1323 #define ASCQ_ERR_MICRO_CODE_HALT 0x15
1324 #define ASCQ_ERR_SET_LRAM_ADDR 0x16
1325 #define ASCQ_ERR_CUR_QNG 0x17
1326 #define ASCQ_ERR_SG_Q_LINKS 0x18
1327 #define ASCQ_ERR_SCSIQ_PTR 0x19
1328 #define ASCQ_ERR_ISR_RE_ENTRY 0x1A
1329 #define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
1330 #define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
1331 #define ASCQ_ERR_SG_LIST_ODD_ADDRESS 0x1D
1332 #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
1333 #define ASCQ_ERR_SCSIQ_NULL_PTR 0x1F
1334 #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR 0x20
1335 #define ASCQ_ERR_GET_NUM_OF_FREE_Q 0x21
1336 #define ASCQ_ERR_SEND_SCSI_Q 0x22
1337 #define ASCQ_ERR_HOST_REQ_RISC_HALT 0x23
1338 #define ASCQ_ERR_RESET_SDTR 0x24
1341 * Warning code values are set in ASC_DVC_VAR 'warn_code'.
1343 #define ASC_WARN_NO_ERROR 0x0000
1344 #define ASC_WARN_IO_PORT_ROTATE 0x0001
1345 #define ASC_WARN_EEPROM_CHKSUM 0x0002
1346 #define ASC_WARN_IRQ_MODIFIED 0x0004
1347 #define ASC_WARN_AUTO_CONFIG 0x0008
1348 #define ASC_WARN_CMD_QNG_CONFLICT 0x0010
1349 #define ASC_WARN_EEPROM_RECOVER 0x0020
1350 #define ASC_WARN_CFG_MSW_RECOVER 0x0040
1351 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080
1354 * Error code values are set in ASC_DVC_VAR 'err_code'.
1356 #define ASC_IERR_WRITE_EEPROM 0x0001
1357 #define ASC_IERR_MCODE_CHKSUM 0x0002
1358 #define ASC_IERR_SET_PC_ADDR 0x0004
1359 #define ASC_IERR_START_STOP_CHIP 0x0008
1360 #define ASC_IERR_IRQ_NO 0x0010
1361 #define ASC_IERR_SET_IRQ_NO 0x0020
1362 #define ASC_IERR_CHIP_VERSION 0x0040
1363 #define ASC_IERR_SET_SCSI_ID 0x0080
1364 #define ASC_IERR_GET_PHY_ADDR 0x0100
1365 #define ASC_IERR_BAD_SIGNATURE 0x0200
1366 #define ASC_IERR_NO_BUS_TYPE 0x0400
1367 #define ASC_IERR_SCAM 0x0800
1368 #define ASC_IERR_SET_SDTR 0x1000
1369 #define ASC_IERR_RW_LRAM 0x8000
1371 #define ASC_DEF_IRQ_NO 10
1372 #define ASC_MAX_IRQ_NO 15
1373 #define ASC_MIN_IRQ_NO 10
1374 #define ASC_MIN_REMAIN_Q (0x02)
1375 #define ASC_DEF_MAX_TOTAL_QNG (0xF0)
1376 #define ASC_MIN_TAG_Q_PER_DVC (0x04)
1377 #define ASC_DEF_TAG_Q_PER_DVC (0x04)
1378 #define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q
1379 #define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q))
1380 #define ASC_MAX_TOTAL_QNG 240
1381 #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16
1382 #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8
1383 #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
1384 #define ASC_MAX_INRAM_TAG_QNG 16
1385 #define ASC_IOADR_TABLE_MAX_IX 11
1386 #define ASC_IOADR_GAP 0x10
1387 #define ASC_SEARCH_IOP_GAP 0x10
1388 #define ASC_MIN_IOP_ADDR (PortAddr)0x0100
1389 #define ASC_MAX_IOP_ADDR (PortAddr)0x3F0
1390 #define ASC_IOADR_1 (PortAddr)0x0110
1391 #define ASC_IOADR_2 (PortAddr)0x0130
1392 #define ASC_IOADR_3 (PortAddr)0x0150
1393 #define ASC_IOADR_4 (PortAddr)0x0190
1394 #define ASC_IOADR_5 (PortAddr)0x0210
1395 #define ASC_IOADR_6 (PortAddr)0x0230
1396 #define ASC_IOADR_7 (PortAddr)0x0250
1397 #define ASC_IOADR_8 (PortAddr)0x0330
1398 #define ASC_IOADR_DEF ASC_IOADR_8
1399 #define ASC_LIB_SCSIQ_WK_SP 256
1400 #define ASC_MAX_SYN_XFER_NO 16
1401 #define ASC_SYN_MAX_OFFSET 0x0F
1402 #define ASC_DEF_SDTR_OFFSET 0x0F
1403 #define ASC_DEF_SDTR_INDEX 0x00
1404 #define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02
1405 #define SYN_XFER_NS_0 25
1406 #define SYN_XFER_NS_1 30
1407 #define SYN_XFER_NS_2 35
1408 #define SYN_XFER_NS_3 40
1409 #define SYN_XFER_NS_4 50
1410 #define SYN_XFER_NS_5 60
1411 #define SYN_XFER_NS_6 70
1412 #define SYN_XFER_NS_7 85
1413 #define SYN_ULTRA_XFER_NS_0 12
1414 #define SYN_ULTRA_XFER_NS_1 19
1415 #define SYN_ULTRA_XFER_NS_2 25
1416 #define SYN_ULTRA_XFER_NS_3 32
1417 #define SYN_ULTRA_XFER_NS_4 38
1418 #define SYN_ULTRA_XFER_NS_5 44
1419 #define SYN_ULTRA_XFER_NS_6 50
1420 #define SYN_ULTRA_XFER_NS_7 57
1421 #define SYN_ULTRA_XFER_NS_8 63
1422 #define SYN_ULTRA_XFER_NS_9 69
1423 #define SYN_ULTRA_XFER_NS_10 75
1424 #define SYN_ULTRA_XFER_NS_11 82
1425 #define SYN_ULTRA_XFER_NS_12 88
1426 #define SYN_ULTRA_XFER_NS_13 94
1427 #define SYN_ULTRA_XFER_NS_14 100
1428 #define SYN_ULTRA_XFER_NS_15 107
1430 typedef struct ext_msg {
1431 uchar msg_type;
1432 uchar msg_len;
1433 uchar msg_req;
1434 union {
1435 struct {
1436 uchar sdtr_xfer_period;
1437 uchar sdtr_req_ack_offset;
1438 } sdtr;
1439 struct {
1440 uchar wdtr_width;
1441 } wdtr;
1442 struct {
1443 uchar mdp_b3;
1444 uchar mdp_b2;
1445 uchar mdp_b1;
1446 uchar mdp_b0;
1447 } mdp;
1448 } u_ext_msg;
1449 uchar res;
1450 } EXT_MSG;
1452 #define xfer_period u_ext_msg.sdtr.sdtr_xfer_period
1453 #define req_ack_offset u_ext_msg.sdtr.sdtr_req_ack_offset
1454 #define wdtr_width u_ext_msg.wdtr.wdtr_width
1455 #define mdp_b3 u_ext_msg.mdp_b3
1456 #define mdp_b2 u_ext_msg.mdp_b2
1457 #define mdp_b1 u_ext_msg.mdp_b1
1458 #define mdp_b0 u_ext_msg.mdp_b0
1460 typedef struct asc_dvc_cfg {
1461 ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
1462 ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
1463 ASC_SCSI_BIT_ID_TYPE disc_enable;
1464 ASC_SCSI_BIT_ID_TYPE sdtr_enable;
1465 uchar chip_scsi_id;
1466 uchar isa_dma_speed;
1467 uchar isa_dma_channel;
1468 uchar chip_version;
1469 ushort lib_serial_no;
1470 ushort lib_version;
1471 ushort mcode_date;
1472 ushort mcode_version;
1473 uchar max_tag_qng[ASC_MAX_TID + 1];
1474 uchar *overrun_buf;
1475 uchar sdtr_period_offset[ASC_MAX_TID + 1];
1476 ushort pci_slot_info;
1477 uchar adapter_info[6];
1478 struct device *dev;
1479 } ASC_DVC_CFG;
1481 #define ASC_DEF_DVC_CNTL 0xFFFF
1482 #define ASC_DEF_CHIP_SCSI_ID 7
1483 #define ASC_DEF_ISA_DMA_SPEED 4
1484 #define ASC_INIT_STATE_NULL 0x0000
1485 #define ASC_INIT_STATE_BEG_GET_CFG 0x0001
1486 #define ASC_INIT_STATE_END_GET_CFG 0x0002
1487 #define ASC_INIT_STATE_BEG_SET_CFG 0x0004
1488 #define ASC_INIT_STATE_END_SET_CFG 0x0008
1489 #define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
1490 #define ASC_INIT_STATE_END_LOAD_MC 0x0020
1491 #define ASC_INIT_STATE_BEG_INQUIRY 0x0040
1492 #define ASC_INIT_STATE_END_INQUIRY 0x0080
1493 #define ASC_INIT_RESET_SCSI_DONE 0x0100
1494 #define ASC_INIT_STATE_WITHOUT_EEP 0x8000
1495 #define ASC_PCI_DEVICE_ID_REV_A 0x1100
1496 #define ASC_PCI_DEVICE_ID_REV_B 0x1200
1497 #define ASC_BUG_FIX_IF_NOT_DWB 0x0001
1498 #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002
1499 #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
1500 #define ASC_MIN_TAGGED_CMD 7
1501 #define ASC_MAX_SCSI_RESET_WAIT 30
1503 struct asc_dvc_var; /* Forward Declaration. */
1505 typedef void (* ASC_ISR_CALLBACK)(struct asc_dvc_var *, ASC_QDONE_INFO *);
1506 typedef int (* ASC_EXE_CALLBACK)(struct asc_dvc_var *, ASC_SCSI_Q *);
1508 typedef struct asc_dvc_var {
1509 PortAddr iop_base;
1510 ushort err_code;
1511 ushort dvc_cntl;
1512 ushort bug_fix_cntl;
1513 ushort bus_type;
1514 ASC_ISR_CALLBACK isr_callback;
1515 ASC_EXE_CALLBACK exe_callback;
1516 ASC_SCSI_BIT_ID_TYPE init_sdtr;
1517 ASC_SCSI_BIT_ID_TYPE sdtr_done;
1518 ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
1519 ASC_SCSI_BIT_ID_TYPE unit_not_ready;
1520 ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
1521 ASC_SCSI_BIT_ID_TYPE start_motor;
1522 uchar scsi_reset_wait;
1523 uchar chip_no;
1524 char is_in_int;
1525 uchar max_total_qng;
1526 uchar cur_total_qng;
1527 uchar in_critical_cnt;
1528 uchar irq_no;
1529 uchar last_q_shortage;
1530 ushort init_state;
1531 uchar cur_dvc_qng[ASC_MAX_TID + 1];
1532 uchar max_dvc_qng[ASC_MAX_TID + 1];
1533 ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1];
1534 ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1];
1535 uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO];
1536 ASC_DVC_CFG *cfg;
1537 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always;
1538 char redo_scam;
1539 ushort res2;
1540 uchar dos_int13_table[ASC_MAX_TID + 1];
1541 ASC_DCNT max_dma_count;
1542 ASC_SCSI_BIT_ID_TYPE no_scam;
1543 ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
1544 uchar max_sdtr_index;
1545 uchar host_init_sdtr_index;
1546 struct asc_board *drv_ptr;
1547 ASC_DCNT uc_break;
1548 } ASC_DVC_VAR;
1550 typedef struct asc_dvc_inq_info {
1551 uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1552 } ASC_DVC_INQ_INFO;
1554 typedef struct asc_cap_info {
1555 ASC_DCNT lba;
1556 ASC_DCNT blk_size;
1557 } ASC_CAP_INFO;
1559 typedef struct asc_cap_info_array {
1560 ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
1561 } ASC_CAP_INFO_ARRAY;
1563 #define ASC_MCNTL_NO_SEL_TIMEOUT (ushort)0x0001
1564 #define ASC_MCNTL_NULL_TARGET (ushort)0x0002
1565 #define ASC_CNTL_INITIATOR (ushort)0x0001
1566 #define ASC_CNTL_BIOS_GT_1GB (ushort)0x0002
1567 #define ASC_CNTL_BIOS_GT_2_DISK (ushort)0x0004
1568 #define ASC_CNTL_BIOS_REMOVABLE (ushort)0x0008
1569 #define ASC_CNTL_NO_SCAM (ushort)0x0010
1570 #define ASC_CNTL_INT_MULTI_Q (ushort)0x0080
1571 #define ASC_CNTL_NO_LUN_SUPPORT (ushort)0x0040
1572 #define ASC_CNTL_NO_VERIFY_COPY (ushort)0x0100
1573 #define ASC_CNTL_RESET_SCSI (ushort)0x0200
1574 #define ASC_CNTL_INIT_INQUIRY (ushort)0x0400
1575 #define ASC_CNTL_INIT_VERBOSE (ushort)0x0800
1576 #define ASC_CNTL_SCSI_PARITY (ushort)0x1000
1577 #define ASC_CNTL_BURST_MODE (ushort)0x2000
1578 #define ASC_CNTL_SDTR_ENABLE_ULTRA (ushort)0x4000
1579 #define ASC_EEP_DVC_CFG_BEG_VL 2
1580 #define ASC_EEP_MAX_DVC_ADDR_VL 15
1581 #define ASC_EEP_DVC_CFG_BEG 32
1582 #define ASC_EEP_MAX_DVC_ADDR 45
1583 #define ASC_EEP_DEFINED_WORDS 10
1584 #define ASC_EEP_MAX_ADDR 63
1585 #define ASC_EEP_RES_WORDS 0
1586 #define ASC_EEP_MAX_RETRY 20
1587 #define ASC_MAX_INIT_BUSY_RETRY 8
1588 #define ASC_EEP_ISA_PNP_WSIZE 16
1591 * These macros keep the chip SCSI id and ISA DMA speed
1592 * bitfields in board order. C bitfields aren't portable
1593 * between big and little-endian platforms so they are
1594 * not used.
1597 #define ASC_EEP_GET_CHIP_ID(cfg) ((cfg)->id_speed & 0x0f)
1598 #define ASC_EEP_GET_DMA_SPD(cfg) (((cfg)->id_speed & 0xf0) >> 4)
1599 #define ASC_EEP_SET_CHIP_ID(cfg, sid) \
1600 ((cfg)->id_speed = ((cfg)->id_speed & 0xf0) | ((sid) & ASC_MAX_TID))
1601 #define ASC_EEP_SET_DMA_SPD(cfg, spd) \
1602 ((cfg)->id_speed = ((cfg)->id_speed & 0x0f) | ((spd) & 0x0f) << 4)
1604 typedef struct asceep_config {
1605 ushort cfg_lsw;
1606 ushort cfg_msw;
1607 uchar init_sdtr;
1608 uchar disc_enable;
1609 uchar use_cmd_qng;
1610 uchar start_motor;
1611 uchar max_total_qng;
1612 uchar max_tag_qng;
1613 uchar bios_scan;
1614 uchar power_up_wait;
1615 uchar no_scam;
1616 uchar id_speed; /* low order 4 bits is chip scsi id */
1617 /* high order 4 bits is isa dma speed */
1618 uchar dos_int13_table[ASC_MAX_TID + 1];
1619 uchar adapter_info[6];
1620 ushort cntl;
1621 ushort chksum;
1622 } ASCEEP_CONFIG;
1624 #define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800
1625 #define ASC_PCI_CFG_LSW_BURST_MODE 0x0080
1626 #define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020
1628 #define ASC_EEP_CMD_READ 0x80
1629 #define ASC_EEP_CMD_WRITE 0x40
1630 #define ASC_EEP_CMD_WRITE_ABLE 0x30
1631 #define ASC_EEP_CMD_WRITE_DISABLE 0x00
1632 #define ASC_OVERRUN_BSIZE 0x00000048UL
1633 #define ASC_CTRL_BREAK_ONCE 0x0001
1634 #define ASC_CTRL_BREAK_STAY_IDLE 0x0002
1635 #define ASCV_MSGOUT_BEG 0x0000
1636 #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
1637 #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
1638 #define ASCV_BREAK_SAVED_CODE (ushort)0x0006
1639 #define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
1640 #define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
1641 #define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
1642 #define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
1643 #define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
1644 #define ASCV_MAX_DVC_QNG_BEG (ushort)0x0020
1645 #define ASCV_BREAK_ADDR (ushort)0x0028
1646 #define ASCV_BREAK_NOTIFY_COUNT (ushort)0x002A
1647 #define ASCV_BREAK_CONTROL (ushort)0x002C
1648 #define ASCV_BREAK_HIT_COUNT (ushort)0x002E
1650 #define ASCV_ASCDVC_ERR_CODE_W (ushort)0x0030
1651 #define ASCV_MCODE_CHKSUM_W (ushort)0x0032
1652 #define ASCV_MCODE_SIZE_W (ushort)0x0034
1653 #define ASCV_STOP_CODE_B (ushort)0x0036
1654 #define ASCV_DVC_ERR_CODE_B (ushort)0x0037
1655 #define ASCV_OVERRUN_PADDR_D (ushort)0x0038
1656 #define ASCV_OVERRUN_BSIZE_D (ushort)0x003C
1657 #define ASCV_HALTCODE_W (ushort)0x0040
1658 #define ASCV_CHKSUM_W (ushort)0x0042
1659 #define ASCV_MC_DATE_W (ushort)0x0044
1660 #define ASCV_MC_VER_W (ushort)0x0046
1661 #define ASCV_NEXTRDY_B (ushort)0x0048
1662 #define ASCV_DONENEXT_B (ushort)0x0049
1663 #define ASCV_USE_TAGGED_QNG_B (ushort)0x004A
1664 #define ASCV_SCSIBUSY_B (ushort)0x004B
1665 #define ASCV_Q_DONE_IN_PROGRESS_B (ushort)0x004C
1666 #define ASCV_CURCDB_B (ushort)0x004D
1667 #define ASCV_RCLUN_B (ushort)0x004E
1668 #define ASCV_BUSY_QHEAD_B (ushort)0x004F
1669 #define ASCV_DISC1_QHEAD_B (ushort)0x0050
1670 #define ASCV_DISC_ENABLE_B (ushort)0x0052
1671 #define ASCV_CAN_TAGGED_QNG_B (ushort)0x0053
1672 #define ASCV_HOSTSCSI_ID_B (ushort)0x0055
1673 #define ASCV_MCODE_CNTL_B (ushort)0x0056
1674 #define ASCV_NULL_TARGET_B (ushort)0x0057
1675 #define ASCV_FREE_Q_HEAD_W (ushort)0x0058
1676 #define ASCV_DONE_Q_TAIL_W (ushort)0x005A
1677 #define ASCV_FREE_Q_HEAD_B (ushort)(ASCV_FREE_Q_HEAD_W+1)
1678 #define ASCV_DONE_Q_TAIL_B (ushort)(ASCV_DONE_Q_TAIL_W+1)
1679 #define ASCV_HOST_FLAG_B (ushort)0x005D
1680 #define ASCV_TOTAL_READY_Q_B (ushort)0x0064
1681 #define ASCV_VER_SERIAL_B (ushort)0x0065
1682 #define ASCV_HALTCODE_SAVED_W (ushort)0x0066
1683 #define ASCV_WTM_FLAG_B (ushort)0x0068
1684 #define ASCV_RISC_FLAG_B (ushort)0x006A
1685 #define ASCV_REQ_SG_LIST_QP (ushort)0x006B
1686 #define ASC_HOST_FLAG_IN_ISR 0x01
1687 #define ASC_HOST_FLAG_ACK_INT 0x02
1688 #define ASC_RISC_FLAG_GEN_INT 0x01
1689 #define ASC_RISC_FLAG_REQ_SG_LIST 0x02
1690 #define IOP_CTRL (0x0F)
1691 #define IOP_STATUS (0x0E)
1692 #define IOP_INT_ACK IOP_STATUS
1693 #define IOP_REG_IFC (0x0D)
1694 #define IOP_SYN_OFFSET (0x0B)
1695 #define IOP_EXTRA_CONTROL (0x0D)
1696 #define IOP_REG_PC (0x0C)
1697 #define IOP_RAM_ADDR (0x0A)
1698 #define IOP_RAM_DATA (0x08)
1699 #define IOP_EEP_DATA (0x06)
1700 #define IOP_EEP_CMD (0x07)
1701 #define IOP_VERSION (0x03)
1702 #define IOP_CONFIG_HIGH (0x04)
1703 #define IOP_CONFIG_LOW (0x02)
1704 #define IOP_SIG_BYTE (0x01)
1705 #define IOP_SIG_WORD (0x00)
1706 #define IOP_REG_DC1 (0x0E)
1707 #define IOP_REG_DC0 (0x0C)
1708 #define IOP_REG_SB (0x0B)
1709 #define IOP_REG_DA1 (0x0A)
1710 #define IOP_REG_DA0 (0x08)
1711 #define IOP_REG_SC (0x09)
1712 #define IOP_DMA_SPEED (0x07)
1713 #define IOP_REG_FLAG (0x07)
1714 #define IOP_FIFO_H (0x06)
1715 #define IOP_FIFO_L (0x04)
1716 #define IOP_REG_ID (0x05)
1717 #define IOP_REG_QP (0x03)
1718 #define IOP_REG_IH (0x02)
1719 #define IOP_REG_IX (0x01)
1720 #define IOP_REG_AX (0x00)
1721 #define IFC_REG_LOCK (0x00)
1722 #define IFC_REG_UNLOCK (0x09)
1723 #define IFC_WR_EN_FILTER (0x10)
1724 #define IFC_RD_NO_EEPROM (0x10)
1725 #define IFC_SLEW_RATE (0x20)
1726 #define IFC_ACT_NEG (0x40)
1727 #define IFC_INP_FILTER (0x80)
1728 #define IFC_INIT_DEFAULT (IFC_ACT_NEG | IFC_REG_UNLOCK)
1729 #define SC_SEL (uchar)(0x80)
1730 #define SC_BSY (uchar)(0x40)
1731 #define SC_ACK (uchar)(0x20)
1732 #define SC_REQ (uchar)(0x10)
1733 #define SC_ATN (uchar)(0x08)
1734 #define SC_IO (uchar)(0x04)
1735 #define SC_CD (uchar)(0x02)
1736 #define SC_MSG (uchar)(0x01)
1737 #define SEC_SCSI_CTL (uchar)(0x80)
1738 #define SEC_ACTIVE_NEGATE (uchar)(0x40)
1739 #define SEC_SLEW_RATE (uchar)(0x20)
1740 #define SEC_ENABLE_FILTER (uchar)(0x10)
1741 #define ASC_HALT_EXTMSG_IN (ushort)0x8000
1742 #define ASC_HALT_CHK_CONDITION (ushort)0x8100
1743 #define ASC_HALT_SS_QUEUE_FULL (ushort)0x8200
1744 #define ASC_HALT_DISABLE_ASYN_USE_SYN_FIX (ushort)0x8300
1745 #define ASC_HALT_ENABLE_ASYN_USE_SYN_FIX (ushort)0x8400
1746 #define ASC_HALT_SDTR_REJECTED (ushort)0x4000
1747 #define ASC_HALT_HOST_COPY_SG_LIST_TO_RISC ( ushort )0x2000
1748 #define ASC_MAX_QNO 0xF8
1749 #define ASC_DATA_SEC_BEG (ushort)0x0080
1750 #define ASC_DATA_SEC_END (ushort)0x0080
1751 #define ASC_CODE_SEC_BEG (ushort)0x0080
1752 #define ASC_CODE_SEC_END (ushort)0x0080
1753 #define ASC_QADR_BEG (0x4000)
1754 #define ASC_QADR_USED (ushort)(ASC_MAX_QNO * 64)
1755 #define ASC_QADR_END (ushort)0x7FFF
1756 #define ASC_QLAST_ADR (ushort)0x7FC0
1757 #define ASC_QBLK_SIZE 0x40
1758 #define ASC_BIOS_DATA_QBEG 0xF8
1759 #define ASC_MIN_ACTIVE_QNO 0x01
1760 #define ASC_QLINK_END 0xFF
1761 #define ASC_EEPROM_WORDS 0x10
1762 #define ASC_MAX_MGS_LEN 0x10
1763 #define ASC_BIOS_ADDR_DEF 0xDC00
1764 #define ASC_BIOS_SIZE 0x3800
1765 #define ASC_BIOS_RAM_OFF 0x3800
1766 #define ASC_BIOS_RAM_SIZE 0x800
1767 #define ASC_BIOS_MIN_ADDR 0xC000
1768 #define ASC_BIOS_MAX_ADDR 0xEC00
1769 #define ASC_BIOS_BANK_SIZE 0x0400
1770 #define ASC_MCODE_START_ADDR 0x0080
1771 #define ASC_CFG0_HOST_INT_ON 0x0020
1772 #define ASC_CFG0_BIOS_ON 0x0040
1773 #define ASC_CFG0_VERA_BURST_ON 0x0080
1774 #define ASC_CFG0_SCSI_PARITY_ON 0x0800
1775 #define ASC_CFG1_SCSI_TARGET_ON 0x0080
1776 #define ASC_CFG1_LRAM_8BITS_ON 0x0800
1777 #define ASC_CFG_MSW_CLR_MASK 0x3080
1778 #define CSW_TEST1 (ASC_CS_TYPE)0x8000
1779 #define CSW_AUTO_CONFIG (ASC_CS_TYPE)0x4000
1780 #define CSW_RESERVED1 (ASC_CS_TYPE)0x2000
1781 #define CSW_IRQ_WRITTEN (ASC_CS_TYPE)0x1000
1782 #define CSW_33MHZ_SELECTED (ASC_CS_TYPE)0x0800
1783 #define CSW_TEST2 (ASC_CS_TYPE)0x0400
1784 #define CSW_TEST3 (ASC_CS_TYPE)0x0200
1785 #define CSW_RESERVED2 (ASC_CS_TYPE)0x0100
1786 #define CSW_DMA_DONE (ASC_CS_TYPE)0x0080
1787 #define CSW_FIFO_RDY (ASC_CS_TYPE)0x0040
1788 #define CSW_EEP_READ_DONE (ASC_CS_TYPE)0x0020
1789 #define CSW_HALTED (ASC_CS_TYPE)0x0010
1790 #define CSW_SCSI_RESET_ACTIVE (ASC_CS_TYPE)0x0008
1791 #define CSW_PARITY_ERR (ASC_CS_TYPE)0x0004
1792 #define CSW_SCSI_RESET_LATCH (ASC_CS_TYPE)0x0002
1793 #define CSW_INT_PENDING (ASC_CS_TYPE)0x0001
1794 #define CIW_CLR_SCSI_RESET_INT (ASC_CS_TYPE)0x1000
1795 #define CIW_INT_ACK (ASC_CS_TYPE)0x0100
1796 #define CIW_TEST1 (ASC_CS_TYPE)0x0200
1797 #define CIW_TEST2 (ASC_CS_TYPE)0x0400
1798 #define CIW_SEL_33MHZ (ASC_CS_TYPE)0x0800
1799 #define CIW_IRQ_ACT (ASC_CS_TYPE)0x1000
1800 #define CC_CHIP_RESET (uchar)0x80
1801 #define CC_SCSI_RESET (uchar)0x40
1802 #define CC_HALT (uchar)0x20
1803 #define CC_SINGLE_STEP (uchar)0x10
1804 #define CC_DMA_ABLE (uchar)0x08
1805 #define CC_TEST (uchar)0x04
1806 #define CC_BANK_ONE (uchar)0x02
1807 #define CC_DIAG (uchar)0x01
1808 #define ASC_1000_ID0W 0x04C1
1809 #define ASC_1000_ID0W_FIX 0x00C1
1810 #define ASC_1000_ID1B 0x25
1811 #define ASC_EISA_BIG_IOP_GAP (0x1C30-0x0C50)
1812 #define ASC_EISA_SMALL_IOP_GAP (0x0020)
1813 #define ASC_EISA_MIN_IOP_ADDR (0x0C30)
1814 #define ASC_EISA_MAX_IOP_ADDR (0xFC50)
1815 #define ASC_EISA_REV_IOP_MASK (0x0C83)
1816 #define ASC_EISA_PID_IOP_MASK (0x0C80)
1817 #define ASC_EISA_CFG_IOP_MASK (0x0C86)
1818 #define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000)
1819 #define ASC_EISA_ID_740 0x01745004UL
1820 #define ASC_EISA_ID_750 0x01755004UL
1821 #define INS_HALTINT (ushort)0x6281
1822 #define INS_HALT (ushort)0x6280
1823 #define INS_SINT (ushort)0x6200
1824 #define INS_RFLAG_WTM (ushort)0x7380
1825 #define ASC_MC_SAVE_CODE_WSIZE 0x500
1826 #define ASC_MC_SAVE_DATA_WSIZE 0x40
1828 typedef struct asc_mc_saved {
1829 ushort data[ASC_MC_SAVE_DATA_WSIZE];
1830 ushort code[ASC_MC_SAVE_CODE_WSIZE];
1831 } ASC_MC_SAVED;
1833 #define AscGetQDoneInProgress(port) AscReadLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B)
1834 #define AscPutQDoneInProgress(port, val) AscWriteLramByte((port), ASCV_Q_DONE_IN_PROGRESS_B, val)
1835 #define AscGetVarFreeQHead(port) AscReadLramWord((port), ASCV_FREE_Q_HEAD_W)
1836 #define AscGetVarDoneQTail(port) AscReadLramWord((port), ASCV_DONE_Q_TAIL_W)
1837 #define AscPutVarFreeQHead(port, val) AscWriteLramWord((port), ASCV_FREE_Q_HEAD_W, val)
1838 #define AscPutVarDoneQTail(port, val) AscWriteLramWord((port), ASCV_DONE_Q_TAIL_W, val)
1839 #define AscGetRiscVarFreeQHead(port) AscReadLramByte((port), ASCV_NEXTRDY_B)
1840 #define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B)
1841 #define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val)
1842 #define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val)
1843 #define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data));
1844 #define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id));
1845 #define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data);
1846 #define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id));
1847 #define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ])
1848 #define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE)
1849 #define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD)
1850 #define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION)
1851 #define AscGetChipCfgLsw(port) (ushort)inpw((port)+IOP_CONFIG_LOW)
1852 #define AscGetChipCfgMsw(port) (ushort)inpw((port)+IOP_CONFIG_HIGH)
1853 #define AscSetChipCfgLsw(port, data) outpw((port)+IOP_CONFIG_LOW, data)
1854 #define AscSetChipCfgMsw(port, data) outpw((port)+IOP_CONFIG_HIGH, data)
1855 #define AscGetChipEEPCmd(port) (uchar)inp((port)+IOP_EEP_CMD)
1856 #define AscSetChipEEPCmd(port, data) outp((port)+IOP_EEP_CMD, data)
1857 #define AscGetChipEEPData(port) (ushort)inpw((port)+IOP_EEP_DATA)
1858 #define AscSetChipEEPData(port, data) outpw((port)+IOP_EEP_DATA, data)
1859 #define AscGetChipLramAddr(port) (ushort)inpw((PortAddr)((port)+IOP_RAM_ADDR))
1860 #define AscSetChipLramAddr(port, addr) outpw((PortAddr)((port)+IOP_RAM_ADDR), addr)
1861 #define AscGetChipLramData(port) (ushort)inpw((port)+IOP_RAM_DATA)
1862 #define AscSetChipLramData(port, data) outpw((port)+IOP_RAM_DATA, data)
1863 #define AscGetChipIFC(port) (uchar)inp((port)+IOP_REG_IFC)
1864 #define AscSetChipIFC(port, data) outp((port)+IOP_REG_IFC, data)
1865 #define AscGetChipStatus(port) (ASC_CS_TYPE)inpw((port)+IOP_STATUS)
1866 #define AscSetChipStatus(port, cs_val) outpw((port)+IOP_STATUS, cs_val)
1867 #define AscGetChipControl(port) (uchar)inp((port)+IOP_CTRL)
1868 #define AscSetChipControl(port, cc_val) outp((port)+IOP_CTRL, cc_val)
1869 #define AscGetChipSyn(port) (uchar)inp((port)+IOP_SYN_OFFSET)
1870 #define AscSetChipSyn(port, data) outp((port)+IOP_SYN_OFFSET, data)
1871 #define AscSetPCAddr(port, data) outpw((port)+IOP_REG_PC, data)
1872 #define AscGetPCAddr(port) (ushort)inpw((port)+IOP_REG_PC)
1873 #define AscIsIntPending(port) (AscGetChipStatus(port) & (CSW_INT_PENDING | CSW_SCSI_RESET_LATCH))
1874 #define AscGetChipScsiID(port) ((AscGetChipCfgLsw(port) >> 8) & ASC_MAX_TID)
1875 #define AscGetExtraControl(port) (uchar)inp((port)+IOP_EXTRA_CONTROL)
1876 #define AscSetExtraControl(port, data) outp((port)+IOP_EXTRA_CONTROL, data)
1877 #define AscReadChipAX(port) (ushort)inpw((port)+IOP_REG_AX)
1878 #define AscWriteChipAX(port, data) outpw((port)+IOP_REG_AX, data)
1879 #define AscReadChipIX(port) (uchar)inp((port)+IOP_REG_IX)
1880 #define AscWriteChipIX(port, data) outp((port)+IOP_REG_IX, data)
1881 #define AscReadChipIH(port) (ushort)inpw((port)+IOP_REG_IH)
1882 #define AscWriteChipIH(port, data) outpw((port)+IOP_REG_IH, data)
1883 #define AscReadChipQP(port) (uchar)inp((port)+IOP_REG_QP)
1884 #define AscWriteChipQP(port, data) outp((port)+IOP_REG_QP, data)
1885 #define AscReadChipFIFO_L(port) (ushort)inpw((port)+IOP_REG_FIFO_L)
1886 #define AscWriteChipFIFO_L(port, data) outpw((port)+IOP_REG_FIFO_L, data)
1887 #define AscReadChipFIFO_H(port) (ushort)inpw((port)+IOP_REG_FIFO_H)
1888 #define AscWriteChipFIFO_H(port, data) outpw((port)+IOP_REG_FIFO_H, data)
1889 #define AscReadChipDmaSpeed(port) (uchar)inp((port)+IOP_DMA_SPEED)
1890 #define AscWriteChipDmaSpeed(port, data) outp((port)+IOP_DMA_SPEED, data)
1891 #define AscReadChipDA0(port) (ushort)inpw((port)+IOP_REG_DA0)
1892 #define AscWriteChipDA0(port) outpw((port)+IOP_REG_DA0, data)
1893 #define AscReadChipDA1(port) (ushort)inpw((port)+IOP_REG_DA1)
1894 #define AscWriteChipDA1(port) outpw((port)+IOP_REG_DA1, data)
1895 #define AscReadChipDC0(port) (ushort)inpw((port)+IOP_REG_DC0)
1896 #define AscWriteChipDC0(port) outpw((port)+IOP_REG_DC0, data)
1897 #define AscReadChipDC1(port) (ushort)inpw((port)+IOP_REG_DC1)
1898 #define AscWriteChipDC1(port) outpw((port)+IOP_REG_DC1, data)
1899 #define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID)
1900 #define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data)
1902 STATIC int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
1903 STATIC int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
1904 STATIC void AscWaitEEPRead(void);
1905 STATIC void AscWaitEEPWrite(void);
1906 STATIC ushort AscReadEEPWord(PortAddr, uchar);
1907 STATIC ushort AscWriteEEPWord(PortAddr, uchar, ushort);
1908 STATIC ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1909 STATIC int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort);
1910 STATIC int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
1911 STATIC int AscStartChip(PortAddr);
1912 STATIC int AscStopChip(PortAddr);
1913 STATIC void AscSetChipIH(PortAddr, ushort);
1914 STATIC int AscIsChipHalted(PortAddr);
1915 STATIC void AscAckInterrupt(PortAddr);
1916 STATIC void AscDisableInterrupt(PortAddr);
1917 STATIC void AscEnableInterrupt(PortAddr);
1918 STATIC void AscSetBank(PortAddr, uchar);
1919 STATIC int AscResetChipAndScsiBus(ASC_DVC_VAR *);
1920 #ifdef CONFIG_ISA
1921 STATIC ushort AscGetIsaDmaChannel(PortAddr);
1922 STATIC ushort AscSetIsaDmaChannel(PortAddr, ushort);
1923 STATIC uchar AscSetIsaDmaSpeed(PortAddr, uchar);
1924 STATIC uchar AscGetIsaDmaSpeed(PortAddr);
1925 #endif /* CONFIG_ISA */
1926 STATIC uchar AscReadLramByte(PortAddr, ushort);
1927 STATIC ushort AscReadLramWord(PortAddr, ushort);
1928 #if CC_VERY_LONG_SG_LIST
1929 STATIC ASC_DCNT AscReadLramDWord(PortAddr, ushort);
1930 #endif /* CC_VERY_LONG_SG_LIST */
1931 STATIC void AscWriteLramWord(PortAddr, ushort, ushort);
1932 STATIC void AscWriteLramByte(PortAddr, ushort, uchar);
1933 STATIC ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int);
1934 STATIC void AscMemWordSetLram(PortAddr, ushort, ushort, int);
1935 STATIC void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1936 STATIC void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int);
1937 STATIC void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int);
1938 STATIC ushort AscInitAscDvcVar(ASC_DVC_VAR *);
1939 STATIC ushort AscInitFromEEP(ASC_DVC_VAR *);
1940 STATIC ushort AscInitFromAscDvcVar(ASC_DVC_VAR *);
1941 STATIC ushort AscInitMicroCodeVar(ASC_DVC_VAR *);
1942 STATIC int AscTestExternalLram(ASC_DVC_VAR *);
1943 STATIC uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar);
1944 STATIC uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar);
1945 STATIC void AscSetChipSDTR(PortAddr, uchar, uchar);
1946 STATIC uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar);
1947 STATIC uchar AscAllocFreeQueue(PortAddr, uchar);
1948 STATIC uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
1949 STATIC int AscHostReqRiscHalt(PortAddr);
1950 STATIC int AscStopQueueExe(PortAddr);
1951 STATIC int AscSendScsiQueue(ASC_DVC_VAR *,
1952 ASC_SCSI_Q * scsiq,
1953 uchar n_q_required);
1954 STATIC int AscPutReadyQueue(ASC_DVC_VAR *,
1955 ASC_SCSI_Q *, uchar);
1956 STATIC int AscPutReadySgListQueue(ASC_DVC_VAR *,
1957 ASC_SCSI_Q *, uchar);
1958 STATIC int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
1959 STATIC int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
1960 STATIC ushort AscInitLram(ASC_DVC_VAR *);
1961 STATIC ushort AscInitQLinkVar(ASC_DVC_VAR *);
1962 STATIC int AscSetLibErrorCode(ASC_DVC_VAR *, ushort);
1963 STATIC int AscIsrChipHalted(ASC_DVC_VAR *);
1964 STATIC uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
1965 ASC_QDONE_INFO *, ASC_DCNT);
1966 STATIC int AscIsrQDone(ASC_DVC_VAR *);
1967 STATIC int AscCompareString(uchar *, uchar *, int);
1968 #ifdef CONFIG_ISA
1969 STATIC ushort AscGetEisaChipCfg(PortAddr);
1970 STATIC ASC_DCNT AscGetEisaProductID(PortAddr);
1971 STATIC PortAddr AscSearchIOPortAddrEISA(PortAddr);
1972 STATIC PortAddr AscSearchIOPortAddr11(PortAddr);
1973 STATIC PortAddr AscSearchIOPortAddr(PortAddr, ushort);
1974 STATIC void AscSetISAPNPWaitForKey(void);
1975 #endif /* CONFIG_ISA */
1976 STATIC uchar AscGetChipScsiCtrl(PortAddr);
1977 STATIC uchar AscSetChipScsiID(PortAddr, uchar);
1978 STATIC uchar AscGetChipVersion(PortAddr, ushort);
1979 STATIC ushort AscGetChipBusType(PortAddr);
1980 STATIC ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort);
1981 STATIC int AscFindSignature(PortAddr);
1982 STATIC void AscToggleIRQAct(PortAddr);
1983 STATIC uchar AscGetChipIRQ(PortAddr, ushort);
1984 STATIC uchar AscSetChipIRQ(PortAddr, uchar, ushort);
1985 STATIC ushort AscGetChipBiosAddress(PortAddr, ushort);
1986 STATIC inline ulong DvcEnterCritical(void);
1987 STATIC inline void DvcLeaveCritical(ulong);
1988 #ifdef CONFIG_PCI
1989 STATIC uchar DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort);
1990 STATIC void DvcWritePCIConfigByte(ASC_DVC_VAR *,
1991 ushort, uchar);
1992 #endif /* CONFIG_PCI */
1993 STATIC ushort AscGetChipBiosAddress(PortAddr, ushort);
1994 STATIC void DvcSleepMilliSecond(ASC_DCNT);
1995 STATIC void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT);
1996 STATIC void DvcPutScsiQ(PortAddr, ushort, uchar *, int);
1997 STATIC void DvcGetQinfo(PortAddr, ushort, uchar *, int);
1998 STATIC ushort AscInitGetConfig(ASC_DVC_VAR *);
1999 STATIC ushort AscInitSetConfig(ASC_DVC_VAR *);
2000 STATIC ushort AscInitAsc1000Driver(ASC_DVC_VAR *);
2001 STATIC void AscAsyncFix(ASC_DVC_VAR *, uchar,
2002 ASC_SCSI_INQUIRY *);
2003 STATIC int AscTagQueuingSafe(ASC_SCSI_INQUIRY *);
2004 STATIC void AscInquiryHandling(ASC_DVC_VAR *,
2005 uchar, ASC_SCSI_INQUIRY *);
2006 STATIC int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *);
2007 STATIC int AscISR(ASC_DVC_VAR *);
2008 STATIC uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar,
2009 uchar);
2010 STATIC int AscSgListToQueue(int);
2011 #ifdef CONFIG_ISA
2012 STATIC void AscEnableIsaDma(uchar);
2013 #endif /* CONFIG_ISA */
2014 STATIC ASC_DCNT AscGetMaxDmaCount(ushort);
2018 * --- Adv Library Constants and Macros
2021 #define ADV_LIB_VERSION_MAJOR 5
2022 #define ADV_LIB_VERSION_MINOR 14
2025 * Define Adv Library required special types.
2029 * Portable Data Types
2031 * Any instance where a 32-bit long or pointer type is assumed
2032 * for precision or HW defined structures, the following define
2033 * types must be used. In Linux the char, short, and int types
2034 * are all consistent at 8, 16, and 32 bits respectively. Pointers
2035 * and long types are 64 bits on Alpha and UltraSPARC.
2037 #define ADV_PADDR __u32 /* Physical address data type. */
2038 #define ADV_VADDR __u32 /* Virtual address data type. */
2039 #define ADV_DCNT __u32 /* Unsigned Data count type. */
2040 #define ADV_SDCNT __s32 /* Signed Data count type. */
2043 * These macros are used to convert a virtual address to a
2044 * 32-bit value. This currently can be used on Linux Alpha
2045 * which uses 64-bit virtual address but a 32-bit bus address.
2046 * This is likely to break in the future, but doing this now
2047 * will give us time to change the HW and FW to handle 64-bit
2048 * addresses.
2050 #define ADV_VADDR_TO_U32 virt_to_bus
2051 #define ADV_U32_TO_VADDR bus_to_virt
2053 #define AdvPortAddr void __iomem * /* Virtual memory address size */
2056 * Define Adv Library required memory access macros.
2058 #define ADV_MEM_READB(addr) readb(addr)
2059 #define ADV_MEM_READW(addr) readw(addr)
2060 #define ADV_MEM_WRITEB(addr, byte) writeb(byte, addr)
2061 #define ADV_MEM_WRITEW(addr, word) writew(word, addr)
2062 #define ADV_MEM_WRITEDW(addr, dword) writel(dword, addr)
2064 #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15)
2067 * For wide boards a CDB length maximum of 16 bytes
2068 * is supported.
2070 #define ADV_MAX_CDB_LEN 16
2073 * Define total number of simultaneous maximum element scatter-gather
2074 * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the
2075 * maximum number of outstanding commands per wide host adapter. Each
2076 * command uses one or more ADV_SG_BLOCK each with 15 scatter-gather
2077 * elements. Allow each command to have at least one ADV_SG_BLOCK structure.
2078 * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK
2079 * structures or 255 scatter-gather elements.
2082 #define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG
2085 * Define Adv Library required maximum number of scatter-gather
2086 * elements per request.
2088 #define ADV_MAX_SG_LIST 255
2090 /* Number of SG blocks needed. */
2091 #define ADV_NUM_SG_BLOCK \
2092 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)
2094 /* Total contiguous memory needed for SG blocks. */
2095 #define ADV_SG_TOTAL_MEM_SIZE \
2096 (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK)
2098 #define ADV_PAGE_SIZE PAGE_SIZE
2100 #define ADV_NUM_PAGE_CROSSING \
2101 ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2103 /* a_condor.h */
2104 #define ADV_PCI_VENDOR_ID 0x10CD
2105 #define ADV_PCI_DEVICE_ID_REV_A 0x2300
2106 #define ADV_PCI_DEVID_38C0800_REV1 0x2500
2107 #define ADV_PCI_DEVID_38C1600_REV1 0x2700
2109 #define ADV_EEP_DVC_CFG_BEGIN (0x00)
2110 #define ADV_EEP_DVC_CFG_END (0x15)
2111 #define ADV_EEP_DVC_CTL_BEGIN (0x16) /* location of OEM name */
2112 #define ADV_EEP_MAX_WORD_ADDR (0x1E)
2114 #define ADV_EEP_DELAY_MS 100
2116 #define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */
2117 #define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */
2119 * For the ASC3550 Bit 13 is Termination Polarity control bit.
2120 * For later ICs Bit 13 controls whether the CIS (Card Information
2121 * Service Section) is loaded from EEPROM.
2123 #define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */
2124 #define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */
2126 * ASC38C1600 Bit 11
2128 * If EEPROM Bit 11 is 0 for Function 0, then Function 0 will specify
2129 * INT A in the PCI Configuration Space Int Pin field. If it is 1, then
2130 * Function 0 will specify INT B.
2132 * If EEPROM Bit 11 is 0 for Function 1, then Function 1 will specify
2133 * INT B in the PCI Configuration Space Int Pin field. If it is 1, then
2134 * Function 1 will specify INT A.
2136 #define ADV_EEPROM_INTAB 0x0800 /* EEPROM Bit 11 */
2138 typedef struct adveep_3550_config
2140 /* Word Offset, Description */
2142 ushort cfg_lsw; /* 00 power up initialization */
2143 /* bit 13 set - Term Polarity Control */
2144 /* bit 14 set - BIOS Enable */
2145 /* bit 15 set - Big Endian Mode */
2146 ushort cfg_msw; /* 01 unused */
2147 ushort disc_enable; /* 02 disconnect enable */
2148 ushort wdtr_able; /* 03 Wide DTR able */
2149 ushort sdtr_able; /* 04 Synchronous DTR able */
2150 ushort start_motor; /* 05 send start up motor */
2151 ushort tagqng_able; /* 06 tag queuing able */
2152 ushort bios_scan; /* 07 BIOS device control */
2153 ushort scam_tolerant; /* 08 no scam */
2155 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2156 uchar bios_boot_delay; /* power up wait */
2158 uchar scsi_reset_delay; /* 10 reset delay */
2159 uchar bios_id_lun; /* first boot device scsi id & lun */
2160 /* high nibble is lun */
2161 /* low nibble is scsi id */
2163 uchar termination; /* 11 0 - automatic */
2164 /* 1 - low off / high off */
2165 /* 2 - low off / high on */
2166 /* 3 - low on / high on */
2167 /* There is no low on / high off */
2169 uchar reserved1; /* reserved byte (not used) */
2171 ushort bios_ctrl; /* 12 BIOS control bits */
2172 /* bit 0 BIOS don't act as initiator. */
2173 /* bit 1 BIOS > 1 GB support */
2174 /* bit 2 BIOS > 2 Disk Support */
2175 /* bit 3 BIOS don't support removables */
2176 /* bit 4 BIOS support bootable CD */
2177 /* bit 5 BIOS scan enabled */
2178 /* bit 6 BIOS support multiple LUNs */
2179 /* bit 7 BIOS display of message */
2180 /* bit 8 SCAM disabled */
2181 /* bit 9 Reset SCSI bus during init. */
2182 /* bit 10 */
2183 /* bit 11 No verbose initialization. */
2184 /* bit 12 SCSI parity enabled */
2185 /* bit 13 */
2186 /* bit 14 */
2187 /* bit 15 */
2188 ushort ultra_able; /* 13 ULTRA speed able */
2189 ushort reserved2; /* 14 reserved */
2190 uchar max_host_qng; /* 15 maximum host queuing */
2191 uchar max_dvc_qng; /* maximum per device queuing */
2192 ushort dvc_cntl; /* 16 control bit for driver */
2193 ushort bug_fix; /* 17 control bit for bug fix */
2194 ushort serial_number_word1; /* 18 Board serial number word 1 */
2195 ushort serial_number_word2; /* 19 Board serial number word 2 */
2196 ushort serial_number_word3; /* 20 Board serial number word 3 */
2197 ushort check_sum; /* 21 EEP check sum */
2198 uchar oem_name[16]; /* 22 OEM name */
2199 ushort dvc_err_code; /* 30 last device driver error code */
2200 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2201 ushort adv_err_addr; /* 32 last uc error address */
2202 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2203 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2204 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2205 ushort num_of_err; /* 36 number of error */
2206 } ADVEEP_3550_CONFIG;
2208 typedef struct adveep_38C0800_config
2210 /* Word Offset, Description */
2212 ushort cfg_lsw; /* 00 power up initialization */
2213 /* bit 13 set - Load CIS */
2214 /* bit 14 set - BIOS Enable */
2215 /* bit 15 set - Big Endian Mode */
2216 ushort cfg_msw; /* 01 unused */
2217 ushort disc_enable; /* 02 disconnect enable */
2218 ushort wdtr_able; /* 03 Wide DTR able */
2219 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2220 ushort start_motor; /* 05 send start up motor */
2221 ushort tagqng_able; /* 06 tag queuing able */
2222 ushort bios_scan; /* 07 BIOS device control */
2223 ushort scam_tolerant; /* 08 no scam */
2225 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2226 uchar bios_boot_delay; /* power up wait */
2228 uchar scsi_reset_delay; /* 10 reset delay */
2229 uchar bios_id_lun; /* first boot device scsi id & lun */
2230 /* high nibble is lun */
2231 /* low nibble is scsi id */
2233 uchar termination_se; /* 11 0 - automatic */
2234 /* 1 - low off / high off */
2235 /* 2 - low off / high on */
2236 /* 3 - low on / high on */
2237 /* There is no low on / high off */
2239 uchar termination_lvd; /* 11 0 - automatic */
2240 /* 1 - low off / high off */
2241 /* 2 - low off / high on */
2242 /* 3 - low on / high on */
2243 /* There is no low on / high off */
2245 ushort bios_ctrl; /* 12 BIOS control bits */
2246 /* bit 0 BIOS don't act as initiator. */
2247 /* bit 1 BIOS > 1 GB support */
2248 /* bit 2 BIOS > 2 Disk Support */
2249 /* bit 3 BIOS don't support removables */
2250 /* bit 4 BIOS support bootable CD */
2251 /* bit 5 BIOS scan enabled */
2252 /* bit 6 BIOS support multiple LUNs */
2253 /* bit 7 BIOS display of message */
2254 /* bit 8 SCAM disabled */
2255 /* bit 9 Reset SCSI bus during init. */
2256 /* bit 10 */
2257 /* bit 11 No verbose initialization. */
2258 /* bit 12 SCSI parity enabled */
2259 /* bit 13 */
2260 /* bit 14 */
2261 /* bit 15 */
2262 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2263 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2264 uchar max_host_qng; /* 15 maximum host queueing */
2265 uchar max_dvc_qng; /* maximum per device queuing */
2266 ushort dvc_cntl; /* 16 control bit for driver */
2267 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2268 ushort serial_number_word1; /* 18 Board serial number word 1 */
2269 ushort serial_number_word2; /* 19 Board serial number word 2 */
2270 ushort serial_number_word3; /* 20 Board serial number word 3 */
2271 ushort check_sum; /* 21 EEP check sum */
2272 uchar oem_name[16]; /* 22 OEM name */
2273 ushort dvc_err_code; /* 30 last device driver error code */
2274 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2275 ushort adv_err_addr; /* 32 last uc error address */
2276 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2277 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2278 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2279 ushort reserved36; /* 36 reserved */
2280 ushort reserved37; /* 37 reserved */
2281 ushort reserved38; /* 38 reserved */
2282 ushort reserved39; /* 39 reserved */
2283 ushort reserved40; /* 40 reserved */
2284 ushort reserved41; /* 41 reserved */
2285 ushort reserved42; /* 42 reserved */
2286 ushort reserved43; /* 43 reserved */
2287 ushort reserved44; /* 44 reserved */
2288 ushort reserved45; /* 45 reserved */
2289 ushort reserved46; /* 46 reserved */
2290 ushort reserved47; /* 47 reserved */
2291 ushort reserved48; /* 48 reserved */
2292 ushort reserved49; /* 49 reserved */
2293 ushort reserved50; /* 50 reserved */
2294 ushort reserved51; /* 51 reserved */
2295 ushort reserved52; /* 52 reserved */
2296 ushort reserved53; /* 53 reserved */
2297 ushort reserved54; /* 54 reserved */
2298 ushort reserved55; /* 55 reserved */
2299 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2300 ushort cisprt_msw; /* 57 CIS PTR MSW */
2301 ushort subsysvid; /* 58 SubSystem Vendor ID */
2302 ushort subsysid; /* 59 SubSystem ID */
2303 ushort reserved60; /* 60 reserved */
2304 ushort reserved61; /* 61 reserved */
2305 ushort reserved62; /* 62 reserved */
2306 ushort reserved63; /* 63 reserved */
2307 } ADVEEP_38C0800_CONFIG;
2309 typedef struct adveep_38C1600_config
2311 /* Word Offset, Description */
2313 ushort cfg_lsw; /* 00 power up initialization */
2314 /* bit 11 set - Func. 0 INTB, Func. 1 INTA */
2315 /* clear - Func. 0 INTA, Func. 1 INTB */
2316 /* bit 13 set - Load CIS */
2317 /* bit 14 set - BIOS Enable */
2318 /* bit 15 set - Big Endian Mode */
2319 ushort cfg_msw; /* 01 unused */
2320 ushort disc_enable; /* 02 disconnect enable */
2321 ushort wdtr_able; /* 03 Wide DTR able */
2322 ushort sdtr_speed1; /* 04 SDTR Speed TID 0-3 */
2323 ushort start_motor; /* 05 send start up motor */
2324 ushort tagqng_able; /* 06 tag queuing able */
2325 ushort bios_scan; /* 07 BIOS device control */
2326 ushort scam_tolerant; /* 08 no scam */
2328 uchar adapter_scsi_id; /* 09 Host Adapter ID */
2329 uchar bios_boot_delay; /* power up wait */
2331 uchar scsi_reset_delay; /* 10 reset delay */
2332 uchar bios_id_lun; /* first boot device scsi id & lun */
2333 /* high nibble is lun */
2334 /* low nibble is scsi id */
2336 uchar termination_se; /* 11 0 - automatic */
2337 /* 1 - low off / high off */
2338 /* 2 - low off / high on */
2339 /* 3 - low on / high on */
2340 /* There is no low on / high off */
2342 uchar termination_lvd; /* 11 0 - automatic */
2343 /* 1 - low off / high off */
2344 /* 2 - low off / high on */
2345 /* 3 - low on / high on */
2346 /* There is no low on / high off */
2348 ushort bios_ctrl; /* 12 BIOS control bits */
2349 /* bit 0 BIOS don't act as initiator. */
2350 /* bit 1 BIOS > 1 GB support */
2351 /* bit 2 BIOS > 2 Disk Support */
2352 /* bit 3 BIOS don't support removables */
2353 /* bit 4 BIOS support bootable CD */
2354 /* bit 5 BIOS scan enabled */
2355 /* bit 6 BIOS support multiple LUNs */
2356 /* bit 7 BIOS display of message */
2357 /* bit 8 SCAM disabled */
2358 /* bit 9 Reset SCSI bus during init. */
2359 /* bit 10 Basic Integrity Checking disabled */
2360 /* bit 11 No verbose initialization. */
2361 /* bit 12 SCSI parity enabled */
2362 /* bit 13 AIPP (Asyn. Info. Ph. Prot.) dis. */
2363 /* bit 14 */
2364 /* bit 15 */
2365 ushort sdtr_speed2; /* 13 SDTR speed TID 4-7 */
2366 ushort sdtr_speed3; /* 14 SDTR speed TID 8-11 */
2367 uchar max_host_qng; /* 15 maximum host queueing */
2368 uchar max_dvc_qng; /* maximum per device queuing */
2369 ushort dvc_cntl; /* 16 control bit for driver */
2370 ushort sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */
2371 ushort serial_number_word1; /* 18 Board serial number word 1 */
2372 ushort serial_number_word2; /* 19 Board serial number word 2 */
2373 ushort serial_number_word3; /* 20 Board serial number word 3 */
2374 ushort check_sum; /* 21 EEP check sum */
2375 uchar oem_name[16]; /* 22 OEM name */
2376 ushort dvc_err_code; /* 30 last device driver error code */
2377 ushort adv_err_code; /* 31 last uc and Adv Lib error code */
2378 ushort adv_err_addr; /* 32 last uc error address */
2379 ushort saved_dvc_err_code; /* 33 saved last dev. driver error code */
2380 ushort saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */
2381 ushort saved_adv_err_addr; /* 35 saved last uc error address */
2382 ushort reserved36; /* 36 reserved */
2383 ushort reserved37; /* 37 reserved */
2384 ushort reserved38; /* 38 reserved */
2385 ushort reserved39; /* 39 reserved */
2386 ushort reserved40; /* 40 reserved */
2387 ushort reserved41; /* 41 reserved */
2388 ushort reserved42; /* 42 reserved */
2389 ushort reserved43; /* 43 reserved */
2390 ushort reserved44; /* 44 reserved */
2391 ushort reserved45; /* 45 reserved */
2392 ushort reserved46; /* 46 reserved */
2393 ushort reserved47; /* 47 reserved */
2394 ushort reserved48; /* 48 reserved */
2395 ushort reserved49; /* 49 reserved */
2396 ushort reserved50; /* 50 reserved */
2397 ushort reserved51; /* 51 reserved */
2398 ushort reserved52; /* 52 reserved */
2399 ushort reserved53; /* 53 reserved */
2400 ushort reserved54; /* 54 reserved */
2401 ushort reserved55; /* 55 reserved */
2402 ushort cisptr_lsw; /* 56 CIS PTR LSW */
2403 ushort cisprt_msw; /* 57 CIS PTR MSW */
2404 ushort subsysvid; /* 58 SubSystem Vendor ID */
2405 ushort subsysid; /* 59 SubSystem ID */
2406 ushort reserved60; /* 60 reserved */
2407 ushort reserved61; /* 61 reserved */
2408 ushort reserved62; /* 62 reserved */
2409 ushort reserved63; /* 63 reserved */
2410 } ADVEEP_38C1600_CONFIG;
2413 * EEPROM Commands
2415 #define ASC_EEP_CMD_DONE 0x0200
2416 #define ASC_EEP_CMD_DONE_ERR 0x0001
2418 /* cfg_word */
2419 #define EEP_CFG_WORD_BIG_ENDIAN 0x8000
2421 /* bios_ctrl */
2422 #define BIOS_CTRL_BIOS 0x0001
2423 #define BIOS_CTRL_EXTENDED_XLAT 0x0002
2424 #define BIOS_CTRL_GT_2_DISK 0x0004
2425 #define BIOS_CTRL_BIOS_REMOVABLE 0x0008
2426 #define BIOS_CTRL_BOOTABLE_CD 0x0010
2427 #define BIOS_CTRL_MULTIPLE_LUN 0x0040
2428 #define BIOS_CTRL_DISPLAY_MSG 0x0080
2429 #define BIOS_CTRL_NO_SCAM 0x0100
2430 #define BIOS_CTRL_RESET_SCSI_BUS 0x0200
2431 #define BIOS_CTRL_INIT_VERBOSE 0x0800
2432 #define BIOS_CTRL_SCSI_PARITY 0x1000
2433 #define BIOS_CTRL_AIPP_DIS 0x2000
2435 #define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */
2436 #define ADV_3550_IOLEN 0x40 /* I/O Port Range in bytes */
2438 #define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2439 #define ADV_38C0800_IOLEN 0x100 /* I/O Port Range in bytes */
2442 * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is
2443 * a special 16K Adv Library and Microcode version. After the issue is
2444 * resolved, should restore 32K support.
2446 * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory *
2448 #define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */
2449 #define ADV_38C1600_IOLEN 0x100 /* I/O Port Range 256 bytes */
2450 #define ADV_38C1600_MEMLEN 0x1000 /* Memory Range 4KB bytes */
2453 * Byte I/O register address from base of 'iop_base'.
2455 #define IOPB_INTR_STATUS_REG 0x00
2456 #define IOPB_CHIP_ID_1 0x01
2457 #define IOPB_INTR_ENABLES 0x02
2458 #define IOPB_CHIP_TYPE_REV 0x03
2459 #define IOPB_RES_ADDR_4 0x04
2460 #define IOPB_RES_ADDR_5 0x05
2461 #define IOPB_RAM_DATA 0x06
2462 #define IOPB_RES_ADDR_7 0x07
2463 #define IOPB_FLAG_REG 0x08
2464 #define IOPB_RES_ADDR_9 0x09
2465 #define IOPB_RISC_CSR 0x0A
2466 #define IOPB_RES_ADDR_B 0x0B
2467 #define IOPB_RES_ADDR_C 0x0C
2468 #define IOPB_RES_ADDR_D 0x0D
2469 #define IOPB_SOFT_OVER_WR 0x0E
2470 #define IOPB_RES_ADDR_F 0x0F
2471 #define IOPB_MEM_CFG 0x10
2472 #define IOPB_RES_ADDR_11 0x11
2473 #define IOPB_GPIO_DATA 0x12
2474 #define IOPB_RES_ADDR_13 0x13
2475 #define IOPB_FLASH_PAGE 0x14
2476 #define IOPB_RES_ADDR_15 0x15
2477 #define IOPB_GPIO_CNTL 0x16
2478 #define IOPB_RES_ADDR_17 0x17
2479 #define IOPB_FLASH_DATA 0x18
2480 #define IOPB_RES_ADDR_19 0x19
2481 #define IOPB_RES_ADDR_1A 0x1A
2482 #define IOPB_RES_ADDR_1B 0x1B
2483 #define IOPB_RES_ADDR_1C 0x1C
2484 #define IOPB_RES_ADDR_1D 0x1D
2485 #define IOPB_RES_ADDR_1E 0x1E
2486 #define IOPB_RES_ADDR_1F 0x1F
2487 #define IOPB_DMA_CFG0 0x20
2488 #define IOPB_DMA_CFG1 0x21
2489 #define IOPB_TICKLE 0x22
2490 #define IOPB_DMA_REG_WR 0x23
2491 #define IOPB_SDMA_STATUS 0x24
2492 #define IOPB_SCSI_BYTE_CNT 0x25
2493 #define IOPB_HOST_BYTE_CNT 0x26
2494 #define IOPB_BYTE_LEFT_TO_XFER 0x27
2495 #define IOPB_BYTE_TO_XFER_0 0x28
2496 #define IOPB_BYTE_TO_XFER_1 0x29
2497 #define IOPB_BYTE_TO_XFER_2 0x2A
2498 #define IOPB_BYTE_TO_XFER_3 0x2B
2499 #define IOPB_ACC_GRP 0x2C
2500 #define IOPB_RES_ADDR_2D 0x2D
2501 #define IOPB_DEV_ID 0x2E
2502 #define IOPB_RES_ADDR_2F 0x2F
2503 #define IOPB_SCSI_DATA 0x30
2504 #define IOPB_RES_ADDR_31 0x31
2505 #define IOPB_RES_ADDR_32 0x32
2506 #define IOPB_SCSI_DATA_HSHK 0x33
2507 #define IOPB_SCSI_CTRL 0x34
2508 #define IOPB_RES_ADDR_35 0x35
2509 #define IOPB_RES_ADDR_36 0x36
2510 #define IOPB_RES_ADDR_37 0x37
2511 #define IOPB_RAM_BIST 0x38
2512 #define IOPB_PLL_TEST 0x39
2513 #define IOPB_PCI_INT_CFG 0x3A
2514 #define IOPB_RES_ADDR_3B 0x3B
2515 #define IOPB_RFIFO_CNT 0x3C
2516 #define IOPB_RES_ADDR_3D 0x3D
2517 #define IOPB_RES_ADDR_3E 0x3E
2518 #define IOPB_RES_ADDR_3F 0x3F
2521 * Word I/O register address from base of 'iop_base'.
2523 #define IOPW_CHIP_ID_0 0x00 /* CID0 */
2524 #define IOPW_CTRL_REG 0x02 /* CC */
2525 #define IOPW_RAM_ADDR 0x04 /* LA */
2526 #define IOPW_RAM_DATA 0x06 /* LD */
2527 #define IOPW_RES_ADDR_08 0x08
2528 #define IOPW_RISC_CSR 0x0A /* CSR */
2529 #define IOPW_SCSI_CFG0 0x0C /* CFG0 */
2530 #define IOPW_SCSI_CFG1 0x0E /* CFG1 */
2531 #define IOPW_RES_ADDR_10 0x10
2532 #define IOPW_SEL_MASK 0x12 /* SM */
2533 #define IOPW_RES_ADDR_14 0x14
2534 #define IOPW_FLASH_ADDR 0x16 /* FA */
2535 #define IOPW_RES_ADDR_18 0x18
2536 #define IOPW_EE_CMD 0x1A /* EC */
2537 #define IOPW_EE_DATA 0x1C /* ED */
2538 #define IOPW_SFIFO_CNT 0x1E /* SFC */
2539 #define IOPW_RES_ADDR_20 0x20
2540 #define IOPW_Q_BASE 0x22 /* QB */
2541 #define IOPW_QP 0x24 /* QP */
2542 #define IOPW_IX 0x26 /* IX */
2543 #define IOPW_SP 0x28 /* SP */
2544 #define IOPW_PC 0x2A /* PC */
2545 #define IOPW_RES_ADDR_2C 0x2C
2546 #define IOPW_RES_ADDR_2E 0x2E
2547 #define IOPW_SCSI_DATA 0x30 /* SD */
2548 #define IOPW_SCSI_DATA_HSHK 0x32 /* SDH */
2549 #define IOPW_SCSI_CTRL 0x34 /* SC */
2550 #define IOPW_HSHK_CFG 0x36 /* HCFG */
2551 #define IOPW_SXFR_STATUS 0x36 /* SXS */
2552 #define IOPW_SXFR_CNTL 0x38 /* SXL */
2553 #define IOPW_SXFR_CNTH 0x3A /* SXH */
2554 #define IOPW_RES_ADDR_3C 0x3C
2555 #define IOPW_RFIFO_DATA 0x3E /* RFD */
2558 * Doubleword I/O register address from base of 'iop_base'.
2560 #define IOPDW_RES_ADDR_0 0x00
2561 #define IOPDW_RAM_DATA 0x04
2562 #define IOPDW_RES_ADDR_8 0x08
2563 #define IOPDW_RES_ADDR_C 0x0C
2564 #define IOPDW_RES_ADDR_10 0x10
2565 #define IOPDW_COMMA 0x14
2566 #define IOPDW_COMMB 0x18
2567 #define IOPDW_RES_ADDR_1C 0x1C
2568 #define IOPDW_SDMA_ADDR0 0x20
2569 #define IOPDW_SDMA_ADDR1 0x24
2570 #define IOPDW_SDMA_COUNT 0x28
2571 #define IOPDW_SDMA_ERROR 0x2C
2572 #define IOPDW_RDMA_ADDR0 0x30
2573 #define IOPDW_RDMA_ADDR1 0x34
2574 #define IOPDW_RDMA_COUNT 0x38
2575 #define IOPDW_RDMA_ERROR 0x3C
2577 #define ADV_CHIP_ID_BYTE 0x25
2578 #define ADV_CHIP_ID_WORD 0x04C1
2580 #define ADV_SC_SCSI_BUS_RESET 0x2000
2582 #define ADV_INTR_ENABLE_HOST_INTR 0x01
2583 #define ADV_INTR_ENABLE_SEL_INTR 0x02
2584 #define ADV_INTR_ENABLE_DPR_INTR 0x04
2585 #define ADV_INTR_ENABLE_RTA_INTR 0x08
2586 #define ADV_INTR_ENABLE_RMA_INTR 0x10
2587 #define ADV_INTR_ENABLE_RST_INTR 0x20
2588 #define ADV_INTR_ENABLE_DPE_INTR 0x40
2589 #define ADV_INTR_ENABLE_GLOBAL_INTR 0x80
2591 #define ADV_INTR_STATUS_INTRA 0x01
2592 #define ADV_INTR_STATUS_INTRB 0x02
2593 #define ADV_INTR_STATUS_INTRC 0x04
2595 #define ADV_RISC_CSR_STOP (0x0000)
2596 #define ADV_RISC_TEST_COND (0x2000)
2597 #define ADV_RISC_CSR_RUN (0x4000)
2598 #define ADV_RISC_CSR_SINGLE_STEP (0x8000)
2600 #define ADV_CTRL_REG_HOST_INTR 0x0100
2601 #define ADV_CTRL_REG_SEL_INTR 0x0200
2602 #define ADV_CTRL_REG_DPR_INTR 0x0400
2603 #define ADV_CTRL_REG_RTA_INTR 0x0800
2604 #define ADV_CTRL_REG_RMA_INTR 0x1000
2605 #define ADV_CTRL_REG_RES_BIT14 0x2000
2606 #define ADV_CTRL_REG_DPE_INTR 0x4000
2607 #define ADV_CTRL_REG_POWER_DONE 0x8000
2608 #define ADV_CTRL_REG_ANY_INTR 0xFF00
2610 #define ADV_CTRL_REG_CMD_RESET 0x00C6
2611 #define ADV_CTRL_REG_CMD_WR_IO_REG 0x00C5
2612 #define ADV_CTRL_REG_CMD_RD_IO_REG 0x00C4
2613 #define ADV_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3
2614 #define ADV_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2
2616 #define ADV_TICKLE_NOP 0x00
2617 #define ADV_TICKLE_A 0x01
2618 #define ADV_TICKLE_B 0x02
2619 #define ADV_TICKLE_C 0x03
2621 #define ADV_SCSI_CTRL_RSTOUT 0x2000
2623 #define AdvIsIntPending(port) \
2624 (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR)
2627 * SCSI_CFG0 Register bit definitions
2629 #define TIMER_MODEAB 0xC000 /* Watchdog, Second, and Select. Timer Ctrl. */
2630 #define PARITY_EN 0x2000 /* Enable SCSI Parity Error detection */
2631 #define EVEN_PARITY 0x1000 /* Select Even Parity */
2632 #define WD_LONG 0x0800 /* Watchdog Interval, 1: 57 min, 0: 13 sec */
2633 #define QUEUE_128 0x0400 /* Queue Size, 1: 128 byte, 0: 64 byte */
2634 #define PRIM_MODE 0x0100 /* Primitive SCSI mode */
2635 #define SCAM_EN 0x0080 /* Enable SCAM selection */
2636 #define SEL_TMO_LONG 0x0040 /* Sel/Resel Timeout, 1: 400 ms, 0: 1.6 ms */
2637 #define CFRM_ID 0x0020 /* SCAM id sel. confirm., 1: fast, 0: 6.4 ms */
2638 #define OUR_ID_EN 0x0010 /* Enable OUR_ID bits */
2639 #define OUR_ID 0x000F /* SCSI ID */
2642 * SCSI_CFG1 Register bit definitions
2644 #define BIG_ENDIAN 0x8000 /* Enable Big Endian Mode MIO:15, EEP:15 */
2645 #define TERM_POL 0x2000 /* Terminator Polarity Ctrl. MIO:13, EEP:13 */
2646 #define SLEW_RATE 0x1000 /* SCSI output buffer slew rate */
2647 #define FILTER_SEL 0x0C00 /* Filter Period Selection */
2648 #define FLTR_DISABLE 0x0000 /* Input Filtering Disabled */
2649 #define FLTR_11_TO_20NS 0x0800 /* Input Filtering 11ns to 20ns */
2650 #define FLTR_21_TO_39NS 0x0C00 /* Input Filtering 21ns to 39ns */
2651 #define ACTIVE_DBL 0x0200 /* Disable Active Negation */
2652 #define DIFF_MODE 0x0100 /* SCSI differential Mode (Read-Only) */
2653 #define DIFF_SENSE 0x0080 /* 1: No SE cables, 0: SE cable (Read-Only) */
2654 #define TERM_CTL_SEL 0x0040 /* Enable TERM_CTL_H and TERM_CTL_L */
2655 #define TERM_CTL 0x0030 /* External SCSI Termination Bits */
2656 #define TERM_CTL_H 0x0020 /* Enable External SCSI Upper Termination */
2657 #define TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */
2658 #define CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */
2661 * Addendum for ASC-38C0800 Chip
2663 * The ASC-38C1600 Chip uses the same definitions except that the
2664 * bus mode override bits [12:10] have been moved to byte register
2665 * offset 0xE (IOPB_SOFT_OVER_WR) bits [12:10]. The [12:10] bits in
2666 * SCSI_CFG1 are read-only and always available. Bit 14 (DIS_TERM_DRV)
2667 * is not needed. The [12:10] bits in IOPB_SOFT_OVER_WR are write-only.
2668 * Also each ASC-38C1600 function or channel uses only cable bits [5:4]
2669 * and [1:0]. Bits [14], [7:6], [3:2] are unused.
2671 #define DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */
2672 #define HVD_LVD_SE 0x1C00 /* Device Detect Bits */
2673 #define HVD 0x1000 /* HVD Device Detect */
2674 #define LVD 0x0800 /* LVD Device Detect */
2675 #define SE 0x0400 /* SE Device Detect */
2676 #define TERM_LVD 0x00C0 /* LVD Termination Bits */
2677 #define TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */
2678 #define TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */
2679 #define TERM_SE 0x0030 /* SE Termination Bits */
2680 #define TERM_SE_HI 0x0020 /* Enable SE Upper Termination */
2681 #define TERM_SE_LO 0x0010 /* Enable SE Lower Termination */
2682 #define C_DET_LVD 0x000C /* LVD Cable Detect Bits */
2683 #define C_DET3 0x0008 /* Cable Detect for LVD External Wide */
2684 #define C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */
2685 #define C_DET_SE 0x0003 /* SE Cable Detect Bits */
2686 #define C_DET1 0x0002 /* Cable Detect for SE Internal Wide */
2687 #define C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */
2690 #define CABLE_ILLEGAL_A 0x7
2691 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */
2693 #define CABLE_ILLEGAL_B 0xB
2694 /* 0 x 0 0 | on on | Illegal (all 3 connectors are used) */
2697 * MEM_CFG Register bit definitions
2699 #define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */
2700 #define FAST_EE_CLK 0x20 /* Diagnostic Bit */
2701 #define RAM_SZ 0x1C /* Specify size of RAM to RISC */
2702 #define RAM_SZ_2KB 0x00 /* 2 KB */
2703 #define RAM_SZ_4KB 0x04 /* 4 KB */
2704 #define RAM_SZ_8KB 0x08 /* 8 KB */
2705 #define RAM_SZ_16KB 0x0C /* 16 KB */
2706 #define RAM_SZ_32KB 0x10 /* 32 KB */
2707 #define RAM_SZ_64KB 0x14 /* 64 KB */
2710 * DMA_CFG0 Register bit definitions
2712 * This register is only accessible to the host.
2714 #define BC_THRESH_ENB 0x80 /* PCI DMA Start Conditions */
2715 #define FIFO_THRESH 0x70 /* PCI DMA FIFO Threshold */
2716 #define FIFO_THRESH_16B 0x00 /* 16 bytes */
2717 #define FIFO_THRESH_32B 0x20 /* 32 bytes */
2718 #define FIFO_THRESH_48B 0x30 /* 48 bytes */
2719 #define FIFO_THRESH_64B 0x40 /* 64 bytes */
2720 #define FIFO_THRESH_80B 0x50 /* 80 bytes (default) */
2721 #define FIFO_THRESH_96B 0x60 /* 96 bytes */
2722 #define FIFO_THRESH_112B 0x70 /* 112 bytes */
2723 #define START_CTL 0x0C /* DMA start conditions */
2724 #define START_CTL_TH 0x00 /* Wait threshold level (default) */
2725 #define START_CTL_ID 0x04 /* Wait SDMA/SBUS idle */
2726 #define START_CTL_THID 0x08 /* Wait threshold and SDMA/SBUS idle */
2727 #define START_CTL_EMFU 0x0C /* Wait SDMA FIFO empty/full */
2728 #define READ_CMD 0x03 /* Memory Read Method */
2729 #define READ_CMD_MR 0x00 /* Memory Read */
2730 #define READ_CMD_MRL 0x02 /* Memory Read Long */
2731 #define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */
2734 * ASC-38C0800 RAM BIST Register bit definitions
2736 #define RAM_TEST_MODE 0x80
2737 #define PRE_TEST_MODE 0x40
2738 #define NORMAL_MODE 0x00
2739 #define RAM_TEST_DONE 0x10
2740 #define RAM_TEST_STATUS 0x0F
2741 #define RAM_TEST_HOST_ERROR 0x08
2742 #define RAM_TEST_INTRAM_ERROR 0x04
2743 #define RAM_TEST_RISC_ERROR 0x02
2744 #define RAM_TEST_SCSI_ERROR 0x01
2745 #define RAM_TEST_SUCCESS 0x00
2746 #define PRE_TEST_VALUE 0x05
2747 #define NORMAL_VALUE 0x00
2750 * ASC38C1600 Definitions
2752 * IOPB_PCI_INT_CFG Bit Field Definitions
2755 #define INTAB_LD 0x80 /* Value loaded from EEPROM Bit 11. */
2758 * Bit 1 can be set to change the interrupt for the Function to operate in
2759 * Totem Pole mode. By default Bit 1 is 0 and the interrupt operates in
2760 * Open Drain mode. Both functions of the ASC38C1600 must be set to the same
2761 * mode, otherwise the operating mode is undefined.
2763 #define TOTEMPOLE 0x02
2766 * Bit 0 can be used to change the Int Pin for the Function. The value is
2767 * 0 by default for both Functions with Function 0 using INT A and Function
2768 * B using INT B. For Function 0 if set, INT B is used. For Function 1 if set,
2769 * INT A is used.
2771 * EEPROM Word 0 Bit 11 for each Function may change the initial Int Pin
2772 * value specified in the PCI Configuration Space.
2774 #define INTAB 0x01
2776 /* a_advlib.h */
2779 * Adv Library Status Definitions
2781 #define ADV_TRUE 1
2782 #define ADV_FALSE 0
2783 #define ADV_NOERROR 1
2784 #define ADV_SUCCESS 1
2785 #define ADV_BUSY 0
2786 #define ADV_ERROR (-1)
2790 * ADV_DVC_VAR 'warn_code' values
2792 #define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */
2793 #define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */
2794 #define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */
2795 #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */
2796 #define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */
2798 #define ADV_MAX_TID 15 /* max. target identifier */
2799 #define ADV_MAX_LUN 7 /* max. logical unit number */
2802 * Error code values are set in ADV_DVC_VAR 'err_code'.
2804 #define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */
2805 #define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */
2806 #define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */
2807 #define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */
2808 #define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */
2809 #define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */
2810 #define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */
2811 #define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */
2812 #define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */
2813 #define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */
2814 #define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */
2815 #define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */
2816 #define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */
2817 #define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */
2820 * Fixed locations of microcode operating variables.
2822 #define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */
2823 #define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */
2824 #define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */
2825 #define ASC_MC_VERSION_DATE 0x0038 /* microcode version */
2826 #define ASC_MC_VERSION_NUM 0x003A /* microcode number */
2827 #define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */
2828 #define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */
2829 #define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */
2830 #define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */
2831 #define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */
2832 #define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */
2833 #define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */
2834 #define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */
2835 #define ASC_MC_CHIP_TYPE 0x009A
2836 #define ASC_MC_INTRB_CODE 0x009B
2837 #define ASC_MC_WDTR_ABLE 0x009C
2838 #define ASC_MC_SDTR_ABLE 0x009E
2839 #define ASC_MC_TAGQNG_ABLE 0x00A0
2840 #define ASC_MC_DISC_ENABLE 0x00A2
2841 #define ASC_MC_IDLE_CMD_STATUS 0x00A4
2842 #define ASC_MC_IDLE_CMD 0x00A6
2843 #define ASC_MC_IDLE_CMD_PARAMETER 0x00A8
2844 #define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC
2845 #define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE
2846 #define ASC_MC_DEFAULT_MEM_CFG 0x00B0
2847 #define ASC_MC_DEFAULT_SEL_MASK 0x00B2
2848 #define ASC_MC_SDTR_DONE 0x00B6
2849 #define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0
2850 #define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0
2851 #define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100
2852 #define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */
2853 #define ASC_MC_WDTR_DONE 0x0124
2854 #define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */
2855 #define ASC_MC_ICQ 0x0160
2856 #define ASC_MC_IRQ 0x0164
2857 #define ASC_MC_PPR_ABLE 0x017A
2860 * BIOS LRAM variable absolute offsets.
2862 #define BIOS_CODESEG 0x54
2863 #define BIOS_CODELEN 0x56
2864 #define BIOS_SIGNATURE 0x58
2865 #define BIOS_VERSION 0x5A
2868 * Microcode Control Flags
2870 * Flags set by the Adv Library in RISC variable 'control_flag' (0x122)
2871 * and handled by the microcode.
2873 #define CONTROL_FLAG_IGNORE_PERR 0x0001 /* Ignore DMA Parity Errors */
2874 #define CONTROL_FLAG_ENABLE_AIPP 0x0002 /* Enabled AIPP checking. */
2877 * ASC_MC_DEVICE_HSHK_CFG_TABLE microcode table or HSHK_CFG register format
2879 #define HSHK_CFG_WIDE_XFR 0x8000
2880 #define HSHK_CFG_RATE 0x0F00
2881 #define HSHK_CFG_OFFSET 0x001F
2883 #define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */
2884 #define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */
2885 #define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */
2886 #define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */
2888 #define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */
2889 #define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */
2890 #define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */
2891 #define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */
2892 #define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */
2894 #define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */
2895 #define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */
2896 #define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */
2897 #define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */
2898 #define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */
2900 * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or
2901 * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used.
2903 #define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */
2904 #define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */
2907 * All fields here are accessed by the board microcode and need to be
2908 * little-endian.
2910 typedef struct adv_carr_t
2912 ADV_VADDR carr_va; /* Carrier Virtual Address */
2913 ADV_PADDR carr_pa; /* Carrier Physical Address */
2914 ADV_VADDR areq_vpa; /* ASC_SCSI_REQ_Q Virtual or Physical Address */
2916 * next_vpa [31:4] Carrier Virtual or Physical Next Pointer
2918 * next_vpa [3:1] Reserved Bits
2919 * next_vpa [0] Done Flag set in Response Queue.
2921 ADV_VADDR next_vpa;
2922 } ADV_CARR_T;
2925 * Mask used to eliminate low 4 bits of carrier 'next_vpa' field.
2927 #define ASC_NEXT_VPA_MASK 0xFFFFFFF0
2929 #define ASC_RQ_DONE 0x00000001
2930 #define ASC_RQ_GOOD 0x00000002
2931 #define ASC_CQ_STOPPER 0x00000000
2933 #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK)
2935 #define ADV_CARRIER_NUM_PAGE_CROSSING \
2936 (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \
2937 (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE)
2939 #define ADV_CARRIER_BUFSIZE \
2940 ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T))
2943 * ASC_SCSI_REQ_Q 'a_flag' definitions
2945 * The Adv Library should limit use to the lower nibble (4 bits) of
2946 * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag.
2948 #define ADV_POLL_REQUEST 0x01 /* poll for request completion */
2949 #define ADV_SCSIQ_DONE 0x02 /* request done */
2950 #define ADV_DONT_RETRY 0x08 /* don't do retry */
2952 #define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */
2953 #define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */
2954 #define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */
2957 * Adapter temporary configuration structure
2959 * This structure can be discarded after initialization. Don't add
2960 * fields here needed after initialization.
2962 * Field naming convention:
2964 * *_enable indicates the field enables or disables a feature. The
2965 * value of the field is never reset.
2967 typedef struct adv_dvc_cfg {
2968 ushort disc_enable; /* enable disconnection */
2969 uchar chip_version; /* chip version */
2970 uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */
2971 ushort lib_version; /* Adv Library version number */
2972 ushort control_flag; /* Microcode Control Flag */
2973 ushort mcode_date; /* Microcode date */
2974 ushort mcode_version; /* Microcode version */
2975 ushort pci_slot_info; /* high byte device/function number */
2976 /* bits 7-3 device num., bits 2-0 function num. */
2977 /* low byte bus num. */
2978 ushort serial1; /* EEPROM serial number word 1 */
2979 ushort serial2; /* EEPROM serial number word 2 */
2980 ushort serial3; /* EEPROM serial number word 3 */
2981 struct device *dev; /* pointer to the pci dev structure for this board */
2982 } ADV_DVC_CFG;
2984 struct adv_dvc_var;
2985 struct adv_scsi_req_q;
2987 typedef void (* ADV_ISR_CALLBACK)
2988 (struct adv_dvc_var *, struct adv_scsi_req_q *);
2990 typedef void (* ADV_ASYNC_CALLBACK)
2991 (struct adv_dvc_var *, uchar);
2994 * Adapter operation variable structure.
2996 * One structure is required per host adapter.
2998 * Field naming convention:
3000 * *_able indicates both whether a feature should be enabled or disabled
3001 * and whether a device isi capable of the feature. At initialization
3002 * this field may be set, but later if a device is found to be incapable
3003 * of the feature, the field is cleared.
3005 typedef struct adv_dvc_var {
3006 AdvPortAddr iop_base; /* I/O port address */
3007 ushort err_code; /* fatal error code */
3008 ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */
3009 ADV_ISR_CALLBACK isr_callback;
3010 ADV_ASYNC_CALLBACK async_callback;
3011 ushort wdtr_able; /* try WDTR for a device */
3012 ushort sdtr_able; /* try SDTR for a device */
3013 ushort ultra_able; /* try SDTR Ultra speed for a device */
3014 ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */
3015 ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */
3016 ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */
3017 ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */
3018 ushort tagqng_able; /* try tagged queuing with a device */
3019 ushort ppr_able; /* PPR message capable per TID bitmask. */
3020 uchar max_dvc_qng; /* maximum number of tagged commands per device */
3021 ushort start_motor; /* start motor command allowed */
3022 uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */
3023 uchar chip_no; /* should be assigned by caller */
3024 uchar max_host_qng; /* maximum number of Q'ed command allowed */
3025 uchar irq_no; /* IRQ number */
3026 ushort no_scam; /* scam_tolerant of EEPROM */
3027 struct asc_board *drv_ptr; /* driver pointer to private structure */
3028 uchar chip_scsi_id; /* chip SCSI target ID */
3029 uchar chip_type;
3030 uchar bist_err_code;
3031 ADV_CARR_T *carrier_buf;
3032 ADV_CARR_T *carr_freelist; /* Carrier free list. */
3033 ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */
3034 ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */
3035 ushort carr_pending_cnt; /* Count of pending carriers. */
3037 * Note: The following fields will not be used after initialization. The
3038 * driver may discard the buffer after initialization is done.
3040 ADV_DVC_CFG *cfg; /* temporary configuration structure */
3041 } ADV_DVC_VAR;
3043 #define NO_OF_SG_PER_BLOCK 15
3045 typedef struct asc_sg_block {
3046 uchar reserved1;
3047 uchar reserved2;
3048 uchar reserved3;
3049 uchar sg_cnt; /* Valid entries in block. */
3050 ADV_PADDR sg_ptr; /* Pointer to next sg block. */
3051 struct {
3052 ADV_PADDR sg_addr; /* SG element address. */
3053 ADV_DCNT sg_count; /* SG element count. */
3054 } sg_list[NO_OF_SG_PER_BLOCK];
3055 } ADV_SG_BLOCK;
3058 * ADV_SCSI_REQ_Q - microcode request structure
3060 * All fields in this structure up to byte 60 are used by the microcode.
3061 * The microcode makes assumptions about the size and ordering of fields
3062 * in this structure. Do not change the structure definition here without
3063 * coordinating the change with the microcode.
3065 * All fields accessed by microcode must be maintained in little_endian
3066 * order.
3068 typedef struct adv_scsi_req_q {
3069 uchar cntl; /* Ucode flags and state (ASC_MC_QC_*). */
3070 uchar target_cmd;
3071 uchar target_id; /* Device target identifier. */
3072 uchar target_lun; /* Device target logical unit number. */
3073 ADV_PADDR data_addr; /* Data buffer physical address. */
3074 ADV_DCNT data_cnt; /* Data count. Ucode sets to residual. */
3075 ADV_PADDR sense_addr;
3076 ADV_PADDR carr_pa;
3077 uchar mflag;
3078 uchar sense_len;
3079 uchar cdb_len; /* SCSI CDB length. Must <= 16 bytes. */
3080 uchar scsi_cntl;
3081 uchar done_status; /* Completion status. */
3082 uchar scsi_status; /* SCSI status byte. */
3083 uchar host_status; /* Ucode host status. */
3084 uchar sg_working_ix;
3085 uchar cdb[12]; /* SCSI CDB bytes 0-11. */
3086 ADV_PADDR sg_real_addr; /* SG list physical address. */
3087 ADV_PADDR scsiq_rptr;
3088 uchar cdb16[4]; /* SCSI CDB bytes 12-15. */
3089 ADV_VADDR scsiq_ptr;
3090 ADV_VADDR carr_va;
3092 * End of microcode structure - 60 bytes. The rest of the structure
3093 * is used by the Adv Library and ignored by the microcode.
3095 ADV_VADDR srb_ptr;
3096 ADV_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */
3097 char *vdata_addr; /* Data buffer virtual address. */
3098 uchar a_flag;
3099 uchar pad[2]; /* Pad out to a word boundary. */
3100 } ADV_SCSI_REQ_Q;
3103 * Microcode idle loop commands
3105 #define IDLE_CMD_COMPLETED 0
3106 #define IDLE_CMD_STOP_CHIP 0x0001
3107 #define IDLE_CMD_STOP_CHIP_SEND_INT 0x0002
3108 #define IDLE_CMD_SEND_INT 0x0004
3109 #define IDLE_CMD_ABORT 0x0008
3110 #define IDLE_CMD_DEVICE_RESET 0x0010
3111 #define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */
3112 #define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */
3113 #define IDLE_CMD_SCSIREQ 0x0080
3115 #define IDLE_CMD_STATUS_SUCCESS 0x0001
3116 #define IDLE_CMD_STATUS_FAILURE 0x0002
3119 * AdvSendIdleCmd() flag definitions.
3121 #define ADV_NOWAIT 0x01
3124 * Wait loop time out values.
3126 #define SCSI_WAIT_10_SEC 10UL /* 10 seconds */
3127 #define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */
3128 #define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */
3129 #define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */
3130 #define SCSI_MAX_RETRY 10 /* retry count */
3132 #define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */
3133 #define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */
3134 #define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */
3135 #define ADV_RDMA_IN_CARR_AND_Q_INVALID 0x04 /* RDMAed-in data invalid. */
3138 #define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */
3141 * Device drivers must define the following functions.
3143 STATIC inline ulong DvcEnterCritical(void);
3144 STATIC inline void DvcLeaveCritical(ulong);
3145 STATIC void DvcSleepMilliSecond(ADV_DCNT);
3146 STATIC uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort);
3147 STATIC void DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar);
3148 STATIC ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *,
3149 uchar *, ASC_SDCNT *, int);
3150 STATIC void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort);
3153 * Adv Library functions available to drivers.
3155 STATIC int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3156 STATIC int AdvISR(ADV_DVC_VAR *);
3157 STATIC int AdvInitGetConfig(ADV_DVC_VAR *);
3158 STATIC int AdvInitAsc3550Driver(ADV_DVC_VAR *);
3159 STATIC int AdvInitAsc38C0800Driver(ADV_DVC_VAR *);
3160 STATIC int AdvInitAsc38C1600Driver(ADV_DVC_VAR *);
3161 STATIC int AdvResetChipAndSB(ADV_DVC_VAR *);
3162 STATIC int AdvResetSB(ADV_DVC_VAR *asc_dvc);
3165 * Internal Adv Library functions.
3167 STATIC int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT);
3168 STATIC void AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
3169 STATIC int AdvInitFrom3550EEP(ADV_DVC_VAR *);
3170 STATIC int AdvInitFrom38C0800EEP(ADV_DVC_VAR *);
3171 STATIC int AdvInitFrom38C1600EEP(ADV_DVC_VAR *);
3172 STATIC ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3173 STATIC void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *);
3174 STATIC ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3175 STATIC void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *);
3176 STATIC ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3177 STATIC void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *);
3178 STATIC void AdvWaitEEPCmd(AdvPortAddr);
3179 STATIC ushort AdvReadEEPWord(AdvPortAddr, int);
3182 * PCI Bus Definitions
3184 #define AscPCICmdRegBits_BusMastering 0x0007
3185 #define AscPCICmdRegBits_ParErrRespCtrl 0x0040
3187 /* Read byte from a register. */
3188 #define AdvReadByteRegister(iop_base, reg_off) \
3189 (ADV_MEM_READB((iop_base) + (reg_off)))
3191 /* Write byte to a register. */
3192 #define AdvWriteByteRegister(iop_base, reg_off, byte) \
3193 (ADV_MEM_WRITEB((iop_base) + (reg_off), (byte)))
3195 /* Read word (2 bytes) from a register. */
3196 #define AdvReadWordRegister(iop_base, reg_off) \
3197 (ADV_MEM_READW((iop_base) + (reg_off)))
3199 /* Write word (2 bytes) to a register. */
3200 #define AdvWriteWordRegister(iop_base, reg_off, word) \
3201 (ADV_MEM_WRITEW((iop_base) + (reg_off), (word)))
3203 /* Write dword (4 bytes) to a register. */
3204 #define AdvWriteDWordRegister(iop_base, reg_off, dword) \
3205 (ADV_MEM_WRITEDW((iop_base) + (reg_off), (dword)))
3207 /* Read byte from LRAM. */
3208 #define AdvReadByteLram(iop_base, addr, byte) \
3209 do { \
3210 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3211 (byte) = ADV_MEM_READB((iop_base) + IOPB_RAM_DATA); \
3212 } while (0)
3214 /* Write byte to LRAM. */
3215 #define AdvWriteByteLram(iop_base, addr, byte) \
3216 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3217 ADV_MEM_WRITEB((iop_base) + IOPB_RAM_DATA, (byte)))
3219 /* Read word (2 bytes) from LRAM. */
3220 #define AdvReadWordLram(iop_base, addr, word) \
3221 do { \
3222 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)); \
3223 (word) = (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA)); \
3224 } while (0)
3226 /* Write word (2 bytes) to LRAM. */
3227 #define AdvWriteWordLram(iop_base, addr, word) \
3228 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3229 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3231 /* Write little-endian double word (4 bytes) to LRAM */
3232 /* Because of unspecified C language ordering don't use auto-increment. */
3233 #define AdvWriteDWordLramNoSwap(iop_base, addr, dword) \
3234 ((ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr)), \
3235 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3236 cpu_to_le16((ushort) ((dword) & 0xFFFF)))), \
3237 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_ADDR, (addr) + 2), \
3238 ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, \
3239 cpu_to_le16((ushort) ((dword >> 16) & 0xFFFF)))))
3241 /* Read word (2 bytes) from LRAM assuming that the address is already set. */
3242 #define AdvReadWordAutoIncLram(iop_base) \
3243 (ADV_MEM_READW((iop_base) + IOPW_RAM_DATA))
3245 /* Write word (2 bytes) to LRAM assuming that the address is already set. */
3246 #define AdvWriteWordAutoIncLram(iop_base, word) \
3247 (ADV_MEM_WRITEW((iop_base) + IOPW_RAM_DATA, (word)))
3251 * Define macro to check for Condor signature.
3253 * Evaluate to ADV_TRUE if a Condor chip is found the specified port
3254 * address 'iop_base'. Otherwise evalue to ADV_FALSE.
3256 #define AdvFindSignature(iop_base) \
3257 (((AdvReadByteRegister((iop_base), IOPB_CHIP_ID_1) == \
3258 ADV_CHIP_ID_BYTE) && \
3259 (AdvReadWordRegister((iop_base), IOPW_CHIP_ID_0) == \
3260 ADV_CHIP_ID_WORD)) ? ADV_TRUE : ADV_FALSE)
3263 * Define macro to Return the version number of the chip at 'iop_base'.
3265 * The second parameter 'bus_type' is currently unused.
3267 #define AdvGetChipVersion(iop_base, bus_type) \
3268 AdvReadByteRegister((iop_base), IOPB_CHIP_TYPE_REV)
3271 * Abort an SRB in the chip's RISC Memory. The 'srb_ptr' argument must
3272 * match the ASC_SCSI_REQ_Q 'srb_ptr' field.
3274 * If the request has not yet been sent to the device it will simply be
3275 * aborted from RISC memory. If the request is disconnected it will be
3276 * aborted on reselection by sending an Abort Message to the target ID.
3278 * Return value:
3279 * ADV_TRUE(1) - Queue was successfully aborted.
3280 * ADV_FALSE(0) - Queue was not found on the active queue list.
3282 #define AdvAbortQueue(asc_dvc, scsiq) \
3283 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_ABORT, \
3284 (ADV_DCNT) (scsiq))
3287 * Send a Bus Device Reset Message to the specified target ID.
3289 * All outstanding commands will be purged if sending the
3290 * Bus Device Reset Message is successful.
3292 * Return Value:
3293 * ADV_TRUE(1) - All requests on the target are purged.
3294 * ADV_FALSE(0) - Couldn't issue Bus Device Reset Message; Requests
3295 * are not purged.
3297 #define AdvResetDevice(asc_dvc, target_id) \
3298 AdvSendIdleCmd((asc_dvc), (ushort) IDLE_CMD_DEVICE_RESET, \
3299 (ADV_DCNT) (target_id))
3302 * SCSI Wide Type definition.
3304 #define ADV_SCSI_BIT_ID_TYPE ushort
3307 * AdvInitScsiTarget() 'cntl_flag' options.
3309 #define ADV_SCAN_LUN 0x01
3310 #define ADV_CAPINFO_NOLUN 0x02
3313 * Convert target id to target id bit mask.
3315 #define ADV_TID_TO_TIDMASK(tid) (0x01 << ((tid) & ADV_MAX_TID))
3318 * ASC_SCSI_REQ_Q 'done_status' and 'host_status' return values.
3321 #define QD_NO_STATUS 0x00 /* Request not completed yet. */
3322 #define QD_NO_ERROR 0x01
3323 #define QD_ABORTED_BY_HOST 0x02
3324 #define QD_WITH_ERROR 0x04
3326 #define QHSTA_NO_ERROR 0x00
3327 #define QHSTA_M_SEL_TIMEOUT 0x11
3328 #define QHSTA_M_DATA_OVER_RUN 0x12
3329 #define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
3330 #define QHSTA_M_QUEUE_ABORTED 0x15
3331 #define QHSTA_M_SXFR_SDMA_ERR 0x16 /* SXFR_STATUS SCSI DMA Error */
3332 #define QHSTA_M_SXFR_SXFR_PERR 0x17 /* SXFR_STATUS SCSI Bus Parity Error */
3333 #define QHSTA_M_RDMA_PERR 0x18 /* RISC PCI DMA parity error */
3334 #define QHSTA_M_SXFR_OFF_UFLW 0x19 /* SXFR_STATUS Offset Underflow */
3335 #define QHSTA_M_SXFR_OFF_OFLW 0x20 /* SXFR_STATUS Offset Overflow */
3336 #define QHSTA_M_SXFR_WD_TMO 0x21 /* SXFR_STATUS Watchdog Timeout */
3337 #define QHSTA_M_SXFR_DESELECTED 0x22 /* SXFR_STATUS Deselected */
3338 /* Note: QHSTA_M_SXFR_XFR_OFLW is identical to QHSTA_M_DATA_OVER_RUN. */
3339 #define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */
3340 #define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */
3341 #define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */
3342 #define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */
3343 #define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */
3344 #define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */
3345 #define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */
3346 #define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */
3347 #define QHSTA_M_WTM_TIMEOUT 0x41
3348 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
3349 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
3350 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
3351 #define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */
3352 #define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */
3353 #define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */
3357 * Default EEPROM Configuration structure defined in a_init.c.
3359 static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config;
3360 static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config;
3361 static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config;
3364 * DvcGetPhyAddr() flag arguments
3366 #define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */
3367 #define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */
3368 #define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */
3369 #define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */
3370 #define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */
3371 #define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */
3373 /* Return the address that is aligned at the next doubleword >= to 'addr'. */
3374 #define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7)
3375 #define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF)
3376 #define ADV_32BALIGN(addr) (((ulong) (addr) + 0x1F) & ~0x1F)
3379 * Total contiguous memory needed for driver SG blocks.
3381 * ADV_MAX_SG_LIST must be defined by a driver. It is the maximum
3382 * number of scatter-gather elements the driver supports in a
3383 * single request.
3386 #define ADV_SG_LIST_MAX_BYTE_SIZE \
3387 (sizeof(ADV_SG_BLOCK) * \
3388 ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK))
3391 * Inquiry data structure and bitfield macros
3393 * Using bitfields to access the subchar data isn't portable across
3394 * endianness, so instead mask and shift. Only quantities of more
3395 * than 1 bit are shifted, since the others are just tested for true
3396 * or false.
3399 #define ADV_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f)
3400 #define ADV_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5)
3401 #define ADV_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f)
3402 #define ADV_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80)
3403 #define ADV_INQ_ANSI_VER(inq) ((inq)->ver & 0x07)
3404 #define ADV_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3)
3405 #define ADV_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6)
3406 #define ADV_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f)
3407 #define ADV_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40)
3408 #define ADV_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80)
3409 #define ADV_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01)
3410 #define ADV_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02)
3411 #define ADV_INQ_LINK_CMD(inq) ((inq)->flags & 0x08)
3412 #define ADV_INQ_SYNC(inq) ((inq)->flags & 0x10)
3413 #define ADV_INQ_WIDE16(inq) ((inq)->flags & 0x20)
3414 #define ADV_INQ_WIDE32(inq) ((inq)->flags & 0x40)
3415 #define ADV_INQ_REL_ADDR(inq) ((inq)->flags & 0x80)
3416 #define ADV_INQ_INFO_UNIT(inq) ((inq)->info & 0x01)
3417 #define ADV_INQ_QUICK_ARB(inq) ((inq)->info & 0x02)
3418 #define ADV_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2)
3420 typedef struct {
3421 uchar periph; /* peripheral device type [0:4] */
3422 /* peripheral qualifier [5:7] */
3423 uchar devtype; /* device type modifier (for SCSI I) [0:6] */
3424 /* RMB - removable medium bit [7] */
3425 uchar ver; /* ANSI approved version [0:2] */
3426 /* ECMA version [3:5] */
3427 /* ISO version [6:7] */
3428 uchar byte3; /* response data format [0:3] */
3429 /* 0 SCSI 1 */
3430 /* 1 CCS */
3431 /* 2 SCSI-2 */
3432 /* 3-F reserved */
3433 /* reserved [4:5] */
3434 /* terminate I/O process bit (see 5.6.22) [6] */
3435 /* asynch. event notification (processor) [7] */
3436 uchar add_len; /* additional length */
3437 uchar res1; /* reserved */
3438 uchar res2; /* reserved */
3439 uchar flags; /* soft reset implemented [0] */
3440 /* command queuing [1] */
3441 /* reserved [2] */
3442 /* linked command for this logical unit [3] */
3443 /* synchronous data transfer [4] */
3444 /* wide bus 16 bit data transfer [5] */
3445 /* wide bus 32 bit data transfer [6] */
3446 /* relative addressing mode [7] */
3447 uchar vendor_id[8]; /* vendor identification */
3448 uchar product_id[16]; /* product identification */
3449 uchar product_rev_level[4]; /* product revision level */
3450 uchar vendor_specific[20]; /* vendor specific */
3451 uchar info; /* information unit supported [0] */
3452 /* quick arbitrate supported [1] */
3453 /* clocking field [2:3] */
3454 /* reserved [4:7] */
3455 uchar res3; /* reserved */
3456 } ADV_SCSI_INQUIRY; /* 58 bytes */
3460 * --- Driver Constants and Macros
3463 #define ASC_NUM_BOARD_SUPPORTED 16
3464 #define ASC_NUM_IOPORT_PROBE 4
3465 #define ASC_NUM_BUS 4
3467 /* Reference Scsi_Host hostdata */
3468 #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata))
3470 /* asc_board_t flags */
3471 #define ASC_HOST_IN_RESET 0x01
3472 #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */
3473 #define ASC_SELECT_QUEUE_DEPTHS 0x08
3475 #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0)
3476 #define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD)
3478 #define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
3480 #define ASC_INFO_SIZE 128 /* advansys_info() line size */
3482 #ifdef CONFIG_PROC_FS
3483 /* /proc/scsi/advansys/[0...] related definitions */
3484 #define ASC_PRTBUF_SIZE 2048
3485 #define ASC_PRTLINE_SIZE 160
3487 #define ASC_PRT_NEXT() \
3488 if (cp) { \
3489 totlen += len; \
3490 leftlen -= len; \
3491 if (leftlen == 0) { \
3492 return totlen; \
3494 cp += len; \
3496 #endif /* CONFIG_PROC_FS */
3498 /* Asc Library return codes */
3499 #define ASC_TRUE 1
3500 #define ASC_FALSE 0
3501 #define ASC_NOERROR 1
3502 #define ASC_BUSY 0
3503 #define ASC_ERROR (-1)
3505 /* struct scsi_cmnd function return codes */
3506 #define STATUS_BYTE(byte) (byte)
3507 #define MSG_BYTE(byte) ((byte) << 8)
3508 #define HOST_BYTE(byte) ((byte) << 16)
3509 #define DRIVER_BYTE(byte) ((byte) << 24)
3512 * The following definitions and macros are OS independent interfaces to
3513 * the queue functions:
3514 * REQ - SCSI request structure
3515 * REQP - pointer to SCSI request structure
3516 * REQPTID(reqp) - reqp's target id
3517 * REQPNEXT(reqp) - reqp's next pointer
3518 * REQPNEXTP(reqp) - pointer to reqp's next pointer
3519 * REQPTIME(reqp) - reqp's time stamp value
3520 * REQTIMESTAMP() - system time stamp value
3522 typedef struct scsi_cmnd REQ, *REQP;
3523 #define REQPNEXT(reqp) ((REQP) ((reqp)->host_scribble))
3524 #define REQPNEXTP(reqp) ((REQP *) &((reqp)->host_scribble))
3525 #define REQPTID(reqp) ((reqp)->device->id)
3526 #define REQPTIME(reqp) ((reqp)->SCp.this_residual)
3527 #define REQTIMESTAMP() (jiffies)
3529 #define REQTIMESTAT(function, ascq, reqp, tid) \
3532 * If the request time stamp is less than the system time stamp, then \
3533 * maybe the system time stamp wrapped. Set the request time to zero.\
3534 */ \
3535 if (REQPTIME(reqp) <= REQTIMESTAMP()) { \
3536 REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \
3537 } else { \
3538 /* Indicate an error occurred with the assertion. */ \
3539 ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \
3540 REQPTIME(reqp) = 0; \
3542 /* Handle first minimum time case without external initialization. */ \
3543 if (((ascq)->q_tot_cnt[tid] == 1) || \
3544 (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \
3545 (ascq)->q_min_tim[tid] = REQPTIME(reqp); \
3546 ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \
3547 (function), (tid), (ascq)->q_min_tim[tid]); \
3549 if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \
3550 (ascq)->q_max_tim[tid] = REQPTIME(reqp); \
3551 ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \
3552 (function), tid, (ascq)->q_max_tim[tid]); \
3554 (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \
3555 /* Reset the time stamp field. */ \
3556 REQPTIME(reqp) = 0; \
3559 /* asc_enqueue() flags */
3560 #define ASC_FRONT 1
3561 #define ASC_BACK 2
3563 /* asc_dequeue_list() argument */
3564 #define ASC_TID_ALL (-1)
3566 /* Return non-zero, if the queue is empty. */
3567 #define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0)
3569 #define PCI_MAX_SLOT 0x1F
3570 #define PCI_MAX_BUS 0xFF
3571 #define PCI_IOADDRESS_MASK 0xFFFE
3572 #define ASC_PCI_VENDORID 0x10CD
3573 #define ASC_PCI_DEVICE_ID_CNT 6 /* PCI Device ID count. */
3574 #define ASC_PCI_DEVICE_ID_1100 0x1100
3575 #define ASC_PCI_DEVICE_ID_1200 0x1200
3576 #define ASC_PCI_DEVICE_ID_1300 0x1300
3577 #define ASC_PCI_DEVICE_ID_2300 0x2300 /* ASC-3550 */
3578 #define ASC_PCI_DEVICE_ID_2500 0x2500 /* ASC-38C0800 */
3579 #define ASC_PCI_DEVICE_ID_2700 0x2700 /* ASC-38C1600 */
3581 #ifndef ADVANSYS_STATS
3582 #define ASC_STATS(shp, counter)
3583 #define ASC_STATS_ADD(shp, counter, count)
3584 #else /* ADVANSYS_STATS */
3585 #define ASC_STATS(shp, counter) \
3586 (ASC_BOARDP(shp)->asc_stats.counter++)
3588 #define ASC_STATS_ADD(shp, counter, count) \
3589 (ASC_BOARDP(shp)->asc_stats.counter += (count))
3590 #endif /* ADVANSYS_STATS */
3592 #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit))
3594 /* If the result wraps when calculating tenths, return 0. */
3595 #define ASC_TENTHS(num, den) \
3596 (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \
3597 0 : ((((num) * 10)/(den)) - (10 * ((num)/(den)))))
3600 * Display a message to the console.
3602 #define ASC_PRINT(s) \
3604 printk("advansys: "); \
3605 printk(s); \
3608 #define ASC_PRINT1(s, a1) \
3610 printk("advansys: "); \
3611 printk((s), (a1)); \
3614 #define ASC_PRINT2(s, a1, a2) \
3616 printk("advansys: "); \
3617 printk((s), (a1), (a2)); \
3620 #define ASC_PRINT3(s, a1, a2, a3) \
3622 printk("advansys: "); \
3623 printk((s), (a1), (a2), (a3)); \
3626 #define ASC_PRINT4(s, a1, a2, a3, a4) \
3628 printk("advansys: "); \
3629 printk((s), (a1), (a2), (a3), (a4)); \
3633 #ifndef ADVANSYS_DEBUG
3635 #define ASC_DBG(lvl, s)
3636 #define ASC_DBG1(lvl, s, a1)
3637 #define ASC_DBG2(lvl, s, a1, a2)
3638 #define ASC_DBG3(lvl, s, a1, a2, a3)
3639 #define ASC_DBG4(lvl, s, a1, a2, a3, a4)
3640 #define ASC_DBG_PRT_SCSI_HOST(lvl, s)
3641 #define ASC_DBG_PRT_SCSI_CMND(lvl, s)
3642 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp)
3643 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3644 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone)
3645 #define ADV_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp)
3646 #define ASC_DBG_PRT_HEX(lvl, name, start, length)
3647 #define ASC_DBG_PRT_CDB(lvl, cdb, len)
3648 #define ASC_DBG_PRT_SENSE(lvl, sense, len)
3649 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
3651 #else /* ADVANSYS_DEBUG */
3654 * Debugging Message Levels:
3655 * 0: Errors Only
3656 * 1: High-Level Tracing
3657 * 2-N: Verbose Tracing
3660 #define ASC_DBG(lvl, s) \
3662 if (asc_dbglvl >= (lvl)) { \
3663 printk(s); \
3667 #define ASC_DBG1(lvl, s, a1) \
3669 if (asc_dbglvl >= (lvl)) { \
3670 printk((s), (a1)); \
3674 #define ASC_DBG2(lvl, s, a1, a2) \
3676 if (asc_dbglvl >= (lvl)) { \
3677 printk((s), (a1), (a2)); \
3681 #define ASC_DBG3(lvl, s, a1, a2, a3) \
3683 if (asc_dbglvl >= (lvl)) { \
3684 printk((s), (a1), (a2), (a3)); \
3688 #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
3690 if (asc_dbglvl >= (lvl)) { \
3691 printk((s), (a1), (a2), (a3), (a4)); \
3695 #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
3697 if (asc_dbglvl >= (lvl)) { \
3698 asc_prt_scsi_host(s); \
3702 #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \
3704 if (asc_dbglvl >= (lvl)) { \
3705 asc_prt_scsi_cmnd(s); \
3709 #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \
3711 if (asc_dbglvl >= (lvl)) { \
3712 asc_prt_asc_scsi_q(scsiqp); \
3716 #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) \
3718 if (asc_dbglvl >= (lvl)) { \
3719 asc_prt_asc_qdone_info(qdone); \
3723 #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) \
3725 if (asc_dbglvl >= (lvl)) { \
3726 asc_prt_adv_scsi_req_q(scsiqp); \
3730 #define ASC_DBG_PRT_HEX(lvl, name, start, length) \
3732 if (asc_dbglvl >= (lvl)) { \
3733 asc_prt_hex((name), (start), (length)); \
3737 #define ASC_DBG_PRT_CDB(lvl, cdb, len) \
3738 ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
3740 #define ASC_DBG_PRT_SENSE(lvl, sense, len) \
3741 ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
3743 #define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
3744 ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
3745 #endif /* ADVANSYS_DEBUG */
3747 #ifndef ADVANSYS_ASSERT
3748 #define ASC_ASSERT(a)
3749 #else /* ADVANSYS_ASSERT */
3751 #define ASC_ASSERT(a) \
3753 if (!(a)) { \
3754 printk("ASC_ASSERT() Failure: file %s, line %d\n", \
3755 __FILE__, __LINE__); \
3759 #endif /* ADVANSYS_ASSERT */
3763 * --- Driver Structures
3766 #ifdef ADVANSYS_STATS
3768 /* Per board statistics structure */
3769 struct asc_stats {
3770 /* Driver Entrypoint Statistics */
3771 ADV_DCNT queuecommand; /* # calls to advansys_queuecommand() */
3772 ADV_DCNT reset; /* # calls to advansys_eh_bus_reset() */
3773 ADV_DCNT biosparam; /* # calls to advansys_biosparam() */
3774 ADV_DCNT interrupt; /* # advansys_interrupt() calls */
3775 ADV_DCNT callback; /* # calls to asc/adv_isr_callback() */
3776 ADV_DCNT done; /* # calls to request's scsi_done function */
3777 ADV_DCNT build_error; /* # asc/adv_build_req() ASC_ERROR returns. */
3778 ADV_DCNT adv_build_noreq; /* # adv_build_req() adv_req_t alloc. fail. */
3779 ADV_DCNT adv_build_nosg; /* # adv_build_req() adv_sgblk_t alloc. fail. */
3780 /* AscExeScsiQueue()/AdvExeScsiQueue() Statistics */
3781 ADV_DCNT exe_noerror; /* # ASC_NOERROR returns. */
3782 ADV_DCNT exe_busy; /* # ASC_BUSY returns. */
3783 ADV_DCNT exe_error; /* # ASC_ERROR returns. */
3784 ADV_DCNT exe_unknown; /* # unknown returns. */
3785 /* Data Transfer Statistics */
3786 ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */
3787 ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */
3788 ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */
3789 ADV_DCNT sg_elem; /* # scatter-gather elements */
3790 ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */
3792 #endif /* ADVANSYS_STATS */
3795 * Request queuing structure
3797 typedef struct asc_queue {
3798 ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */
3799 REQP q_first[ADV_MAX_TID+1]; /* first queued request */
3800 REQP q_last[ADV_MAX_TID+1]; /* last queued request */
3801 #ifdef ADVANSYS_STATS
3802 short q_cur_cnt[ADV_MAX_TID+1]; /* current queue count */
3803 short q_max_cnt[ADV_MAX_TID+1]; /* maximum queue count */
3804 ADV_DCNT q_tot_cnt[ADV_MAX_TID+1]; /* total enqueue count */
3805 ADV_DCNT q_tot_tim[ADV_MAX_TID+1]; /* total time queued */
3806 ushort q_max_tim[ADV_MAX_TID+1]; /* maximum time queued */
3807 ushort q_min_tim[ADV_MAX_TID+1]; /* minimum time queued */
3808 #endif /* ADVANSYS_STATS */
3809 } asc_queue_t;
3812 * Adv Library Request Structures
3814 * The following two structures are used to process Wide Board requests.
3816 * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library
3817 * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the
3818 * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the
3819 * Mid-Level SCSI request structure.
3821 * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each
3822 * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux
3823 * up to 255 scatter-gather elements may be used per request or
3824 * ADV_SCSI_REQ_Q.
3826 * Both structures must be 32 byte aligned.
3828 typedef struct adv_sgblk {
3829 ADV_SG_BLOCK sg_block; /* Sgblock structure. */
3830 uchar align[32]; /* Sgblock structure padding. */
3831 struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */
3832 } adv_sgblk_t;
3834 typedef struct adv_req {
3835 ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */
3836 uchar align[32]; /* Request structure padding. */
3837 struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */
3838 adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */
3839 struct adv_req *next_reqp; /* Next Request Structure. */
3840 } adv_req_t;
3843 * Structure allocated for each board.
3845 * This structure is allocated by scsi_register() at the end
3846 * of the 'Scsi_Host' structure starting at the 'hostdata'
3847 * field. It is guaranteed to be allocated from DMA-able memory.
3849 typedef struct asc_board {
3850 int id; /* Board Id */
3851 uint flags; /* Board flags */
3852 union {
3853 ASC_DVC_VAR asc_dvc_var; /* Narrow board */
3854 ADV_DVC_VAR adv_dvc_var; /* Wide board */
3855 } dvc_var;
3856 union {
3857 ASC_DVC_CFG asc_dvc_cfg; /* Narrow board */
3858 ADV_DVC_CFG adv_dvc_cfg; /* Wide board */
3859 } dvc_cfg;
3860 ushort asc_n_io_port; /* Number I/O ports. */
3861 asc_queue_t active; /* Active command queue */
3862 asc_queue_t waiting; /* Waiting command queue */
3863 asc_queue_t done; /* Done command queue */
3864 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
3865 struct scsi_device *device[ADV_MAX_TID+1]; /* Mid-Level Scsi Device */
3866 ushort reqcnt[ADV_MAX_TID+1]; /* Starvation request count */
3867 ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */
3868 ushort queue_full_cnt[ADV_MAX_TID+1]; /* Queue full count */
3869 union {
3870 ASCEEP_CONFIG asc_eep; /* Narrow EEPROM config. */
3871 ADVEEP_3550_CONFIG adv_3550_eep; /* 3550 EEPROM config. */
3872 ADVEEP_38C0800_CONFIG adv_38C0800_eep; /* 38C0800 EEPROM config. */
3873 ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */
3874 } eep_config;
3875 ulong last_reset; /* Saved last reset time */
3876 spinlock_t lock; /* Board spinlock */
3877 #ifdef CONFIG_PROC_FS
3878 /* /proc/scsi/advansys/[0...] */
3879 char *prtbuf; /* /proc print buffer */
3880 #endif /* CONFIG_PROC_FS */
3881 #ifdef ADVANSYS_STATS
3882 struct asc_stats asc_stats; /* Board statistics */
3883 #endif /* ADVANSYS_STATS */
3885 * The following fields are used only for Narrow Boards.
3887 /* The following three structures must be in DMA-able memory. */
3888 ASC_SCSI_REQ_Q scsireqq;
3889 ASC_CAP_INFO cap_info;
3890 ASC_SCSI_INQUIRY inquiry;
3891 uchar sdtr_data[ASC_MAX_TID+1]; /* SDTR information */
3893 * The following fields are used only for Wide Boards.
3895 void *ioremap_addr; /* I/O Memory remap address. */
3896 ushort ioport; /* I/O Port address. */
3897 ADV_CARR_T *orig_carrp; /* ADV_CARR_T memory block. */
3898 adv_req_t *orig_reqp; /* adv_req_t memory block. */
3899 adv_req_t *adv_reqp; /* Request structures. */
3900 adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */
3901 ushort bios_signature; /* BIOS Signature. */
3902 ushort bios_version; /* BIOS Version. */
3903 ushort bios_codeseg; /* BIOS Code Segment. */
3904 ushort bios_codelen; /* BIOS Code Segment Length. */
3905 } asc_board_t;
3908 * PCI configuration structures
3910 typedef struct _PCI_DATA_
3912 uchar type;
3913 uchar bus;
3914 uchar slot;
3915 uchar func;
3916 uchar offset;
3917 } PCI_DATA;
3919 typedef struct _PCI_DEVICE_
3921 ushort vendorID;
3922 ushort deviceID;
3923 ushort slotNumber;
3924 ushort slotFound;
3925 uchar busNumber;
3926 uchar maxBusNumber;
3927 uchar devFunc;
3928 ushort startSlot;
3929 ushort endSlot;
3930 uchar bridge;
3931 uchar type;
3932 } PCI_DEVICE;
3934 typedef struct _PCI_CONFIG_SPACE_
3936 ushort vendorID;
3937 ushort deviceID;
3938 ushort command;
3939 ushort status;
3940 uchar revision;
3941 uchar classCode[3];
3942 uchar cacheSize;
3943 uchar latencyTimer;
3944 uchar headerType;
3945 uchar bist;
3946 ADV_PADDR baseAddress[6];
3947 ushort reserved[4];
3948 ADV_PADDR optionRomAddr;
3949 ushort reserved2[4];
3950 uchar irqLine;
3951 uchar irqPin;
3952 uchar minGnt;
3953 uchar maxLatency;
3954 } PCI_CONFIG_SPACE;
3958 * --- Driver Data
3961 /* Note: All driver global data should be initialized. */
3963 /* Number of boards detected in system. */
3964 STATIC int asc_board_count = 0;
3965 STATIC struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { 0 };
3967 /* Overrun buffer used by all narrow boards. */
3968 STATIC uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 };
3971 * Global structures required to issue a command.
3973 STATIC ASC_SCSI_Q asc_scsi_q = { { 0 } };
3974 STATIC ASC_SG_HEAD asc_sg_head = { 0 };
3976 /* List of supported bus types. */
3977 STATIC ushort asc_bus[ASC_NUM_BUS] __initdata = {
3978 ASC_IS_ISA,
3979 ASC_IS_VL,
3980 ASC_IS_EISA,
3981 ASC_IS_PCI,
3985 * Used with the LILO 'advansys' option to eliminate or
3986 * limit I/O port probing at boot time, cf. advansys_setup().
3988 STATIC int asc_iopflag = ASC_FALSE;
3989 STATIC int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 };
3991 #ifdef ADVANSYS_DEBUG
3992 STATIC char *
3993 asc_bus_name[ASC_NUM_BUS] = {
3994 "ASC_IS_ISA",
3995 "ASC_IS_VL",
3996 "ASC_IS_EISA",
3997 "ASC_IS_PCI",
4000 STATIC int asc_dbglvl = 3;
4001 #endif /* ADVANSYS_DEBUG */
4003 /* Declaration for Asc Library internal data referenced by driver. */
4004 STATIC PortAddr _asc_def_iop_base[];
4008 * --- Driver Function Prototypes
4010 * advansys.h contains function prototypes for functions global to Linux.
4013 STATIC irqreturn_t advansys_interrupt(int, void *, struct pt_regs *);
4014 STATIC int advansys_slave_configure(struct scsi_device *);
4015 STATIC void asc_scsi_done_list(struct scsi_cmnd *);
4016 STATIC int asc_execute_scsi_cmnd(struct scsi_cmnd *);
4017 STATIC int asc_build_req(asc_board_t *, struct scsi_cmnd *);
4018 STATIC int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **);
4019 STATIC int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int);
4020 STATIC void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
4021 STATIC void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *);
4022 STATIC void adv_async_callback(ADV_DVC_VAR *, uchar);
4023 STATIC void asc_enqueue(asc_queue_t *, REQP, int);
4024 STATIC REQP asc_dequeue(asc_queue_t *, int);
4025 STATIC REQP asc_dequeue_list(asc_queue_t *, REQP *, int);
4026 STATIC int asc_rmqueue(asc_queue_t *, REQP);
4027 STATIC void asc_execute_queue(asc_queue_t *);
4028 #ifdef CONFIG_PROC_FS
4029 STATIC int asc_proc_copy(off_t, off_t, char *, int , char *, int);
4030 STATIC int asc_prt_board_devices(struct Scsi_Host *, char *, int);
4031 STATIC int asc_prt_adv_bios(struct Scsi_Host *, char *, int);
4032 STATIC int asc_get_eeprom_string(ushort *serialnum, uchar *cp);
4033 STATIC int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int);
4034 STATIC int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int);
4035 STATIC int asc_prt_driver_conf(struct Scsi_Host *, char *, int);
4036 STATIC int asc_prt_asc_board_info(struct Scsi_Host *, char *, int);
4037 STATIC int asc_prt_adv_board_info(struct Scsi_Host *, char *, int);
4038 STATIC int asc_prt_line(char *, int, char *fmt, ...);
4039 #endif /* CONFIG_PROC_FS */
4041 /* Declaration for Asc Library internal functions referenced by driver. */
4042 STATIC int AscFindSignature(PortAddr);
4043 STATIC ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort);
4045 /* Statistics function prototypes. */
4046 #ifdef ADVANSYS_STATS
4047 #ifdef CONFIG_PROC_FS
4048 STATIC int asc_prt_board_stats(struct Scsi_Host *, char *, int);
4049 STATIC int asc_prt_target_stats(struct Scsi_Host *, int, char *, int);
4050 #endif /* CONFIG_PROC_FS */
4051 #endif /* ADVANSYS_STATS */
4053 /* Debug function prototypes. */
4054 #ifdef ADVANSYS_DEBUG
4055 STATIC void asc_prt_scsi_host(struct Scsi_Host *);
4056 STATIC void asc_prt_scsi_cmnd(struct scsi_cmnd *);
4057 STATIC void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *);
4058 STATIC void asc_prt_asc_dvc_var(ASC_DVC_VAR *);
4059 STATIC void asc_prt_asc_scsi_q(ASC_SCSI_Q *);
4060 STATIC void asc_prt_asc_qdone_info(ASC_QDONE_INFO *);
4061 STATIC void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *);
4062 STATIC void asc_prt_adv_dvc_var(ADV_DVC_VAR *);
4063 STATIC void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *);
4064 STATIC void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *);
4065 STATIC void asc_prt_hex(char *f, uchar *, int);
4066 #endif /* ADVANSYS_DEBUG */
4070 * --- Linux 'struct scsi_host_template' and advansys_setup() Functions
4073 #ifdef CONFIG_PROC_FS
4075 * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)]
4077 * *buffer: I/O buffer
4078 * **start: if inout == FALSE pointer into buffer where user read should start
4079 * offset: current offset into a /proc/scsi/advansys/[0...] file
4080 * length: length of buffer
4081 * hostno: Scsi_Host host_no
4082 * inout: TRUE - user is writing; FALSE - user is reading
4084 * Return the number of bytes read from or written to a
4085 * /proc/scsi/advansys/[0...] file.
4087 * Note: This function uses the per board buffer 'prtbuf' which is
4088 * allocated when the board is initialized in advansys_detect(). The
4089 * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is
4090 * used to write to the buffer. The way asc_proc_copy() is written
4091 * if 'prtbuf' is too small it will not be overwritten. Instead the
4092 * user just won't get all the available statistics.
4095 advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start,
4096 off_t offset, int length, int inout)
4098 struct Scsi_Host *shp;
4099 asc_board_t *boardp;
4100 int i;
4101 char *cp;
4102 int cplen;
4103 int cnt;
4104 int totcnt;
4105 int leftlen;
4106 char *curbuf;
4107 off_t advoffset;
4108 #ifdef ADVANSYS_STATS
4109 int tgt_id;
4110 #endif /* ADVANSYS_STATS */
4112 ASC_DBG(1, "advansys_proc_info: begin\n");
4115 * User write not supported.
4117 if (inout == TRUE) {
4118 return(-ENOSYS);
4122 * User read of /proc/scsi/advansys/[0...] file.
4125 /* Find the specified board. */
4126 for (i = 0; i < asc_board_count; i++) {
4127 if (asc_host[i]->host_no == shost->host_no) {
4128 break;
4131 if (i == asc_board_count) {
4132 return(-ENOENT);
4135 shp = asc_host[i];
4136 boardp = ASC_BOARDP(shp);
4138 /* Copy read data starting at the beginning of the buffer. */
4139 *start = buffer;
4140 curbuf = buffer;
4141 advoffset = 0;
4142 totcnt = 0;
4143 leftlen = length;
4146 * Get board configuration information.
4148 * advansys_info() returns the board string from its own static buffer.
4150 cp = (char *) advansys_info(shp);
4151 strcat(cp, "\n");
4152 cplen = strlen(cp);
4153 /* Copy board information. */
4154 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4155 totcnt += cnt;
4156 leftlen -= cnt;
4157 if (leftlen == 0) {
4158 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4159 return totcnt;
4161 advoffset += cplen;
4162 curbuf += cnt;
4165 * Display Wide Board BIOS Information.
4167 if (ASC_WIDE_BOARD(boardp)) {
4168 cp = boardp->prtbuf;
4169 cplen = asc_prt_adv_bios(shp, cp, ASC_PRTBUF_SIZE);
4170 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4171 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4172 totcnt += cnt;
4173 leftlen -= cnt;
4174 if (leftlen == 0) {
4175 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4176 return totcnt;
4178 advoffset += cplen;
4179 curbuf += cnt;
4183 * Display driver information for each device attached to the board.
4185 cp = boardp->prtbuf;
4186 cplen = asc_prt_board_devices(shp, cp, ASC_PRTBUF_SIZE);
4187 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4188 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4189 totcnt += cnt;
4190 leftlen -= cnt;
4191 if (leftlen == 0) {
4192 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4193 return totcnt;
4195 advoffset += cplen;
4196 curbuf += cnt;
4199 * Display EEPROM configuration for the board.
4201 cp = boardp->prtbuf;
4202 if (ASC_NARROW_BOARD(boardp)) {
4203 cplen = asc_prt_asc_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4204 } else {
4205 cplen = asc_prt_adv_board_eeprom(shp, cp, ASC_PRTBUF_SIZE);
4207 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4208 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4209 totcnt += cnt;
4210 leftlen -= cnt;
4211 if (leftlen == 0) {
4212 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4213 return totcnt;
4215 advoffset += cplen;
4216 curbuf += cnt;
4219 * Display driver configuration and information for the board.
4221 cp = boardp->prtbuf;
4222 cplen = asc_prt_driver_conf(shp, cp, ASC_PRTBUF_SIZE);
4223 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4224 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4225 totcnt += cnt;
4226 leftlen -= cnt;
4227 if (leftlen == 0) {
4228 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4229 return totcnt;
4231 advoffset += cplen;
4232 curbuf += cnt;
4234 #ifdef ADVANSYS_STATS
4236 * Display driver statistics for the board.
4238 cp = boardp->prtbuf;
4239 cplen = asc_prt_board_stats(shp, cp, ASC_PRTBUF_SIZE);
4240 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4241 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4242 totcnt += cnt;
4243 leftlen -= cnt;
4244 if (leftlen == 0) {
4245 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4246 return totcnt;
4248 advoffset += cplen;
4249 curbuf += cnt;
4252 * Display driver statistics for each target.
4254 for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) {
4255 cp = boardp->prtbuf;
4256 cplen = asc_prt_target_stats(shp, tgt_id, cp, ASC_PRTBUF_SIZE);
4257 ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE);
4258 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4259 totcnt += cnt;
4260 leftlen -= cnt;
4261 if (leftlen == 0) {
4262 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4263 return totcnt;
4265 advoffset += cplen;
4266 curbuf += cnt;
4268 #endif /* ADVANSYS_STATS */
4271 * Display Asc Library dynamic configuration information
4272 * for the board.
4274 cp = boardp->prtbuf;
4275 if (ASC_NARROW_BOARD(boardp)) {
4276 cplen = asc_prt_asc_board_info(shp, cp, ASC_PRTBUF_SIZE);
4277 } else {
4278 cplen = asc_prt_adv_board_info(shp, cp, ASC_PRTBUF_SIZE);
4280 ASC_ASSERT(cplen < ASC_PRTBUF_SIZE);
4281 cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
4282 totcnt += cnt;
4283 leftlen -= cnt;
4284 if (leftlen == 0) {
4285 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4286 return totcnt;
4288 advoffset += cplen;
4289 curbuf += cnt;
4291 ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
4293 return totcnt;
4295 #endif /* CONFIG_PROC_FS */
4298 * advansys_detect()
4300 * Detect function for AdvanSys adapters.
4302 * Argument is a pointer to the host driver's scsi_hosts entry.
4304 * Return number of adapters found.
4306 * Note: Because this function is called during system initialization
4307 * it must not call SCSI mid-level functions including scsi_malloc()
4308 * and scsi_free().
4310 int __init
4311 advansys_detect(struct scsi_host_template *tpnt)
4313 static int detect_called = ASC_FALSE;
4314 int iop;
4315 int bus;
4316 struct Scsi_Host *shp = NULL;
4317 asc_board_t *boardp = NULL;
4318 ASC_DVC_VAR *asc_dvc_varp = NULL;
4319 ADV_DVC_VAR *adv_dvc_varp = NULL;
4320 adv_sgblk_t *sgp = NULL;
4321 int ioport = 0;
4322 int share_irq = FALSE;
4323 int iolen = 0;
4324 struct device *dev = NULL;
4325 #ifdef CONFIG_PCI
4326 int pci_init_search = 0;
4327 struct pci_dev *pci_devicep[ASC_NUM_BOARD_SUPPORTED];
4328 int pci_card_cnt_max = 0;
4329 int pci_card_cnt = 0;
4330 struct pci_dev *pci_devp = NULL;
4331 int pci_device_id_cnt = 0;
4332 unsigned int pci_device_id[ASC_PCI_DEVICE_ID_CNT] = {
4333 ASC_PCI_DEVICE_ID_1100,
4334 ASC_PCI_DEVICE_ID_1200,
4335 ASC_PCI_DEVICE_ID_1300,
4336 ASC_PCI_DEVICE_ID_2300,
4337 ASC_PCI_DEVICE_ID_2500,
4338 ASC_PCI_DEVICE_ID_2700
4340 ADV_PADDR pci_memory_address;
4341 #endif /* CONFIG_PCI */
4342 int warn_code, err_code;
4343 int ret;
4345 if (detect_called == ASC_FALSE) {
4346 detect_called = ASC_TRUE;
4347 } else {
4348 printk("AdvanSys SCSI: advansys_detect() multiple calls ignored\n");
4349 return 0;
4352 ASC_DBG(1, "advansys_detect: begin\n");
4354 asc_board_count = 0;
4357 * If I/O port probing has been modified, then verify and
4358 * clean-up the 'asc_ioport' list.
4360 if (asc_iopflag == ASC_TRUE) {
4361 for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
4362 ASC_DBG2(1, "advansys_detect: asc_ioport[%d] 0x%x\n",
4363 ioport, asc_ioport[ioport]);
4364 if (asc_ioport[ioport] != 0) {
4365 for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX; iop++) {
4366 if (_asc_def_iop_base[iop] == asc_ioport[ioport]) {
4367 break;
4370 if (iop == ASC_IOADR_TABLE_MAX_IX) {
4371 printk(
4372 "AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
4373 asc_ioport[ioport]);
4374 asc_ioport[ioport] = 0;
4378 ioport = 0;
4381 for (bus = 0; bus < ASC_NUM_BUS; bus++) {
4383 ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
4384 bus, asc_bus_name[bus]);
4385 iop = 0;
4387 while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) {
4389 ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
4390 asc_board_count);
4392 switch (asc_bus[bus]) {
4393 case ASC_IS_ISA:
4394 case ASC_IS_VL:
4395 #ifdef CONFIG_ISA
4396 if (asc_iopflag == ASC_FALSE) {
4397 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4398 } else {
4400 * ISA and VL I/O port scanning has either been
4401 * eliminated or limited to selected ports on
4402 * the LILO command line, /etc/lilo.conf, or
4403 * by setting variables when the module was loaded.
4405 ASC_DBG(1, "advansys_detect: I/O port scanning modified\n");
4406 ioport_try_again:
4407 iop = 0;
4408 for (; ioport < ASC_NUM_IOPORT_PROBE; ioport++) {
4409 if ((iop = asc_ioport[ioport]) != 0) {
4410 break;
4413 if (iop) {
4414 ASC_DBG1(1,
4415 "advansys_detect: probing I/O port 0x%x...\n",
4416 iop);
4417 if (check_region(iop, ASC_IOADR_GAP) != 0) {
4418 printk(
4419 "AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop);
4420 /* Don't try this I/O port twice. */
4421 asc_ioport[ioport] = 0;
4422 goto ioport_try_again;
4423 } else if (AscFindSignature(iop) == ASC_FALSE) {
4424 printk(
4425 "AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop);
4426 /* Don't try this I/O port twice. */
4427 asc_ioport[ioport] = 0;
4428 goto ioport_try_again;
4429 } else {
4431 * If this isn't an ISA board, then it must be
4432 * a VL board. If currently looking an ISA
4433 * board is being looked for then try for
4434 * another ISA board in 'asc_ioport'.
4436 if (asc_bus[bus] == ASC_IS_ISA &&
4437 (AscGetChipVersion(iop, ASC_IS_ISA) &
4438 ASC_CHIP_VER_ISA_BIT) == 0) {
4440 * Don't clear 'asc_ioport[ioport]'. Try
4441 * this board again for VL. Increment
4442 * 'ioport' past this board.
4444 ioport++;
4445 goto ioport_try_again;
4449 * This board appears good, don't try the I/O port
4450 * again by clearing its value. Increment 'ioport'
4451 * for the next iteration.
4453 asc_ioport[ioport++] = 0;
4456 #endif /* CONFIG_ISA */
4457 break;
4459 case ASC_IS_EISA:
4460 #ifdef CONFIG_ISA
4461 iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
4462 #endif /* CONFIG_ISA */
4463 break;
4465 case ASC_IS_PCI:
4466 #ifdef CONFIG_PCI
4467 if (pci_init_search == 0) {
4468 int i, j;
4470 pci_init_search = 1;
4472 /* Find all PCI cards. */
4473 while (pci_device_id_cnt < ASC_PCI_DEVICE_ID_CNT) {
4474 if ((pci_devp = pci_find_device(ASC_PCI_VENDORID,
4475 pci_device_id[pci_device_id_cnt], pci_devp)) ==
4476 NULL) {
4477 pci_device_id_cnt++;
4478 } else {
4479 if (pci_enable_device(pci_devp) == 0) {
4480 pci_devicep[pci_card_cnt_max++] = pci_devp;
4486 * Sort PCI cards in ascending order by PCI Bus, Slot,
4487 * and Device Number.
4489 for (i = 0; i < pci_card_cnt_max - 1; i++)
4491 for (j = i + 1; j < pci_card_cnt_max; j++) {
4492 if ((pci_devicep[j]->bus->number <
4493 pci_devicep[i]->bus->number) ||
4494 ((pci_devicep[j]->bus->number ==
4495 pci_devicep[i]->bus->number) &&
4496 (pci_devicep[j]->devfn <
4497 pci_devicep[i]->devfn))) {
4498 pci_devp = pci_devicep[i];
4499 pci_devicep[i] = pci_devicep[j];
4500 pci_devicep[j] = pci_devp;
4505 pci_card_cnt = 0;
4506 } else {
4507 pci_card_cnt++;
4510 if (pci_card_cnt == pci_card_cnt_max) {
4511 iop = 0;
4512 } else {
4513 pci_devp = pci_devicep[pci_card_cnt];
4515 ASC_DBG2(2,
4516 "advansys_detect: devfn %d, bus number %d\n",
4517 pci_devp->devfn, pci_devp->bus->number);
4518 iop = pci_resource_start(pci_devp, 0);
4519 ASC_DBG2(1,
4520 "advansys_detect: vendorID %X, deviceID %X\n",
4521 pci_devp->vendor, pci_devp->device);
4522 ASC_DBG2(2, "advansys_detect: iop %X, irqLine %d\n",
4523 iop, pci_devp->irq);
4525 if(pci_devp)
4526 dev = &pci_devp->dev;
4528 #endif /* CONFIG_PCI */
4529 break;
4531 default:
4532 ASC_PRINT1("advansys_detect: unknown bus type: %d\n",
4533 asc_bus[bus]);
4534 break;
4536 ASC_DBG1(1, "advansys_detect: iop 0x%x\n", iop);
4539 * Adapter not found, try next bus type.
4541 if (iop == 0) {
4542 break;
4546 * Adapter found.
4548 * Register the adapter, get its configuration, and
4549 * initialize it.
4551 ASC_DBG(2, "advansys_detect: scsi_register()\n");
4552 shp = scsi_register(tpnt, sizeof(asc_board_t));
4554 if (shp == NULL) {
4555 continue;
4558 /* Save a pointer to the Scsi_Host of each board found. */
4559 asc_host[asc_board_count++] = shp;
4561 /* Initialize private per board data */
4562 boardp = ASC_BOARDP(shp);
4563 memset(boardp, 0, sizeof(asc_board_t));
4564 boardp->id = asc_board_count - 1;
4566 /* Initialize spinlock. */
4567 spin_lock_init(&boardp->lock);
4570 * Handle both narrow and wide boards.
4572 * If a Wide board was detected, set the board structure
4573 * wide board flag. Set-up the board structure based on
4574 * the board type.
4576 #ifdef CONFIG_PCI
4577 if (asc_bus[bus] == ASC_IS_PCI &&
4578 (pci_devp->device == ASC_PCI_DEVICE_ID_2300 ||
4579 pci_devp->device == ASC_PCI_DEVICE_ID_2500 ||
4580 pci_devp->device == ASC_PCI_DEVICE_ID_2700))
4582 boardp->flags |= ASC_IS_WIDE_BOARD;
4584 #endif /* CONFIG_PCI */
4586 if (ASC_NARROW_BOARD(boardp)) {
4587 ASC_DBG(1, "advansys_detect: narrow board\n");
4588 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
4589 asc_dvc_varp->bus_type = asc_bus[bus];
4590 asc_dvc_varp->drv_ptr = boardp;
4591 asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg;
4592 asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0];
4593 asc_dvc_varp->iop_base = iop;
4594 asc_dvc_varp->isr_callback = asc_isr_callback;
4595 } else {
4596 ASC_DBG(1, "advansys_detect: wide board\n");
4597 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
4598 adv_dvc_varp->drv_ptr = boardp;
4599 adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg;
4600 adv_dvc_varp->isr_callback = adv_isr_callback;
4601 adv_dvc_varp->async_callback = adv_async_callback;
4602 #ifdef CONFIG_PCI
4603 if (pci_devp->device == ASC_PCI_DEVICE_ID_2300)
4605 ASC_DBG(1, "advansys_detect: ASC-3550\n");
4606 adv_dvc_varp->chip_type = ADV_CHIP_ASC3550;
4607 } else if (pci_devp->device == ASC_PCI_DEVICE_ID_2500)
4609 ASC_DBG(1, "advansys_detect: ASC-38C0800\n");
4610 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800;
4611 } else
4613 ASC_DBG(1, "advansys_detect: ASC-38C1600\n");
4614 adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600;
4616 #endif /* CONFIG_PCI */
4619 * Map the board's registers into virtual memory for
4620 * PCI slave access. Only memory accesses are used to
4621 * access the board's registers.
4623 * Note: The PCI register base address is not always
4624 * page aligned, but the address passed to ioremap()
4625 * must be page aligned. It is guaranteed that the
4626 * PCI register base address will not cross a page
4627 * boundary.
4629 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
4631 iolen = ADV_3550_IOLEN;
4632 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
4634 iolen = ADV_38C0800_IOLEN;
4635 } else
4637 iolen = ADV_38C1600_IOLEN;
4639 #ifdef CONFIG_PCI
4640 pci_memory_address = pci_resource_start(pci_devp, 1);
4641 ASC_DBG1(1, "advansys_detect: pci_memory_address: 0x%lx\n",
4642 (ulong) pci_memory_address);
4643 if ((boardp->ioremap_addr =
4644 ioremap(pci_memory_address & PAGE_MASK,
4645 PAGE_SIZE)) == 0) {
4646 ASC_PRINT3(
4647 "advansys_detect: board %d: ioremap(%x, %d) returned NULL\n",
4648 boardp->id, pci_memory_address, iolen);
4649 scsi_unregister(shp);
4650 asc_board_count--;
4651 continue;
4653 ASC_DBG1(1, "advansys_detect: ioremap_addr: 0x%lx\n",
4654 (ulong) boardp->ioremap_addr);
4655 adv_dvc_varp->iop_base = (AdvPortAddr)
4656 (boardp->ioremap_addr +
4657 (pci_memory_address - (pci_memory_address & PAGE_MASK)));
4658 ASC_DBG1(1, "advansys_detect: iop_base: 0x%lx\n",
4659 adv_dvc_varp->iop_base);
4660 #endif /* CONFIG_PCI */
4663 * Even though it isn't used to access wide boards, other
4664 * than for the debug line below, save I/O Port address so
4665 * that it can be reported.
4667 boardp->ioport = iop;
4669 ASC_DBG2(1,
4670 "advansys_detect: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n",
4671 (ushort) inp(iop + 1), (ushort) inpw(iop));
4674 #ifdef CONFIG_PROC_FS
4676 * Allocate buffer for printing information from
4677 * /proc/scsi/advansys/[0...].
4679 if ((boardp->prtbuf =
4680 kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) {
4681 ASC_PRINT3(
4682 "advansys_detect: board %d: kmalloc(%d, %d) returned NULL\n",
4683 boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC);
4684 scsi_unregister(shp);
4685 asc_board_count--;
4686 continue;
4688 #endif /* CONFIG_PROC_FS */
4690 if (ASC_NARROW_BOARD(boardp)) {
4691 asc_dvc_varp->cfg->dev = dev;
4693 * Set the board bus type and PCI IRQ before
4694 * calling AscInitGetConfig().
4696 switch (asc_dvc_varp->bus_type) {
4697 #ifdef CONFIG_ISA
4698 case ASC_IS_ISA:
4699 shp->unchecked_isa_dma = TRUE;
4700 share_irq = FALSE;
4701 break;
4702 case ASC_IS_VL:
4703 shp->unchecked_isa_dma = FALSE;
4704 share_irq = FALSE;
4705 break;
4706 case ASC_IS_EISA:
4707 shp->unchecked_isa_dma = FALSE;
4708 share_irq = TRUE;
4709 break;
4710 #endif /* CONFIG_ISA */
4711 #ifdef CONFIG_PCI
4712 case ASC_IS_PCI:
4713 shp->irq = asc_dvc_varp->irq_no = pci_devp->irq;
4714 asc_dvc_varp->cfg->pci_slot_info =
4715 ASC_PCI_MKID(pci_devp->bus->number,
4716 PCI_SLOT(pci_devp->devfn),
4717 PCI_FUNC(pci_devp->devfn));
4718 shp->unchecked_isa_dma = FALSE;
4719 share_irq = TRUE;
4720 break;
4721 #endif /* CONFIG_PCI */
4722 default:
4723 ASC_PRINT2(
4724 "advansys_detect: board %d: unknown adapter type: %d\n",
4725 boardp->id, asc_dvc_varp->bus_type);
4726 shp->unchecked_isa_dma = TRUE;
4727 share_irq = FALSE;
4728 break;
4730 } else {
4731 adv_dvc_varp->cfg->dev = dev;
4733 * For Wide boards set PCI information before calling
4734 * AdvInitGetConfig().
4736 #ifdef CONFIG_PCI
4737 shp->irq = adv_dvc_varp->irq_no = pci_devp->irq;
4738 adv_dvc_varp->cfg->pci_slot_info =
4739 ASC_PCI_MKID(pci_devp->bus->number,
4740 PCI_SLOT(pci_devp->devfn),
4741 PCI_FUNC(pci_devp->devfn));
4742 shp->unchecked_isa_dma = FALSE;
4743 share_irq = TRUE;
4744 #endif /* CONFIG_PCI */
4748 * Read the board configuration.
4750 if (ASC_NARROW_BOARD(boardp)) {
4752 * NOTE: AscInitGetConfig() may change the board's
4753 * bus_type value. The asc_bus[bus] value should no
4754 * longer be used. If the bus_type field must be
4755 * referenced only use the bit-wise AND operator "&".
4757 ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
4758 switch(ret = AscInitGetConfig(asc_dvc_varp)) {
4759 case 0: /* No error */
4760 break;
4761 case ASC_WARN_IO_PORT_ROTATE:
4762 ASC_PRINT1(
4763 "AscInitGetConfig: board %d: I/O port address modified\n",
4764 boardp->id);
4765 break;
4766 case ASC_WARN_AUTO_CONFIG:
4767 ASC_PRINT1(
4768 "AscInitGetConfig: board %d: I/O port increment switch enabled\n",
4769 boardp->id);
4770 break;
4771 case ASC_WARN_EEPROM_CHKSUM:
4772 ASC_PRINT1(
4773 "AscInitGetConfig: board %d: EEPROM checksum error\n",
4774 boardp->id);
4775 break;
4776 case ASC_WARN_IRQ_MODIFIED:
4777 ASC_PRINT1(
4778 "AscInitGetConfig: board %d: IRQ modified\n",
4779 boardp->id);
4780 break;
4781 case ASC_WARN_CMD_QNG_CONFLICT:
4782 ASC_PRINT1(
4783 "AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n",
4784 boardp->id);
4785 break;
4786 default:
4787 ASC_PRINT2(
4788 "AscInitGetConfig: board %d: unknown warning: 0x%x\n",
4789 boardp->id, ret);
4790 break;
4792 if ((err_code = asc_dvc_varp->err_code) != 0) {
4793 ASC_PRINT3(
4794 "AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
4795 boardp->id, asc_dvc_varp->init_state,
4796 asc_dvc_varp->err_code);
4798 } else {
4799 ASC_DBG(2, "advansys_detect: AdvInitGetConfig()\n");
4800 if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) {
4801 ASC_PRINT2("AdvInitGetConfig: board %d: warning: 0x%x\n",
4802 boardp->id, ret);
4804 if ((err_code = adv_dvc_varp->err_code) != 0) {
4805 ASC_PRINT2(
4806 "AdvInitGetConfig: board %d error: err_code 0x%x\n",
4807 boardp->id, adv_dvc_varp->err_code);
4811 if (err_code != 0) {
4812 #ifdef CONFIG_PROC_FS
4813 kfree(boardp->prtbuf);
4814 #endif /* CONFIG_PROC_FS */
4815 scsi_unregister(shp);
4816 asc_board_count--;
4817 continue;
4821 * Save the EEPROM configuration so that it can be displayed
4822 * from /proc/scsi/advansys/[0...].
4824 if (ASC_NARROW_BOARD(boardp)) {
4826 ASCEEP_CONFIG *ep;
4829 * Set the adapter's target id bit in the 'init_tidmask' field.
4831 boardp->init_tidmask |=
4832 ADV_TID_TO_TIDMASK(asc_dvc_varp->cfg->chip_scsi_id);
4835 * Save EEPROM settings for the board.
4837 ep = &boardp->eep_config.asc_eep;
4839 ep->init_sdtr = asc_dvc_varp->cfg->sdtr_enable;
4840 ep->disc_enable = asc_dvc_varp->cfg->disc_enable;
4841 ep->use_cmd_qng = asc_dvc_varp->cfg->cmd_qng_enabled;
4842 ASC_EEP_SET_DMA_SPD(ep, asc_dvc_varp->cfg->isa_dma_speed);
4843 ep->start_motor = asc_dvc_varp->start_motor;
4844 ep->cntl = asc_dvc_varp->dvc_cntl;
4845 ep->no_scam = asc_dvc_varp->no_scam;
4846 ep->max_total_qng = asc_dvc_varp->max_total_qng;
4847 ASC_EEP_SET_CHIP_ID(ep, asc_dvc_varp->cfg->chip_scsi_id);
4848 /* 'max_tag_qng' is set to the same value for every device. */
4849 ep->max_tag_qng = asc_dvc_varp->cfg->max_tag_qng[0];
4850 ep->adapter_info[0] = asc_dvc_varp->cfg->adapter_info[0];
4851 ep->adapter_info[1] = asc_dvc_varp->cfg->adapter_info[1];
4852 ep->adapter_info[2] = asc_dvc_varp->cfg->adapter_info[2];
4853 ep->adapter_info[3] = asc_dvc_varp->cfg->adapter_info[3];
4854 ep->adapter_info[4] = asc_dvc_varp->cfg->adapter_info[4];
4855 ep->adapter_info[5] = asc_dvc_varp->cfg->adapter_info[5];
4858 * Modify board configuration.
4860 ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n");
4861 switch (ret = AscInitSetConfig(asc_dvc_varp)) {
4862 case 0: /* No error. */
4863 break;
4864 case ASC_WARN_IO_PORT_ROTATE:
4865 ASC_PRINT1(
4866 "AscInitSetConfig: board %d: I/O port address modified\n",
4867 boardp->id);
4868 break;
4869 case ASC_WARN_AUTO_CONFIG:
4870 ASC_PRINT1(
4871 "AscInitSetConfig: board %d: I/O port increment switch enabled\n",
4872 boardp->id);
4873 break;
4874 case ASC_WARN_EEPROM_CHKSUM:
4875 ASC_PRINT1(
4876 "AscInitSetConfig: board %d: EEPROM checksum error\n",
4877 boardp->id);
4878 break;
4879 case ASC_WARN_IRQ_MODIFIED:
4880 ASC_PRINT1(
4881 "AscInitSetConfig: board %d: IRQ modified\n",
4882 boardp->id);
4883 break;
4884 case ASC_WARN_CMD_QNG_CONFLICT:
4885 ASC_PRINT1(
4886 "AscInitSetConfig: board %d: tag queuing w/o disconnects\n",
4887 boardp->id);
4888 break;
4889 default:
4890 ASC_PRINT2(
4891 "AscInitSetConfig: board %d: unknown warning: 0x%x\n",
4892 boardp->id, ret);
4893 break;
4895 if (asc_dvc_varp->err_code != 0) {
4896 ASC_PRINT3(
4897 "AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
4898 boardp->id, asc_dvc_varp->init_state,
4899 asc_dvc_varp->err_code);
4900 #ifdef CONFIG_PROC_FS
4901 kfree(boardp->prtbuf);
4902 #endif /* CONFIG_PROC_FS */
4903 scsi_unregister(shp);
4904 asc_board_count--;
4905 continue;
4909 * Finish initializing the 'Scsi_Host' structure.
4911 /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
4912 if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) {
4913 shp->irq = asc_dvc_varp->irq_no;
4915 } else {
4916 ADVEEP_3550_CONFIG *ep_3550;
4917 ADVEEP_38C0800_CONFIG *ep_38C0800;
4918 ADVEEP_38C1600_CONFIG *ep_38C1600;
4921 * Save Wide EEP Configuration Information.
4923 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
4925 ep_3550 = &boardp->eep_config.adv_3550_eep;
4927 ep_3550->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
4928 ep_3550->max_host_qng = adv_dvc_varp->max_host_qng;
4929 ep_3550->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
4930 ep_3550->termination = adv_dvc_varp->cfg->termination;
4931 ep_3550->disc_enable = adv_dvc_varp->cfg->disc_enable;
4932 ep_3550->bios_ctrl = adv_dvc_varp->bios_ctrl;
4933 ep_3550->wdtr_able = adv_dvc_varp->wdtr_able;
4934 ep_3550->sdtr_able = adv_dvc_varp->sdtr_able;
4935 ep_3550->ultra_able = adv_dvc_varp->ultra_able;
4936 ep_3550->tagqng_able = adv_dvc_varp->tagqng_able;
4937 ep_3550->start_motor = adv_dvc_varp->start_motor;
4938 ep_3550->scsi_reset_delay = adv_dvc_varp->scsi_reset_wait;
4939 ep_3550->serial_number_word1 =
4940 adv_dvc_varp->cfg->serial1;
4941 ep_3550->serial_number_word2 =
4942 adv_dvc_varp->cfg->serial2;
4943 ep_3550->serial_number_word3 =
4944 adv_dvc_varp->cfg->serial3;
4945 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
4947 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
4949 ep_38C0800->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
4950 ep_38C0800->max_host_qng = adv_dvc_varp->max_host_qng;
4951 ep_38C0800->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
4952 ep_38C0800->termination_lvd =
4953 adv_dvc_varp->cfg->termination;
4954 ep_38C0800->disc_enable = adv_dvc_varp->cfg->disc_enable;
4955 ep_38C0800->bios_ctrl = adv_dvc_varp->bios_ctrl;
4956 ep_38C0800->wdtr_able = adv_dvc_varp->wdtr_able;
4957 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
4958 ep_38C0800->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
4959 ep_38C0800->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
4960 ep_38C0800->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
4961 ep_38C0800->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
4962 ep_38C0800->tagqng_able = adv_dvc_varp->tagqng_able;
4963 ep_38C0800->start_motor = adv_dvc_varp->start_motor;
4964 ep_38C0800->scsi_reset_delay =
4965 adv_dvc_varp->scsi_reset_wait;
4966 ep_38C0800->serial_number_word1 =
4967 adv_dvc_varp->cfg->serial1;
4968 ep_38C0800->serial_number_word2 =
4969 adv_dvc_varp->cfg->serial2;
4970 ep_38C0800->serial_number_word3 =
4971 adv_dvc_varp->cfg->serial3;
4972 } else
4974 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
4976 ep_38C1600->adapter_scsi_id = adv_dvc_varp->chip_scsi_id;
4977 ep_38C1600->max_host_qng = adv_dvc_varp->max_host_qng;
4978 ep_38C1600->max_dvc_qng = adv_dvc_varp->max_dvc_qng;
4979 ep_38C1600->termination_lvd =
4980 adv_dvc_varp->cfg->termination;
4981 ep_38C1600->disc_enable = adv_dvc_varp->cfg->disc_enable;
4982 ep_38C1600->bios_ctrl = adv_dvc_varp->bios_ctrl;
4983 ep_38C1600->wdtr_able = adv_dvc_varp->wdtr_able;
4984 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
4985 ep_38C1600->sdtr_speed1 = adv_dvc_varp->sdtr_speed1;
4986 ep_38C1600->sdtr_speed2 = adv_dvc_varp->sdtr_speed2;
4987 ep_38C1600->sdtr_speed3 = adv_dvc_varp->sdtr_speed3;
4988 ep_38C1600->sdtr_speed4 = adv_dvc_varp->sdtr_speed4;
4989 ep_38C1600->tagqng_able = adv_dvc_varp->tagqng_able;
4990 ep_38C1600->start_motor = adv_dvc_varp->start_motor;
4991 ep_38C1600->scsi_reset_delay =
4992 adv_dvc_varp->scsi_reset_wait;
4993 ep_38C1600->serial_number_word1 =
4994 adv_dvc_varp->cfg->serial1;
4995 ep_38C1600->serial_number_word2 =
4996 adv_dvc_varp->cfg->serial2;
4997 ep_38C1600->serial_number_word3 =
4998 adv_dvc_varp->cfg->serial3;
5002 * Set the adapter's target id bit in the 'init_tidmask' field.
5004 boardp->init_tidmask |=
5005 ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id);
5008 * Finish initializing the 'Scsi_Host' structure.
5010 shp->irq = adv_dvc_varp->irq_no;
5014 * Channels are numbered beginning with 0. For AdvanSys one host
5015 * structure supports one channel. Multi-channel boards have a
5016 * separate host structure for each channel.
5018 shp->max_channel = 0;
5019 if (ASC_NARROW_BOARD(boardp)) {
5020 shp->max_id = ASC_MAX_TID + 1;
5021 shp->max_lun = ASC_MAX_LUN + 1;
5023 shp->io_port = asc_dvc_varp->iop_base;
5024 boardp->asc_n_io_port = ASC_IOADR_GAP;
5025 shp->this_id = asc_dvc_varp->cfg->chip_scsi_id;
5027 /* Set maximum number of queues the adapter can handle. */
5028 shp->can_queue = asc_dvc_varp->max_total_qng;
5029 } else {
5030 shp->max_id = ADV_MAX_TID + 1;
5031 shp->max_lun = ADV_MAX_LUN + 1;
5034 * Save the I/O Port address and length even though
5035 * I/O ports are not used to access Wide boards.
5036 * Instead the Wide boards are accessed with
5037 * PCI Memory Mapped I/O.
5039 shp->io_port = iop;
5040 boardp->asc_n_io_port = iolen;
5042 shp->this_id = adv_dvc_varp->chip_scsi_id;
5044 /* Set maximum number of queues the adapter can handle. */
5045 shp->can_queue = adv_dvc_varp->max_host_qng;
5049 * 'n_io_port' currently is one byte.
5051 * Set a value to 'n_io_port', but never referenced it because
5052 * it may be truncated.
5054 shp->n_io_port = boardp->asc_n_io_port <= 255 ?
5055 boardp->asc_n_io_port : 255;
5058 * Following v1.3.89, 'cmd_per_lun' is no longer needed
5059 * and should be set to zero.
5061 * But because of a bug introduced in v1.3.89 if the driver is
5062 * compiled as a module and 'cmd_per_lun' is zero, the Mid-Level
5063 * SCSI function 'allocate_device' will panic. To allow the driver
5064 * to work as a module in these kernels set 'cmd_per_lun' to 1.
5066 * Note: This is wrong. cmd_per_lun should be set to the depth
5067 * you want on untagged devices always.
5068 #ifdef MODULE
5070 shp->cmd_per_lun = 1;
5071 /* #else
5072 shp->cmd_per_lun = 0;
5073 #endif */
5076 * Set the maximum number of scatter-gather elements the
5077 * adapter can handle.
5079 if (ASC_NARROW_BOARD(boardp)) {
5081 * Allow two commands with 'sg_tablesize' scatter-gather
5082 * elements to be executed simultaneously. This value is
5083 * the theoretical hardware limit. It may be decreased
5084 * below.
5086 shp->sg_tablesize =
5087 (((asc_dvc_varp->max_total_qng - 2) / 2) *
5088 ASC_SG_LIST_PER_Q) + 1;
5089 } else {
5090 shp->sg_tablesize = ADV_MAX_SG_LIST;
5094 * The value of 'sg_tablesize' can not exceed the SCSI
5095 * mid-level driver definition of SG_ALL. SG_ALL also
5096 * must not be exceeded, because it is used to define the
5097 * size of the scatter-gather table in 'struct asc_sg_head'.
5099 if (shp->sg_tablesize > SG_ALL) {
5100 shp->sg_tablesize = SG_ALL;
5103 ASC_DBG1(1, "advansys_detect: sg_tablesize: %d\n",
5104 shp->sg_tablesize);
5106 /* BIOS start address. */
5107 if (ASC_NARROW_BOARD(boardp)) {
5108 shp->base =
5109 ((ulong) AscGetChipBiosAddress(
5110 asc_dvc_varp->iop_base,
5111 asc_dvc_varp->bus_type));
5112 } else {
5114 * Fill-in BIOS board variables. The Wide BIOS saves
5115 * information in LRAM that is used by the driver.
5117 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_SIGNATURE,
5118 boardp->bios_signature);
5119 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_VERSION,
5120 boardp->bios_version);
5121 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODESEG,
5122 boardp->bios_codeseg);
5123 AdvReadWordLram(adv_dvc_varp->iop_base, BIOS_CODELEN,
5124 boardp->bios_codelen);
5126 ASC_DBG2(1,
5127 "advansys_detect: bios_signature 0x%x, bios_version 0x%x\n",
5128 boardp->bios_signature, boardp->bios_version);
5130 ASC_DBG2(1,
5131 "advansys_detect: bios_codeseg 0x%x, bios_codelen 0x%x\n",
5132 boardp->bios_codeseg, boardp->bios_codelen);
5135 * If the BIOS saved a valid signature, then fill in
5136 * the BIOS code segment base address.
5138 if (boardp->bios_signature == 0x55AA) {
5140 * Convert x86 realmode code segment to a linear
5141 * address by shifting left 4.
5143 shp->base = ((ulong) boardp->bios_codeseg << 4);
5144 } else {
5145 shp->base = 0;
5150 * Register Board Resources - I/O Port, DMA, IRQ
5154 * Register I/O port range.
5156 * For Wide boards the I/O ports are not used to access
5157 * the board, but request the region anyway.
5159 * 'shp->n_io_port' is not referenced, because it may be truncated.
5161 ASC_DBG2(2,
5162 "advansys_detect: request_region port 0x%lx, len 0x%x\n",
5163 (ulong) shp->io_port, boardp->asc_n_io_port);
5164 if (request_region(shp->io_port, boardp->asc_n_io_port,
5165 "advansys") == NULL) {
5166 ASC_PRINT3(
5167 "advansys_detect: board %d: request_region() failed, port 0x%lx, len 0x%x\n",
5168 boardp->id, (ulong) shp->io_port, boardp->asc_n_io_port);
5169 #ifdef CONFIG_PROC_FS
5170 kfree(boardp->prtbuf);
5171 #endif /* CONFIG_PROC_FS */
5172 scsi_unregister(shp);
5173 asc_board_count--;
5174 continue;
5177 /* Register DMA Channel for Narrow boards. */
5178 shp->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */
5179 #ifdef CONFIG_ISA
5180 if (ASC_NARROW_BOARD(boardp)) {
5181 /* Register DMA channel for ISA bus. */
5182 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5183 shp->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
5184 if ((ret =
5185 request_dma(shp->dma_channel, "advansys")) != 0) {
5186 ASC_PRINT3(
5187 "advansys_detect: board %d: request_dma() %d failed %d\n",
5188 boardp->id, shp->dma_channel, ret);
5189 release_region(shp->io_port, boardp->asc_n_io_port);
5190 #ifdef CONFIG_PROC_FS
5191 kfree(boardp->prtbuf);
5192 #endif /* CONFIG_PROC_FS */
5193 scsi_unregister(shp);
5194 asc_board_count--;
5195 continue;
5197 AscEnableIsaDma(shp->dma_channel);
5200 #endif /* CONFIG_ISA */
5202 /* Register IRQ Number. */
5203 ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
5205 * If request_irq() fails with the SA_INTERRUPT flag set,
5206 * then try again without the SA_INTERRUPT flag set. This
5207 * allows IRQ sharing to work even with other drivers that
5208 * do not set the SA_INTERRUPT flag.
5210 * If SA_INTERRUPT is not set, then interrupts are enabled
5211 * before the driver interrupt function is called.
5213 if (((ret = request_irq(shp->irq, advansys_interrupt,
5214 SA_INTERRUPT | (share_irq == TRUE ? SA_SHIRQ : 0),
5215 "advansys", boardp)) != 0) &&
5216 ((ret = request_irq(shp->irq, advansys_interrupt,
5217 (share_irq == TRUE ? SA_SHIRQ : 0),
5218 "advansys", boardp)) != 0))
5220 if (ret == -EBUSY) {
5221 ASC_PRINT2(
5222 "advansys_detect: board %d: request_irq(): IRQ 0x%x already in use.\n",
5223 boardp->id, shp->irq);
5224 } else if (ret == -EINVAL) {
5225 ASC_PRINT2(
5226 "advansys_detect: board %d: request_irq(): IRQ 0x%x not valid.\n",
5227 boardp->id, shp->irq);
5228 } else {
5229 ASC_PRINT3(
5230 "advansys_detect: board %d: request_irq(): IRQ 0x%x failed with %d\n",
5231 boardp->id, shp->irq, ret);
5233 release_region(shp->io_port, boardp->asc_n_io_port);
5234 iounmap(boardp->ioremap_addr);
5235 if (shp->dma_channel != NO_ISA_DMA) {
5236 free_dma(shp->dma_channel);
5238 #ifdef CONFIG_PROC_FS
5239 kfree(boardp->prtbuf);
5240 #endif /* CONFIG_PROC_FS */
5241 scsi_unregister(shp);
5242 asc_board_count--;
5243 continue;
5247 * Initialize board RISC chip and enable interrupts.
5249 if (ASC_NARROW_BOARD(boardp)) {
5250 ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n");
5251 warn_code = AscInitAsc1000Driver(asc_dvc_varp);
5252 err_code = asc_dvc_varp->err_code;
5254 if (warn_code || err_code) {
5255 ASC_PRINT4(
5256 "advansys_detect: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n",
5257 boardp->id, asc_dvc_varp->init_state,
5258 warn_code, err_code);
5260 } else {
5261 ADV_CARR_T *carrp;
5262 int req_cnt = 0;
5263 adv_req_t *reqp = NULL;
5264 int sg_cnt = 0;
5267 * Allocate buffer carrier structures. The total size
5268 * is about 4 KB, so allocate all at once.
5270 carrp =
5271 (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC);
5272 ASC_DBG1(1, "advansys_detect: carrp 0x%lx\n", (ulong) carrp);
5274 if (carrp == NULL) {
5275 goto kmalloc_error;
5279 * Allocate up to 'max_host_qng' request structures for
5280 * the Wide board. The total size is about 16 KB, so
5281 * allocate all at once. If the allocation fails decrement
5282 * and try again.
5284 for (req_cnt = adv_dvc_varp->max_host_qng;
5285 req_cnt > 0; req_cnt--) {
5287 reqp = (adv_req_t *)
5288 kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC);
5290 ASC_DBG3(1,
5291 "advansys_detect: reqp 0x%lx, req_cnt %d, bytes %lu\n",
5292 (ulong) reqp, req_cnt,
5293 (ulong) sizeof(adv_req_t) * req_cnt);
5295 if (reqp != NULL) {
5296 break;
5299 if (reqp == NULL)
5301 goto kmalloc_error;
5305 * Allocate up to ADV_TOT_SG_BLOCK request structures for
5306 * the Wide board. Each structure is about 136 bytes.
5308 boardp->adv_sgblkp = NULL;
5309 for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
5311 sgp = (adv_sgblk_t *)
5312 kmalloc(sizeof(adv_sgblk_t), GFP_ATOMIC);
5314 if (sgp == NULL) {
5315 break;
5318 sgp->next_sgblkp = boardp->adv_sgblkp;
5319 boardp->adv_sgblkp = sgp;
5322 ASC_DBG3(1,
5323 "advansys_detect: sg_cnt %d * %u = %u bytes\n",
5324 sg_cnt, sizeof(adv_sgblk_t),
5325 (unsigned) (sizeof(adv_sgblk_t) * sg_cnt));
5328 * If no request structures or scatter-gather structures could
5329 * be allocated, then return an error. Otherwise continue with
5330 * initialization.
5332 kmalloc_error:
5333 if (carrp == NULL)
5335 ASC_PRINT1(
5336 "advansys_detect: board %d error: failed to kmalloc() carrier buffer.\n",
5337 boardp->id);
5338 err_code = ADV_ERROR;
5339 } else if (reqp == NULL) {
5340 kfree(carrp);
5341 ASC_PRINT1(
5342 "advansys_detect: board %d error: failed to kmalloc() adv_req_t buffer.\n",
5343 boardp->id);
5344 err_code = ADV_ERROR;
5345 } else if (boardp->adv_sgblkp == NULL) {
5346 kfree(carrp);
5347 kfree(reqp);
5348 ASC_PRINT1(
5349 "advansys_detect: board %d error: failed to kmalloc() adv_sgblk_t buffers.\n",
5350 boardp->id);
5351 err_code = ADV_ERROR;
5352 } else {
5354 /* Save carrier buffer pointer. */
5355 boardp->orig_carrp = carrp;
5358 * Save original pointer for kfree() in case the
5359 * driver is built as a module and can be unloaded.
5361 boardp->orig_reqp = reqp;
5363 adv_dvc_varp->carrier_buf = carrp;
5366 * Point 'adv_reqp' to the request structures and
5367 * link them together.
5369 req_cnt--;
5370 reqp[req_cnt].next_reqp = NULL;
5371 for (; req_cnt > 0; req_cnt--) {
5372 reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
5374 boardp->adv_reqp = &reqp[0];
5376 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5378 ASC_DBG(2,
5379 "advansys_detect: AdvInitAsc3550Driver()\n");
5380 warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
5381 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
5382 ASC_DBG(2,
5383 "advansys_detect: AdvInitAsc38C0800Driver()\n");
5384 warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
5385 } else {
5386 ASC_DBG(2,
5387 "advansys_detect: AdvInitAsc38C1600Driver()\n");
5388 warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
5390 err_code = adv_dvc_varp->err_code;
5392 if (warn_code || err_code) {
5393 ASC_PRINT3(
5394 "advansys_detect: board %d error: warn 0x%x, error 0x%x\n",
5395 boardp->id, warn_code, err_code);
5400 if (err_code != 0) {
5401 release_region(shp->io_port, boardp->asc_n_io_port);
5402 if (ASC_WIDE_BOARD(boardp)) {
5403 iounmap(boardp->ioremap_addr);
5404 kfree(boardp->orig_carrp);
5405 boardp->orig_carrp = NULL;
5406 if (boardp->orig_reqp) {
5407 kfree(boardp->orig_reqp);
5408 boardp->orig_reqp = boardp->adv_reqp = NULL;
5410 while ((sgp = boardp->adv_sgblkp) != NULL)
5412 boardp->adv_sgblkp = sgp->next_sgblkp;
5413 kfree(sgp);
5416 if (shp->dma_channel != NO_ISA_DMA) {
5417 free_dma(shp->dma_channel);
5419 #ifdef CONFIG_PROC_FS
5420 kfree(boardp->prtbuf);
5421 #endif /* CONFIG_PROC_FS */
5422 free_irq(shp->irq, boardp);
5423 scsi_unregister(shp);
5424 asc_board_count--;
5425 continue;
5427 ASC_DBG_PRT_SCSI_HOST(2, shp);
5431 ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count);
5432 return asc_board_count;
5436 * advansys_release()
5438 * Release resources allocated for a single AdvanSys adapter.
5441 advansys_release(struct Scsi_Host *shp)
5443 asc_board_t *boardp;
5445 ASC_DBG(1, "advansys_release: begin\n");
5446 boardp = ASC_BOARDP(shp);
5447 free_irq(shp->irq, boardp);
5448 if (shp->dma_channel != NO_ISA_DMA) {
5449 ASC_DBG(1, "advansys_release: free_dma()\n");
5450 free_dma(shp->dma_channel);
5452 release_region(shp->io_port, boardp->asc_n_io_port);
5453 if (ASC_WIDE_BOARD(boardp)) {
5454 adv_sgblk_t *sgp = NULL;
5456 iounmap(boardp->ioremap_addr);
5457 kfree(boardp->orig_carrp);
5458 boardp->orig_carrp = NULL;
5459 if (boardp->orig_reqp) {
5460 kfree(boardp->orig_reqp);
5461 boardp->orig_reqp = boardp->adv_reqp = NULL;
5463 while ((sgp = boardp->adv_sgblkp) != NULL)
5465 boardp->adv_sgblkp = sgp->next_sgblkp;
5466 kfree(sgp);
5469 #ifdef CONFIG_PROC_FS
5470 ASC_ASSERT(boardp->prtbuf != NULL);
5471 kfree(boardp->prtbuf);
5472 #endif /* CONFIG_PROC_FS */
5473 scsi_unregister(shp);
5474 ASC_DBG(1, "advansys_release: end\n");
5475 return 0;
5479 * advansys_info()
5481 * Return suitable for printing on the console with the argument
5482 * adapter's configuration information.
5484 * Note: The information line should not exceed ASC_INFO_SIZE bytes,
5485 * otherwise the static 'info' array will be overrun.
5487 const char *
5488 advansys_info(struct Scsi_Host *shp)
5490 static char info[ASC_INFO_SIZE];
5491 asc_board_t *boardp;
5492 ASC_DVC_VAR *asc_dvc_varp;
5493 ADV_DVC_VAR *adv_dvc_varp;
5494 char *busname;
5495 int iolen;
5496 char *widename = NULL;
5498 boardp = ASC_BOARDP(shp);
5499 if (ASC_NARROW_BOARD(boardp)) {
5500 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5501 ASC_DBG(1, "advansys_info: begin\n");
5502 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
5503 if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == ASC_IS_ISAPNP) {
5504 busname = "ISA PnP";
5505 } else {
5506 busname = "ISA";
5508 /* Don't reference 'shp->n_io_port'; It may be truncated. */
5509 sprintf(info,
5510 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X",
5511 ASC_VERSION, busname,
5512 (ulong) shp->io_port,
5513 (ulong) shp->io_port + boardp->asc_n_io_port - 1,
5514 shp->irq, shp->dma_channel);
5515 } else {
5516 if (asc_dvc_varp->bus_type & ASC_IS_VL) {
5517 busname = "VL";
5518 } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) {
5519 busname = "EISA";
5520 } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) {
5521 if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA)
5522 == ASC_IS_PCI_ULTRA) {
5523 busname = "PCI Ultra";
5524 } else {
5525 busname = "PCI";
5527 } else {
5528 busname = "?";
5529 ASC_PRINT2( "advansys_info: board %d: unknown bus type %d\n",
5530 boardp->id, asc_dvc_varp->bus_type);
5532 /* Don't reference 'shp->n_io_port'; It may be truncated. */
5533 sprintf(info,
5534 "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X",
5535 ASC_VERSION, busname,
5536 (ulong) shp->io_port,
5537 (ulong) shp->io_port + boardp->asc_n_io_port - 1,
5538 shp->irq);
5540 } else {
5542 * Wide Adapter Information
5544 * Memory-mapped I/O is used instead of I/O space to access
5545 * the adapter, but display the I/O Port range. The Memory
5546 * I/O address is displayed through the driver /proc file.
5548 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5549 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
5551 iolen = ADV_3550_IOLEN;
5552 widename = "Ultra-Wide";
5553 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
5555 iolen = ADV_38C0800_IOLEN;
5556 widename = "Ultra2-Wide";
5557 } else
5559 iolen = ADV_38C1600_IOLEN;
5560 widename = "Ultra3-Wide";
5562 sprintf(info, "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X",
5563 ASC_VERSION,
5564 widename,
5565 (ulong) adv_dvc_varp->iop_base,
5566 (ulong) adv_dvc_varp->iop_base + iolen - 1,
5567 shp->irq);
5569 ASC_ASSERT(strlen(info) < ASC_INFO_SIZE);
5570 ASC_DBG(1, "advansys_info: end\n");
5571 return info;
5575 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
5577 * This function always returns 0. Command return status is saved
5578 * in the 'scp' result field.
5581 advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
5583 struct Scsi_Host *shp;
5584 asc_board_t *boardp;
5585 ulong flags;
5586 struct scsi_cmnd *done_scp;
5588 shp = scp->device->host;
5589 boardp = ASC_BOARDP(shp);
5590 ASC_STATS(shp, queuecommand);
5592 /* host_lock taken by mid-level prior to call but need to protect */
5593 /* against own ISR */
5594 spin_lock_irqsave(&boardp->lock, flags);
5597 * Block new commands while handling a reset or abort request.
5599 if (boardp->flags & ASC_HOST_IN_RESET) {
5600 ASC_DBG1(1,
5601 "advansys_queuecommand: scp 0x%lx blocked for reset request\n",
5602 (ulong) scp);
5603 scp->result = HOST_BYTE(DID_RESET);
5606 * Add blocked requests to the board's 'done' queue. The queued
5607 * requests will be completed at the end of the abort or reset
5608 * handling.
5610 asc_enqueue(&boardp->done, scp, ASC_BACK);
5611 spin_unlock_irqrestore(&boardp->lock, flags);
5612 return 0;
5616 * Attempt to execute any waiting commands for the board.
5618 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
5619 ASC_DBG(1,
5620 "advansys_queuecommand: before asc_execute_queue() waiting\n");
5621 asc_execute_queue(&boardp->waiting);
5625 * Save the function pointer to Linux mid-level 'done' function
5626 * and attempt to execute the command.
5628 * If ASC_NOERROR is returned the request has been added to the
5629 * board's 'active' queue and will be completed by the interrupt
5630 * handler.
5632 * If ASC_BUSY is returned add the request to the board's per
5633 * target waiting list. This is the first time the request has
5634 * been tried. Add it to the back of the waiting list. It will be
5635 * retried later.
5637 * If an error occurred, the request will have been placed on the
5638 * board's 'done' queue and must be completed before returning.
5640 scp->scsi_done = done;
5641 switch (asc_execute_scsi_cmnd(scp)) {
5642 case ASC_NOERROR:
5643 break;
5644 case ASC_BUSY:
5645 asc_enqueue(&boardp->waiting, scp, ASC_BACK);
5646 break;
5647 case ASC_ERROR:
5648 default:
5649 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
5650 /* Interrupts could be enabled here. */
5651 asc_scsi_done_list(done_scp);
5652 break;
5654 spin_unlock_irqrestore(&boardp->lock, flags);
5656 return 0;
5660 * advansys_reset()
5662 * Reset the bus associated with the command 'scp'.
5664 * This function runs its own thread. Interrupts must be blocked but
5665 * sleeping is allowed and no locking other than for host structures is
5666 * required. Returns SUCCESS or FAILED.
5669 advansys_reset(struct scsi_cmnd *scp)
5671 struct Scsi_Host *shp;
5672 asc_board_t *boardp;
5673 ASC_DVC_VAR *asc_dvc_varp;
5674 ADV_DVC_VAR *adv_dvc_varp;
5675 ulong flags;
5676 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
5677 struct scsi_cmnd *tscp, *new_last_scp;
5678 int status;
5679 int ret = SUCCESS;
5681 ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong) scp);
5683 #ifdef ADVANSYS_STATS
5684 if (scp->device->host != NULL) {
5685 ASC_STATS(scp->device->host, reset);
5687 #endif /* ADVANSYS_STATS */
5689 if ((shp = scp->device->host) == NULL) {
5690 scp->result = HOST_BYTE(DID_ERROR);
5691 return FAILED;
5694 boardp = ASC_BOARDP(shp);
5696 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n",
5697 boardp->id);
5699 * Check for re-entrancy.
5701 spin_lock_irqsave(&boardp->lock, flags);
5702 if (boardp->flags & ASC_HOST_IN_RESET) {
5703 spin_unlock_irqrestore(&boardp->lock, flags);
5704 return FAILED;
5706 boardp->flags |= ASC_HOST_IN_RESET;
5707 spin_unlock_irqrestore(&boardp->lock, flags);
5709 if (ASC_NARROW_BOARD(boardp)) {
5711 * Narrow Board
5713 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
5716 * Reset the chip and SCSI bus.
5718 ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n");
5719 status = AscInitAsc1000Driver(asc_dvc_varp);
5721 /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */
5722 if (asc_dvc_varp->err_code) {
5723 ASC_PRINT2(
5724 "advansys_reset: board %d: SCSI bus reset error: 0x%x\n",
5725 boardp->id, asc_dvc_varp->err_code);
5726 ret = FAILED;
5727 } else if (status) {
5728 ASC_PRINT2(
5729 "advansys_reset: board %d: SCSI bus reset warning: 0x%x\n",
5730 boardp->id, status);
5731 } else {
5732 ASC_PRINT1(
5733 "advansys_reset: board %d: SCSI bus reset successful.\n",
5734 boardp->id);
5737 ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n");
5738 spin_lock_irqsave(&boardp->lock, flags);
5740 } else {
5742 * Wide Board
5744 * If the suggest reset bus flags are set, then reset the bus.
5745 * Otherwise only reset the device.
5747 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
5750 * Reset the target's SCSI bus.
5752 ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n");
5753 switch (AdvResetChipAndSB(adv_dvc_varp)) {
5754 case ASC_TRUE:
5755 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset successful.\n",
5756 boardp->id);
5757 break;
5758 case ASC_FALSE:
5759 default:
5760 ASC_PRINT1("advansys_reset: board %d: SCSI bus reset error.\n",
5761 boardp->id);
5762 ret = FAILED;
5763 break;
5765 spin_lock_irqsave(&boardp->lock, flags);
5766 (void) AdvISR(adv_dvc_varp);
5768 /* Board lock is held. */
5771 * Dequeue all board 'done' requests. A pointer to the last request
5772 * is returned in 'last_scp'.
5774 done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
5777 * Dequeue all board 'active' requests for all devices and set
5778 * the request status to DID_RESET. A pointer to the last request
5779 * is returned in 'last_scp'.
5781 if (done_scp == NULL) {
5782 done_scp = asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL);
5783 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
5784 tscp->result = HOST_BYTE(DID_RESET);
5786 } else {
5787 /* Append to 'done_scp' at the end with 'last_scp'. */
5788 ASC_ASSERT(last_scp != NULL);
5789 last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
5790 &boardp->active, &new_last_scp, ASC_TID_ALL);
5791 if (new_last_scp != NULL) {
5792 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
5793 for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
5794 tscp->result = HOST_BYTE(DID_RESET);
5796 last_scp = new_last_scp;
5801 * Dequeue all 'waiting' requests and set the request status
5802 * to DID_RESET.
5804 if (done_scp == NULL) {
5805 done_scp = asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL);
5806 for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) {
5807 tscp->result = HOST_BYTE(DID_RESET);
5809 } else {
5810 /* Append to 'done_scp' at the end with 'last_scp'. */
5811 ASC_ASSERT(last_scp != NULL);
5812 last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
5813 &boardp->waiting, &new_last_scp, ASC_TID_ALL);
5814 if (new_last_scp != NULL) {
5815 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
5816 for (tscp = REQPNEXT(last_scp); tscp; tscp = REQPNEXT(tscp)) {
5817 tscp->result = HOST_BYTE(DID_RESET);
5819 last_scp = new_last_scp;
5823 /* Save the time of the most recently completed reset. */
5824 boardp->last_reset = jiffies;
5826 /* Clear reset flag. */
5827 boardp->flags &= ~ASC_HOST_IN_RESET;
5828 spin_unlock_irqrestore(&boardp->lock, flags);
5831 * Complete all the 'done_scp' requests.
5833 if (done_scp != NULL) {
5834 asc_scsi_done_list(done_scp);
5837 ASC_DBG1(1, "advansys_reset: ret %d\n", ret);
5839 return ret;
5843 * advansys_biosparam()
5845 * Translate disk drive geometry if the "BIOS greater than 1 GB"
5846 * support is enabled for a drive.
5848 * ip (information pointer) is an int array with the following definition:
5849 * ip[0]: heads
5850 * ip[1]: sectors
5851 * ip[2]: cylinders
5854 advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev,
5855 sector_t capacity, int ip[])
5857 asc_board_t *boardp;
5859 ASC_DBG(1, "advansys_biosparam: begin\n");
5860 ASC_STATS(sdev->host, biosparam);
5861 boardp = ASC_BOARDP(sdev->host);
5862 if (ASC_NARROW_BOARD(boardp)) {
5863 if ((boardp->dvc_var.asc_dvc_var.dvc_cntl &
5864 ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) {
5865 ip[0] = 255;
5866 ip[1] = 63;
5867 } else {
5868 ip[0] = 64;
5869 ip[1] = 32;
5871 } else {
5872 if ((boardp->dvc_var.adv_dvc_var.bios_ctrl &
5873 BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) {
5874 ip[0] = 255;
5875 ip[1] = 63;
5876 } else {
5877 ip[0] = 64;
5878 ip[1] = 32;
5881 ip[2] = (unsigned long)capacity / (ip[0] * ip[1]);
5882 ASC_DBG(1, "advansys_biosparam: end\n");
5883 return 0;
5887 * advansys_setup()
5889 * This function is called from init/main.c at boot time.
5890 * It it passed LILO parameters that can be set from the
5891 * LILO command line or in /etc/lilo.conf.
5893 * It is used by the AdvanSys driver to either disable I/O
5894 * port scanning or to limit scanning to 1 - 4 I/O ports.
5895 * Regardless of the option setting EISA and PCI boards
5896 * will still be searched for and detected. This option
5897 * only affects searching for ISA and VL boards.
5899 * If ADVANSYS_DEBUG is defined the driver debug level may
5900 * be set using the 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port.
5902 * Examples:
5903 * 1. Eliminate I/O port scanning:
5904 * boot: linux advansys=
5905 * or
5906 * boot: linux advansys=0x0
5907 * 2. Limit I/O port scanning to one I/O port:
5908 * boot: linux advansys=0x110
5909 * 3. Limit I/O port scanning to four I/O ports:
5910 * boot: linux advansys=0x110,0x210,0x230,0x330
5911 * 4. If ADVANSYS_DEBUG, limit I/O port scanning to four I/O ports and
5912 * set the driver debug level to 2.
5913 * boot: linux advansys=0x110,0x210,0x230,0x330,0xdeb2
5915 * ints[0] - number of arguments
5916 * ints[1] - first argument
5917 * ints[2] - second argument
5918 * ...
5920 void __init
5921 advansys_setup(char *str, int *ints)
5923 int i;
5925 if (asc_iopflag == ASC_TRUE) {
5926 printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n");
5927 return;
5930 asc_iopflag = ASC_TRUE;
5932 if (ints[0] > ASC_NUM_IOPORT_PROBE) {
5933 #ifdef ADVANSYS_DEBUG
5934 if ((ints[0] == ASC_NUM_IOPORT_PROBE + 1) &&
5935 (ints[ASC_NUM_IOPORT_PROBE + 1] >> 4 == 0xdeb)) {
5936 asc_dbglvl = ints[ASC_NUM_IOPORT_PROBE + 1] & 0xf;
5937 } else {
5938 #endif /* ADVANSYS_DEBUG */
5939 printk("AdvanSys SCSI: only %d I/O ports accepted\n",
5940 ASC_NUM_IOPORT_PROBE);
5941 #ifdef ADVANSYS_DEBUG
5943 #endif /* ADVANSYS_DEBUG */
5946 #ifdef ADVANSYS_DEBUG
5947 ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]);
5948 for (i = 1; i < ints[0]; i++) {
5949 ASC_DBG2(1, " ints[%d] 0x%x", i, ints[i]);
5951 ASC_DBG(1, "\n");
5952 #endif /* ADVANSYS_DEBUG */
5954 for (i = 1; i <= ints[0] && i <= ASC_NUM_IOPORT_PROBE; i++) {
5955 asc_ioport[i-1] = ints[i];
5956 ASC_DBG2(1, "advansys_setup: asc_ioport[%d] 0x%x\n",
5957 i - 1, asc_ioport[i-1]);
5963 * --- Loadable Driver Support
5966 static struct scsi_host_template driver_template = {
5967 .proc_name = "advansys",
5968 #ifdef CONFIG_PROC_FS
5969 .proc_info = advansys_proc_info,
5970 #endif
5971 .name = "advansys",
5972 .detect = advansys_detect,
5973 .release = advansys_release,
5974 .info = advansys_info,
5975 .queuecommand = advansys_queuecommand,
5976 .eh_bus_reset_handler = advansys_reset,
5977 .bios_param = advansys_biosparam,
5978 .slave_configure = advansys_slave_configure,
5980 * Because the driver may control an ISA adapter 'unchecked_isa_dma'
5981 * must be set. The flag will be cleared in advansys_detect for non-ISA
5982 * adapters. Refer to the comment in scsi_module.c for more information.
5984 .unchecked_isa_dma = 1,
5986 * All adapters controlled by this driver are capable of large
5987 * scatter-gather lists. According to the mid-level SCSI documentation
5988 * this obviates any performance gain provided by setting
5989 * 'use_clustering'. But empirically while CPU utilization is increased
5990 * by enabling clustering, I/O throughput increases as well.
5992 .use_clustering = ENABLE_CLUSTERING,
5994 #include "scsi_module.c"
5998 * --- Miscellaneous Driver Functions
6002 * First-level interrupt handler.
6004 * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because
6005 * all boards are currently checked for interrupts on each interrupt, 'dev_id'
6006 * is not referenced. 'dev_id' could be used to identify an interrupt passed
6007 * to the AdvanSys driver which is for a device sharing an interrupt with
6008 * an AdvanSys adapter.
6010 STATIC irqreturn_t
6011 advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs)
6013 ulong flags;
6014 int i;
6015 asc_board_t *boardp;
6016 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
6017 struct scsi_cmnd *new_last_scp;
6018 struct Scsi_Host *shp;
6020 ASC_DBG(1, "advansys_interrupt: begin\n");
6023 * Check for interrupts on all boards.
6024 * AscISR() will call asc_isr_callback().
6026 for (i = 0; i < asc_board_count; i++) {
6027 shp = asc_host[i];
6028 boardp = ASC_BOARDP(shp);
6029 ASC_DBG2(2, "advansys_interrupt: i %d, boardp 0x%lx\n",
6030 i, (ulong) boardp);
6031 spin_lock_irqsave(&boardp->lock, flags);
6032 if (ASC_NARROW_BOARD(boardp)) {
6034 * Narrow Board
6036 if (AscIsIntPending(shp->io_port)) {
6037 ASC_STATS(shp, interrupt);
6038 ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
6039 AscISR(&boardp->dvc_var.asc_dvc_var);
6041 } else {
6043 * Wide Board
6045 ASC_DBG(1, "advansys_interrupt: before AdvISR()\n");
6046 if (AdvISR(&boardp->dvc_var.adv_dvc_var)) {
6047 ASC_STATS(shp, interrupt);
6052 * Start waiting requests and create a list of completed requests.
6054 * If a reset request is being performed for the board, the reset
6055 * handler will complete pending requests after it has completed.
6057 if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
6058 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%lx, last_scp 0x%lx\n",
6059 (ulong) done_scp, (ulong) last_scp);
6061 /* Start any waiting commands for the board. */
6062 if (!ASC_QUEUE_EMPTY(&boardp->waiting)) {
6063 ASC_DBG(1, "advansys_interrupt: before asc_execute_queue()\n");
6064 asc_execute_queue(&boardp->waiting);
6068 * Add to the list of requests that must be completed.
6070 * 'done_scp' will always be NULL on the first iteration
6071 * of this loop. 'last_scp' is set at the same time as
6072 * 'done_scp'.
6074 if (done_scp == NULL) {
6075 done_scp = asc_dequeue_list(&boardp->done, &last_scp,
6076 ASC_TID_ALL);
6077 } else {
6078 ASC_ASSERT(last_scp != NULL);
6079 last_scp->host_scribble = (unsigned char *)asc_dequeue_list(
6080 &boardp->done, &new_last_scp, ASC_TID_ALL);
6081 if (new_last_scp != NULL) {
6082 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
6083 last_scp = new_last_scp;
6087 spin_unlock_irqrestore(&boardp->lock, flags);
6091 * If interrupts were enabled on entry, then they
6092 * are now enabled here.
6094 * Complete all requests on the done list.
6097 asc_scsi_done_list(done_scp);
6099 ASC_DBG(1, "advansys_interrupt: end\n");
6100 return IRQ_HANDLED;
6104 * Set the number of commands to queue per device for the
6105 * specified host adapter.
6107 STATIC int
6108 advansys_slave_configure(struct scsi_device *device)
6110 asc_board_t *boardp;
6112 boardp = ASC_BOARDP(device->host);
6113 boardp->flags |= ASC_SELECT_QUEUE_DEPTHS;
6115 * Save a pointer to the device and set its initial/maximum
6116 * queue depth. Only save the pointer for a lun0 dev though.
6118 if(device->lun == 0)
6119 boardp->device[device->id] = device;
6120 if(device->tagged_supported) {
6121 if (ASC_NARROW_BOARD(boardp)) {
6122 scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
6123 boardp->dvc_var.asc_dvc_var.max_dvc_qng[device->id]);
6124 } else {
6125 scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
6126 boardp->dvc_var.adv_dvc_var.max_dvc_qng);
6128 } else {
6129 scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun);
6131 ASC_DBG4(1, "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n",
6132 (ulong) device, (ulong) boardp, device->id, device->queue_depth);
6133 return 0;
6137 * Complete all requests on the singly linked list pointed
6138 * to by 'scp'.
6140 * Interrupts can be enabled on entry.
6142 STATIC void
6143 asc_scsi_done_list(struct scsi_cmnd *scp)
6145 struct scsi_cmnd *tscp;
6147 ASC_DBG(2, "asc_scsi_done_list: begin\n");
6148 while (scp != NULL) {
6149 asc_board_t *boardp;
6150 struct device *dev;
6152 ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong) scp);
6153 tscp = REQPNEXT(scp);
6154 scp->host_scribble = NULL;
6156 boardp = ASC_BOARDP(scp->device->host);
6158 if (ASC_NARROW_BOARD(boardp))
6159 dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
6160 else
6161 dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
6163 if (scp->use_sg)
6164 dma_unmap_sg(dev, (struct scatterlist *)scp->request_buffer,
6165 scp->use_sg, scp->sc_data_direction);
6166 else if (scp->request_bufflen)
6167 dma_unmap_single(dev, scp->SCp.dma_handle,
6168 scp->request_bufflen, scp->sc_data_direction);
6170 ASC_STATS(scp->device->host, done);
6171 ASC_ASSERT(scp->scsi_done != NULL);
6173 scp->scsi_done(scp);
6175 scp = tscp;
6177 ASC_DBG(2, "asc_scsi_done_list: done\n");
6178 return;
6182 * Execute a single 'Scsi_Cmnd'.
6184 * The function 'done' is called when the request has been completed.
6186 * Scsi_Cmnd:
6188 * host - board controlling device
6189 * device - device to send command
6190 * target - target of device
6191 * lun - lun of device
6192 * cmd_len - length of SCSI CDB
6193 * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
6194 * use_sg - if non-zero indicates scatter-gather request with use_sg elements
6196 * if (use_sg == 0) {
6197 * request_buffer - buffer address for request
6198 * request_bufflen - length of request buffer
6199 * } else {
6200 * request_buffer - pointer to scatterlist structure
6203 * sense_buffer - sense command buffer
6205 * result (4 bytes of an int):
6206 * Byte Meaning
6207 * 0 SCSI Status Byte Code
6208 * 1 SCSI One Byte Message Code
6209 * 2 Host Error Code
6210 * 3 Mid-Level Error Code
6212 * host driver fields:
6213 * SCp - Scsi_Pointer used for command processing status
6214 * scsi_done - used to save caller's done function
6215 * host_scribble - used for pointer to another struct scsi_cmnd
6217 * If this function returns ASC_NOERROR the request has been enqueued
6218 * on the board's 'active' queue and will be completed from the
6219 * interrupt handler.
6221 * If this function returns ASC_NOERROR the request has been enqueued
6222 * on the board's 'done' queue and must be completed by the caller.
6224 * If ASC_BUSY is returned the request will be enqueued by the
6225 * caller on the target's waiting queue and re-tried later.
6227 STATIC int
6228 asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
6230 asc_board_t *boardp;
6231 ASC_DVC_VAR *asc_dvc_varp;
6232 ADV_DVC_VAR *adv_dvc_varp;
6233 ADV_SCSI_REQ_Q *adv_scsiqp;
6234 struct scsi_device *device;
6235 int ret;
6237 ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n",
6238 (ulong) scp, (ulong) scp->scsi_done);
6240 boardp = ASC_BOARDP(scp->device->host);
6241 device = boardp->device[scp->device->id];
6243 if (ASC_NARROW_BOARD(boardp)) {
6245 * Build and execute Narrow Board request.
6248 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
6251 * Build Asc Library request structure using the
6252 * global structures 'asc_scsi_req' and 'asc_sg_head'.
6254 * If an error is returned, then the request has been
6255 * queued on the board done queue. It will be completed
6256 * by the caller.
6258 * asc_build_req() can not return ASC_BUSY.
6260 if (asc_build_req(boardp, scp) == ASC_ERROR) {
6261 ASC_STATS(scp->device->host, build_error);
6262 return ASC_ERROR;
6266 * Execute the command. If there is no error, add the command
6267 * to the active queue.
6269 switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) {
6270 case ASC_NOERROR:
6271 ASC_STATS(scp->device->host, exe_noerror);
6273 * Increment monotonically increasing per device successful
6274 * request counter. Wrapping doesn't matter.
6276 boardp->reqcnt[scp->device->id]++;
6277 asc_enqueue(&boardp->active, scp, ASC_BACK);
6278 ASC_DBG(1,
6279 "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n");
6280 break;
6281 case ASC_BUSY:
6283 * Caller will enqueue request on the target's waiting queue
6284 * and retry later.
6286 ASC_STATS(scp->device->host, exe_busy);
6287 break;
6288 case ASC_ERROR:
6289 ASC_PRINT2(
6290 "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
6291 boardp->id, asc_dvc_varp->err_code);
6292 ASC_STATS(scp->device->host, exe_error);
6293 scp->result = HOST_BYTE(DID_ERROR);
6294 asc_enqueue(&boardp->done, scp, ASC_BACK);
6295 break;
6296 default:
6297 ASC_PRINT2(
6298 "asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n",
6299 boardp->id, asc_dvc_varp->err_code);
6300 ASC_STATS(scp->device->host, exe_unknown);
6301 scp->result = HOST_BYTE(DID_ERROR);
6302 asc_enqueue(&boardp->done, scp, ASC_BACK);
6303 break;
6305 } else {
6307 * Build and execute Wide Board request.
6309 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
6312 * Build and get a pointer to an Adv Library request structure.
6314 * If the request is successfully built then send it below,
6315 * otherwise return with an error.
6317 switch (adv_build_req(boardp, scp, &adv_scsiqp)) {
6318 case ASC_NOERROR:
6319 ASC_DBG(3, "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n");
6320 break;
6321 case ASC_BUSY:
6322 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n");
6324 * If busy is returned the request has not been enqueued.
6325 * It will be enqueued by the caller on the target's waiting
6326 * queue and retried later.
6328 * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg'
6329 * count wide board busy conditions. They are updated in
6330 * adv_build_req and adv_get_sglist, respectively.
6332 return ASC_BUSY;
6333 case ASC_ERROR:
6335 * If an error is returned, then the request has been
6336 * queued on the board done queue. It will be completed
6337 * by the caller.
6339 default:
6340 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n");
6341 ASC_STATS(scp->device->host, build_error);
6342 return ASC_ERROR;
6346 * Execute the command. If there is no error, add the command
6347 * to the active queue.
6349 switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) {
6350 case ASC_NOERROR:
6351 ASC_STATS(scp->device->host, exe_noerror);
6353 * Increment monotonically increasing per device successful
6354 * request counter. Wrapping doesn't matter.
6356 boardp->reqcnt[scp->device->id]++;
6357 asc_enqueue(&boardp->active, scp, ASC_BACK);
6358 ASC_DBG(1,
6359 "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n");
6360 break;
6361 case ASC_BUSY:
6363 * Caller will enqueue request on the target's waiting queue
6364 * and retry later.
6366 ASC_STATS(scp->device->host, exe_busy);
6367 break;
6368 case ASC_ERROR:
6369 ASC_PRINT2(
6370 "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n",
6371 boardp->id, adv_dvc_varp->err_code);
6372 ASC_STATS(scp->device->host, exe_error);
6373 scp->result = HOST_BYTE(DID_ERROR);
6374 asc_enqueue(&boardp->done, scp, ASC_BACK);
6375 break;
6376 default:
6377 ASC_PRINT2(
6378 "asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n",
6379 boardp->id, adv_dvc_varp->err_code);
6380 ASC_STATS(scp->device->host, exe_unknown);
6381 scp->result = HOST_BYTE(DID_ERROR);
6382 asc_enqueue(&boardp->done, scp, ASC_BACK);
6383 break;
6387 ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
6388 return ret;
6392 * Build a request structure for the Asc Library (Narrow Board).
6394 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
6395 * used to build the request.
6397 * If an error occurs, then queue the request on the board done
6398 * queue and return ASC_ERROR.
6400 STATIC int
6401 asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
6403 struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev;
6406 * Mutually exclusive access is required to 'asc_scsi_q' and
6407 * 'asc_sg_head' until after the request is started.
6409 memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q));
6412 * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'.
6414 asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp);
6417 * Build the ASC_SCSI_Q request.
6419 * For narrow boards a CDB length maximum of 12 bytes
6420 * is supported.
6422 if (scp->cmd_len > ASC_MAX_CDB_LEN) {
6423 ASC_PRINT3(
6424 "asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN %d\n",
6425 boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN);
6426 scp->result = HOST_BYTE(DID_ERROR);
6427 asc_enqueue(&boardp->done, scp, ASC_BACK);
6428 return ASC_ERROR;
6430 asc_scsi_q.cdbptr = &scp->cmnd[0];
6431 asc_scsi_q.q2.cdb_len = scp->cmd_len;
6432 asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id);
6433 asc_scsi_q.q1.target_lun = scp->device->lun;
6434 asc_scsi_q.q2.target_ix = ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun);
6435 asc_scsi_q.q1.sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
6436 asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer);
6439 * If there are any outstanding requests for the current target,
6440 * then every 255th request send an ORDERED request. This heuristic
6441 * tries to retain the benefit of request sorting while preventing
6442 * request starvation. 255 is the max number of tags or pending commands
6443 * a device may have outstanding.
6445 * The request count is incremented below for every successfully
6446 * started request.
6449 if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) &&
6450 (boardp->reqcnt[scp->device->id] % 255) == 0) {
6451 asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG;
6452 } else {
6453 asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG;
6457 * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
6458 * buffer command.
6460 if (scp->use_sg == 0) {
6462 * CDB request of single contiguous buffer.
6464 ASC_STATS(scp->device->host, cont_cnt);
6465 scp->SCp.dma_handle = scp->request_bufflen ?
6466 dma_map_single(dev, scp->request_buffer,
6467 scp->request_bufflen, scp->sc_data_direction) : 0;
6468 asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle);
6469 asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen);
6470 ASC_STATS_ADD(scp->device->host, cont_xfer,
6471 ASC_CEILING(scp->request_bufflen, 512));
6472 asc_scsi_q.q1.sg_queue_cnt = 0;
6473 asc_scsi_q.sg_head = NULL;
6474 } else {
6476 * CDB scatter-gather request list.
6478 int sgcnt;
6479 int use_sg;
6480 struct scatterlist *slp;
6482 slp = (struct scatterlist *)scp->request_buffer;
6483 use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
6485 if (use_sg > scp->device->host->sg_tablesize) {
6486 ASC_PRINT3(
6487 "asc_build_req: board %d: use_sg %d > sg_tablesize %d\n",
6488 boardp->id, use_sg, scp->device->host->sg_tablesize);
6489 dma_unmap_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
6490 scp->result = HOST_BYTE(DID_ERROR);
6491 asc_enqueue(&boardp->done, scp, ASC_BACK);
6492 return ASC_ERROR;
6495 ASC_STATS(scp->device->host, sg_cnt);
6498 * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q
6499 * structure to point to it.
6501 memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD));
6503 asc_scsi_q.q1.cntl |= QC_SG_HEAD;
6504 asc_scsi_q.sg_head = &asc_sg_head;
6505 asc_scsi_q.q1.data_cnt = 0;
6506 asc_scsi_q.q1.data_addr = 0;
6507 /* This is a byte value, otherwise it would need to be swapped. */
6508 asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg;
6509 ASC_STATS_ADD(scp->device->host, sg_elem, asc_sg_head.entry_cnt);
6512 * Convert scatter-gather list into ASC_SG_HEAD list.
6514 for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
6515 asc_sg_head.sg_list[sgcnt].addr = cpu_to_le32(sg_dma_address(slp));
6516 asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(sg_dma_len(slp));
6517 ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512));
6521 ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q);
6522 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6524 return ASC_NOERROR;
6528 * Build a request structure for the Adv Library (Wide Board).
6530 * If an adv_req_t can not be allocated to issue the request,
6531 * then return ASC_BUSY. If an error occurs, then return ASC_ERROR.
6533 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the
6534 * microcode for DMA addresses or math operations are byte swapped
6535 * to little-endian order.
6537 STATIC int
6538 adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
6539 ADV_SCSI_REQ_Q **adv_scsiqpp)
6541 adv_req_t *reqp;
6542 ADV_SCSI_REQ_Q *scsiqp;
6543 int i;
6544 int ret;
6545 struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev;
6548 * Allocate an adv_req_t structure from the board to execute
6549 * the command.
6551 if (boardp->adv_reqp == NULL) {
6552 ASC_DBG(1, "adv_build_req: no free adv_req_t\n");
6553 ASC_STATS(scp->device->host, adv_build_noreq);
6554 return ASC_BUSY;
6555 } else {
6556 reqp = boardp->adv_reqp;
6557 boardp->adv_reqp = reqp->next_reqp;
6558 reqp->next_reqp = NULL;
6562 * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers.
6564 scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
6567 * Initialize the structure.
6569 scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0;
6572 * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure.
6574 scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp);
6577 * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure.
6579 reqp->cmndp = scp;
6582 * Build the ADV_SCSI_REQ_Q request.
6586 * Set CDB length and copy it to the request structure.
6587 * For wide boards a CDB length maximum of 16 bytes
6588 * is supported.
6590 if (scp->cmd_len > ADV_MAX_CDB_LEN) {
6591 ASC_PRINT3(
6592 "adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n",
6593 boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
6594 scp->result = HOST_BYTE(DID_ERROR);
6595 asc_enqueue(&boardp->done, scp, ASC_BACK);
6596 return ASC_ERROR;
6598 scsiqp->cdb_len = scp->cmd_len;
6599 /* Copy first 12 CDB bytes to cdb[]. */
6600 for (i = 0; i < scp->cmd_len && i < 12; i++) {
6601 scsiqp->cdb[i] = scp->cmnd[i];
6603 /* Copy last 4 CDB bytes, if present, to cdb16[]. */
6604 for (; i < scp->cmd_len; i++) {
6605 scsiqp->cdb16[i - 12] = scp->cmnd[i];
6608 scsiqp->target_id = scp->device->id;
6609 scsiqp->target_lun = scp->device->lun;
6611 scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0]));
6612 scsiqp->sense_len = sizeof(scp->sense_buffer);
6615 * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather
6616 * buffer command.
6619 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
6620 scsiqp->vdata_addr = scp->request_buffer;
6621 scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer));
6623 if (scp->use_sg == 0) {
6625 * CDB request of single contiguous buffer.
6627 reqp->sgblkp = NULL;
6628 scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen);
6629 if (scp->request_bufflen) {
6630 scsiqp->vdata_addr = scp->request_buffer;
6631 scp->SCp.dma_handle =
6632 dma_map_single(dev, scp->request_buffer,
6633 scp->request_bufflen, scp->sc_data_direction);
6634 } else {
6635 scsiqp->vdata_addr = 0;
6636 scp->SCp.dma_handle = 0;
6638 scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle);
6639 scsiqp->sg_list_ptr = NULL;
6640 scsiqp->sg_real_addr = 0;
6641 ASC_STATS(scp->device->host, cont_cnt);
6642 ASC_STATS_ADD(scp->device->host, cont_xfer,
6643 ASC_CEILING(scp->request_bufflen, 512));
6644 } else {
6646 * CDB scatter-gather request list.
6648 struct scatterlist *slp;
6649 int use_sg;
6651 slp = (struct scatterlist *)scp->request_buffer;
6652 use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
6654 if (use_sg > ADV_MAX_SG_LIST) {
6655 ASC_PRINT3(
6656 "adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n",
6657 boardp->id, use_sg, scp->device->host->sg_tablesize);
6658 dma_unmap_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
6659 scp->result = HOST_BYTE(DID_ERROR);
6660 asc_enqueue(&boardp->done, scp, ASC_BACK);
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 ASC_ERROR;
6672 if ((ret = adv_get_sglist(boardp, reqp, scp, use_sg)) != ADV_SUCCESS) {
6674 * Free the adv_req_t structure by adding it back to the
6675 * board free list.
6677 reqp->next_reqp = boardp->adv_reqp;
6678 boardp->adv_reqp = reqp;
6680 return ret;
6683 ASC_STATS(scp->device->host, sg_cnt);
6684 ASC_STATS_ADD(scp->device->host, sg_elem, use_sg);
6687 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
6688 ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
6690 *adv_scsiqpp = scsiqp;
6692 return ASC_NOERROR;
6696 * Build scatter-gather list for Adv Library (Wide Board).
6698 * Additional ADV_SG_BLOCK structures will need to be allocated
6699 * if the total number of scatter-gather elements exceeds
6700 * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are
6701 * assumed to be physically contiguous.
6703 * Return:
6704 * ADV_SUCCESS(1) - SG List successfully created
6705 * ADV_ERROR(-1) - SG List creation failed
6707 STATIC int
6708 adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, int use_sg)
6710 adv_sgblk_t *sgblkp;
6711 ADV_SCSI_REQ_Q *scsiqp;
6712 struct scatterlist *slp;
6713 int sg_elem_cnt;
6714 ADV_SG_BLOCK *sg_block, *prev_sg_block;
6715 ADV_PADDR sg_block_paddr;
6716 int i;
6718 scsiqp = (ADV_SCSI_REQ_Q *) ADV_32BALIGN(&reqp->scsi_req_q);
6719 slp = (struct scatterlist *) scp->request_buffer;
6720 sg_elem_cnt = use_sg;
6721 prev_sg_block = NULL;
6722 reqp->sgblkp = NULL;
6727 * Allocate a 'adv_sgblk_t' structure from the board free
6728 * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK
6729 * (15) scatter-gather elements.
6731 if ((sgblkp = boardp->adv_sgblkp) == NULL) {
6732 ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n");
6733 ASC_STATS(scp->device->host, adv_build_nosg);
6736 * Allocation failed. Free 'adv_sgblk_t' structures already
6737 * allocated for the request.
6739 while ((sgblkp = reqp->sgblkp) != NULL)
6741 /* Remove 'sgblkp' from the request list. */
6742 reqp->sgblkp = sgblkp->next_sgblkp;
6744 /* Add 'sgblkp' to the board free list. */
6745 sgblkp->next_sgblkp = boardp->adv_sgblkp;
6746 boardp->adv_sgblkp = sgblkp;
6748 return ASC_BUSY;
6749 } else {
6750 /* Complete 'adv_sgblk_t' board allocation. */
6751 boardp->adv_sgblkp = sgblkp->next_sgblkp;
6752 sgblkp->next_sgblkp = NULL;
6755 * Get 8 byte aligned virtual and physical addresses for
6756 * the allocated ADV_SG_BLOCK structure.
6758 sg_block = (ADV_SG_BLOCK *) ADV_8BALIGN(&sgblkp->sg_block);
6759 sg_block_paddr = virt_to_bus(sg_block);
6762 * Check if this is the first 'adv_sgblk_t' for the request.
6764 if (reqp->sgblkp == NULL)
6766 /* Request's first scatter-gather block. */
6767 reqp->sgblkp = sgblkp;
6770 * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical
6771 * address pointers.
6773 scsiqp->sg_list_ptr = sg_block;
6774 scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr);
6775 } else
6777 /* Request's second or later scatter-gather block. */
6778 sgblkp->next_sgblkp = reqp->sgblkp;
6779 reqp->sgblkp = sgblkp;
6782 * Point the previous ADV_SG_BLOCK structure to
6783 * the newly allocated ADV_SG_BLOCK structure.
6785 ASC_ASSERT(prev_sg_block != NULL);
6786 prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr);
6790 for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
6792 sg_block->sg_list[i].sg_addr = cpu_to_le32(sg_dma_address(slp));
6793 sg_block->sg_list[i].sg_count = cpu_to_le32(sg_dma_len(slp));
6794 ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512));
6796 if (--sg_elem_cnt == 0)
6797 { /* Last ADV_SG_BLOCK and scatter-gather entry. */
6798 sg_block->sg_cnt = i + 1;
6799 sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
6800 return ADV_SUCCESS;
6802 slp++;
6804 sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
6805 prev_sg_block = sg_block;
6807 while (1);
6808 /* NOTREACHED */
6812 * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
6814 * Interrupt callback function for the Narrow SCSI Asc Library.
6816 STATIC void
6817 asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
6819 asc_board_t *boardp;
6820 struct scsi_cmnd *scp;
6821 struct Scsi_Host *shp;
6822 int i;
6824 ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n",
6825 (ulong) asc_dvc_varp, (ulong) qdonep);
6826 ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep);
6829 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
6830 * command that has been completed.
6832 scp = (struct scsi_cmnd *) ASC_U32_TO_VADDR(qdonep->d2.srb_ptr);
6833 ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong) scp);
6835 if (scp == NULL) {
6836 ASC_PRINT("asc_isr_callback: scp is NULL\n");
6837 return;
6839 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
6842 * If the request's host pointer is not valid, display a
6843 * message and return.
6845 shp = scp->device->host;
6846 for (i = 0; i < asc_board_count; i++) {
6847 if (asc_host[i] == shp) {
6848 break;
6851 if (i == asc_board_count) {
6852 ASC_PRINT2(
6853 "asc_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
6854 (ulong) scp, (ulong) shp);
6855 return;
6858 ASC_STATS(shp, callback);
6859 ASC_DBG1(1, "asc_isr_callback: shp 0x%lx\n", (ulong) shp);
6862 * If the request isn't found on the active queue, it may
6863 * have been removed to handle a reset request.
6864 * Display a message and return.
6866 boardp = ASC_BOARDP(shp);
6867 ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var);
6868 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
6869 ASC_PRINT2(
6870 "asc_isr_callback: board %d: scp 0x%lx not on active queue\n",
6871 boardp->id, (ulong) scp);
6872 return;
6876 * 'qdonep' contains the command's ending status.
6878 switch (qdonep->d3.done_stat) {
6879 case QD_NO_ERROR:
6880 ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
6881 scp->result = 0;
6884 * If an INQUIRY command completed successfully, then call
6885 * the AscInquiryHandling() function to set-up the device.
6887 if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 &&
6888 (scp->request_bufflen - qdonep->remain_bytes) >= 8)
6890 AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7,
6891 (ASC_SCSI_INQUIRY *) scp->request_buffer);
6895 * Check for an underrun condition.
6897 * If there was no error and an underrun condition, then
6898 * then return the number of underrun bytes.
6900 if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 &&
6901 qdonep->remain_bytes <= scp->request_bufflen) {
6902 ASC_DBG1(1, "asc_isr_callback: underrun condition %u bytes\n",
6903 (unsigned) qdonep->remain_bytes);
6904 scp->resid = qdonep->remain_bytes;
6906 break;
6908 case QD_WITH_ERROR:
6909 ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
6910 switch (qdonep->d3.host_stat) {
6911 case QHSTA_NO_ERROR:
6912 if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) {
6913 ASC_DBG(2, "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n");
6914 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
6915 sizeof(scp->sense_buffer));
6917 * Note: The 'status_byte()' macro used by target drivers
6918 * defined in scsi.h shifts the status byte returned by
6919 * host drivers right by 1 bit. This is why target drivers
6920 * also use right shifted status byte definitions. For
6921 * instance target drivers use CHECK_CONDITION, defined to
6922 * 0x1, instead of the SCSI defined check condition value
6923 * of 0x2. Host drivers are supposed to return the status
6924 * byte as it is defined by SCSI.
6926 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
6927 STATUS_BYTE(qdonep->d3.scsi_stat);
6928 } else {
6929 scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
6931 break;
6933 default:
6934 /* QHSTA error occurred */
6935 ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n",
6936 qdonep->d3.host_stat);
6937 scp->result = HOST_BYTE(DID_BAD_TARGET);
6938 break;
6940 break;
6942 case QD_ABORTED_BY_HOST:
6943 ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
6944 scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.scsi_msg) |
6945 STATUS_BYTE(qdonep->d3.scsi_stat);
6946 break;
6948 default:
6949 ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n", qdonep->d3.done_stat);
6950 scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
6951 STATUS_BYTE(qdonep->d3.scsi_stat);
6952 break;
6956 * If the 'init_tidmask' bit isn't already set for the target and the
6957 * current request finished normally, then set the bit for the target
6958 * to indicate that a device is present.
6960 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
6961 qdonep->d3.done_stat == QD_NO_ERROR &&
6962 qdonep->d3.host_stat == QHSTA_NO_ERROR) {
6963 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
6967 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
6968 * function, add the command to the end of the board's done queue.
6969 * The done function for the command will be called from
6970 * advansys_interrupt().
6972 asc_enqueue(&boardp->done, scp, ASC_BACK);
6974 return;
6978 * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR().
6980 * Callback function for the Wide SCSI Adv Library.
6982 STATIC void
6983 adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
6985 asc_board_t *boardp;
6986 adv_req_t *reqp;
6987 adv_sgblk_t *sgblkp;
6988 struct scsi_cmnd *scp;
6989 struct Scsi_Host *shp;
6990 int i;
6991 ADV_DCNT resid_cnt;
6994 ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n",
6995 (ulong) adv_dvc_varp, (ulong) scsiqp);
6996 ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp);
6999 * Get the adv_req_t structure for the command that has been
7000 * completed. The adv_req_t structure actually contains the
7001 * completed ADV_SCSI_REQ_Q structure.
7003 reqp = (adv_req_t *) ADV_U32_TO_VADDR(scsiqp->srb_ptr);
7004 ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong) reqp);
7005 if (reqp == NULL) {
7006 ASC_PRINT("adv_isr_callback: reqp is NULL\n");
7007 return;
7011 * Get the struct scsi_cmnd structure and Scsi_Host structure for the
7012 * command that has been completed.
7014 * Note: The adv_req_t request structure and adv_sgblk_t structure,
7015 * if any, are dropped, because a board structure pointer can not be
7016 * determined.
7018 scp = reqp->cmndp;
7019 ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong) scp);
7020 if (scp == NULL) {
7021 ASC_PRINT("adv_isr_callback: scp is NULL; adv_req_t dropped.\n");
7022 return;
7024 ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
7027 * If the request's host pointer is not valid, display a message
7028 * and return.
7030 shp = scp->device->host;
7031 for (i = 0; i < asc_board_count; i++) {
7032 if (asc_host[i] == shp) {
7033 break;
7037 * Note: If the host structure is not found, the adv_req_t request
7038 * structure and adv_sgblk_t structure, if any, is dropped.
7040 if (i == asc_board_count) {
7041 ASC_PRINT2(
7042 "adv_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n",
7043 (ulong) scp, (ulong) shp);
7044 return;
7047 ASC_STATS(shp, callback);
7048 ASC_DBG1(1, "adv_isr_callback: shp 0x%lx\n", (ulong) shp);
7051 * If the request isn't found on the active queue, it may have been
7052 * removed to handle a reset request. Display a message and return.
7054 * Note: Because the structure may still be in use don't attempt
7055 * to free the adv_req_t and adv_sgblk_t, if any, structures.
7057 boardp = ASC_BOARDP(shp);
7058 ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var);
7059 if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) {
7060 ASC_PRINT2(
7061 "adv_isr_callback: board %d: scp 0x%lx not on active queue\n",
7062 boardp->id, (ulong) scp);
7063 return;
7067 * 'done_status' contains the command's ending status.
7069 switch (scsiqp->done_status) {
7070 case QD_NO_ERROR:
7071 ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n");
7072 scp->result = 0;
7075 * Check for an underrun condition.
7077 * If there was no error and an underrun condition, then
7078 * then return the number of underrun bytes.
7080 resid_cnt = le32_to_cpu(scsiqp->data_cnt);
7081 if (scp->request_bufflen != 0 && resid_cnt != 0 &&
7082 resid_cnt <= scp->request_bufflen) {
7083 ASC_DBG1(1, "adv_isr_callback: underrun condition %lu bytes\n",
7084 (ulong) resid_cnt);
7085 scp->resid = resid_cnt;
7087 break;
7089 case QD_WITH_ERROR:
7090 ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n");
7091 switch (scsiqp->host_status) {
7092 case QHSTA_NO_ERROR:
7093 if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) {
7094 ASC_DBG(2, "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n");
7095 ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
7096 sizeof(scp->sense_buffer));
7098 * Note: The 'status_byte()' macro used by target drivers
7099 * defined in scsi.h shifts the status byte returned by
7100 * host drivers right by 1 bit. This is why target drivers
7101 * also use right shifted status byte definitions. For
7102 * instance target drivers use CHECK_CONDITION, defined to
7103 * 0x1, instead of the SCSI defined check condition value
7104 * of 0x2. Host drivers are supposed to return the status
7105 * byte as it is defined by SCSI.
7107 scp->result = DRIVER_BYTE(DRIVER_SENSE) |
7108 STATUS_BYTE(scsiqp->scsi_status);
7109 } else {
7110 scp->result = STATUS_BYTE(scsiqp->scsi_status);
7112 break;
7114 default:
7115 /* Some other QHSTA error occurred. */
7116 ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n",
7117 scsiqp->host_status);
7118 scp->result = HOST_BYTE(DID_BAD_TARGET);
7119 break;
7121 break;
7123 case QD_ABORTED_BY_HOST:
7124 ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n");
7125 scp->result = HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status);
7126 break;
7128 default:
7129 ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n", scsiqp->done_status);
7130 scp->result = HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status);
7131 break;
7135 * If the 'init_tidmask' bit isn't already set for the target and the
7136 * current request finished normally, then set the bit for the target
7137 * to indicate that a device is present.
7139 if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 &&
7140 scsiqp->done_status == QD_NO_ERROR &&
7141 scsiqp->host_status == QHSTA_NO_ERROR) {
7142 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
7146 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
7147 * function, add the command to the end of the board's done queue.
7148 * The done function for the command will be called from
7149 * advansys_interrupt().
7151 asc_enqueue(&boardp->done, scp, ASC_BACK);
7154 * Free all 'adv_sgblk_t' structures allocated for the request.
7156 while ((sgblkp = reqp->sgblkp) != NULL)
7158 /* Remove 'sgblkp' from the request list. */
7159 reqp->sgblkp = sgblkp->next_sgblkp;
7161 /* Add 'sgblkp' to the board free list. */
7162 sgblkp->next_sgblkp = boardp->adv_sgblkp;
7163 boardp->adv_sgblkp = sgblkp;
7167 * Free the adv_req_t structure used with the command by adding
7168 * it back to the board free list.
7170 reqp->next_reqp = boardp->adv_reqp;
7171 boardp->adv_reqp = reqp;
7173 ASC_DBG(1, "adv_isr_callback: done\n");
7175 return;
7179 * adv_async_callback() - Adv Library asynchronous event callback function.
7181 STATIC void
7182 adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code)
7184 switch (code)
7186 case ADV_ASYNC_SCSI_BUS_RESET_DET:
7188 * The firmware detected a SCSI Bus reset.
7190 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n");
7191 break;
7193 case ADV_ASYNC_RDMA_FAILURE:
7195 * Handle RDMA failure by resetting the SCSI Bus and
7196 * possibly the chip if it is unresponsive. Log the error
7197 * with a unique code.
7199 ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n");
7200 AdvResetChipAndSB(adv_dvc_varp);
7201 break;
7203 case ADV_HOST_SCSI_BUS_RESET:
7205 * Host generated SCSI bus reset occurred.
7207 ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n");
7208 break;
7210 default:
7211 ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code);
7212 break;
7217 * Add a 'REQP' to the end of specified queue. Set 'tidmask'
7218 * to indicate a command is queued for the device.
7220 * 'flag' may be either ASC_FRONT or ASC_BACK.
7222 * 'REQPNEXT(reqp)' returns reqp's next pointer.
7224 STATIC void
7225 asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag)
7227 int tid;
7229 ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n",
7230 (ulong) ascq, (ulong) reqp, flag);
7231 ASC_ASSERT(reqp != NULL);
7232 ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
7233 tid = REQPTID(reqp);
7234 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7235 if (flag == ASC_FRONT) {
7236 reqp->host_scribble = (unsigned char *)ascq->q_first[tid];
7237 ascq->q_first[tid] = reqp;
7238 /* If the queue was empty, set the last pointer. */
7239 if (ascq->q_last[tid] == NULL) {
7240 ascq->q_last[tid] = reqp;
7242 } else { /* ASC_BACK */
7243 if (ascq->q_last[tid] != NULL) {
7244 ascq->q_last[tid]->host_scribble = (unsigned char *)reqp;
7246 ascq->q_last[tid] = reqp;
7247 reqp->host_scribble = NULL;
7248 /* If the queue was empty, set the first pointer. */
7249 if (ascq->q_first[tid] == NULL) {
7250 ascq->q_first[tid] = reqp;
7253 /* The queue has at least one entry, set its bit. */
7254 ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid);
7255 #ifdef ADVANSYS_STATS
7256 /* Maintain request queue statistics. */
7257 ascq->q_tot_cnt[tid]++;
7258 ascq->q_cur_cnt[tid]++;
7259 if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) {
7260 ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid];
7261 ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n",
7262 tid, ascq->q_max_cnt[tid]);
7264 REQPTIME(reqp) = REQTIMESTAMP();
7265 #endif /* ADVANSYS_STATS */
7266 ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong) reqp);
7267 return;
7271 * Return first queued 'REQP' on the specified queue for
7272 * the specified target device. Clear the 'tidmask' bit for
7273 * the device if no more commands are left queued for it.
7275 * 'REQPNEXT(reqp)' returns reqp's next pointer.
7277 STATIC REQP
7278 asc_dequeue(asc_queue_t *ascq, int tid)
7280 REQP reqp;
7282 ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong) ascq, tid);
7283 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7284 if ((reqp = ascq->q_first[tid]) != NULL) {
7285 ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid));
7286 ascq->q_first[tid] = REQPNEXT(reqp);
7287 /* If the queue is empty, clear its bit and the last pointer. */
7288 if (ascq->q_first[tid] == NULL) {
7289 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7290 ASC_ASSERT(ascq->q_last[tid] == reqp);
7291 ascq->q_last[tid] = NULL;
7293 #ifdef ADVANSYS_STATS
7294 /* Maintain request queue statistics. */
7295 ascq->q_cur_cnt[tid]--;
7296 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
7297 REQTIMESTAT("asc_dequeue", ascq, reqp, tid);
7298 #endif /* ADVANSYS_STATS */
7300 ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong) reqp);
7301 return reqp;
7305 * Return a pointer to a singly linked list of all the requests queued
7306 * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'.
7308 * If 'lastpp' is not NULL, '*lastpp' will be set to point to the
7309 * the last request returned in the singly linked list.
7311 * 'tid' should either be a valid target id or if it is ASC_TID_ALL,
7312 * then all queued requests are concatenated into one list and
7313 * returned.
7315 * Note: If 'lastpp' is used to append a new list to the end of
7316 * an old list, only change the old list last pointer if '*lastpp'
7317 * (or the function return value) is not NULL, i.e. use a temporary
7318 * variable for 'lastpp' and check its value after the function return
7319 * before assigning it to the list last pointer.
7321 * Unfortunately collecting queuing time statistics adds overhead to
7322 * the function that isn't inherent to the function's algorithm.
7324 STATIC REQP
7325 asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid)
7327 REQP firstp, lastp;
7328 int i;
7330 ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong) ascq, tid);
7331 ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID));
7334 * If 'tid' is not ASC_TID_ALL, return requests only for
7335 * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all
7336 * requests for all tids.
7338 if (tid != ASC_TID_ALL) {
7339 /* Return all requests for the specified 'tid'. */
7340 if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) {
7341 /* List is empty; Set first and last return pointers to NULL. */
7342 firstp = lastp = NULL;
7343 } else {
7344 firstp = ascq->q_first[tid];
7345 lastp = ascq->q_last[tid];
7346 ascq->q_first[tid] = ascq->q_last[tid] = NULL;
7347 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7348 #ifdef ADVANSYS_STATS
7350 REQP reqp;
7351 ascq->q_cur_cnt[tid] = 0;
7352 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
7353 REQTIMESTAT("asc_dequeue_list", ascq, reqp, tid);
7356 #endif /* ADVANSYS_STATS */
7358 } else {
7359 /* Return all requests for all tids. */
7360 firstp = lastp = NULL;
7361 for (i = 0; i <= ADV_MAX_TID; i++) {
7362 if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) {
7363 if (firstp == NULL) {
7364 firstp = ascq->q_first[i];
7365 lastp = ascq->q_last[i];
7366 } else {
7367 ASC_ASSERT(lastp != NULL);
7368 lastp->host_scribble = (unsigned char *)ascq->q_first[i];
7369 lastp = ascq->q_last[i];
7371 ascq->q_first[i] = ascq->q_last[i] = NULL;
7372 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7373 #ifdef ADVANSYS_STATS
7374 ascq->q_cur_cnt[i] = 0;
7375 #endif /* ADVANSYS_STATS */
7378 #ifdef ADVANSYS_STATS
7380 REQP reqp;
7381 for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) {
7382 REQTIMESTAT("asc_dequeue_list", ascq, reqp, reqp->device->id);
7385 #endif /* ADVANSYS_STATS */
7387 if (lastpp) {
7388 *lastpp = lastp;
7390 ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong) firstp);
7391 return firstp;
7395 * Remove the specified 'REQP' from the specified queue for
7396 * the specified target device. Clear the 'tidmask' bit for the
7397 * device if no more commands are left queued for it.
7399 * 'REQPNEXT(reqp)' returns reqp's the next pointer.
7401 * Return ASC_TRUE if the command was found and removed,
7402 * otherwise return ASC_FALSE.
7404 STATIC int
7405 asc_rmqueue(asc_queue_t *ascq, REQP reqp)
7407 REQP currp, prevp;
7408 int tid;
7409 int ret = ASC_FALSE;
7411 ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n",
7412 (ulong) ascq, (ulong) reqp);
7413 ASC_ASSERT(reqp != NULL);
7415 tid = REQPTID(reqp);
7416 ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID);
7419 * Handle the common case of 'reqp' being the first
7420 * entry on the queue.
7422 if (reqp == ascq->q_first[tid]) {
7423 ret = ASC_TRUE;
7424 ascq->q_first[tid] = REQPNEXT(reqp);
7425 /* If the queue is now empty, clear its bit and the last pointer. */
7426 if (ascq->q_first[tid] == NULL) {
7427 ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid);
7428 ASC_ASSERT(ascq->q_last[tid] == reqp);
7429 ascq->q_last[tid] = NULL;
7431 } else if (ascq->q_first[tid] != NULL) {
7432 ASC_ASSERT(ascq->q_last[tid] != NULL);
7434 * Because the case of 'reqp' being the first entry has been
7435 * handled above and it is known the queue is not empty, if
7436 * 'reqp' is found on the queue it is guaranteed the queue will
7437 * not become empty and that 'q_first[tid]' will not be changed.
7439 * Set 'prevp' to the first entry, 'currp' to the second entry,
7440 * and search for 'reqp'.
7442 for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp);
7443 currp; prevp = currp, currp = REQPNEXT(currp)) {
7444 if (currp == reqp) {
7445 ret = ASC_TRUE;
7446 prevp->host_scribble = (unsigned char *)REQPNEXT(currp);
7447 reqp->host_scribble = NULL;
7448 if (ascq->q_last[tid] == reqp) {
7449 ascq->q_last[tid] = prevp;
7451 break;
7455 #ifdef ADVANSYS_STATS
7456 /* Maintain request queue statistics. */
7457 if (ret == ASC_TRUE) {
7458 ascq->q_cur_cnt[tid]--;
7459 REQTIMESTAT("asc_rmqueue", ascq, reqp, tid);
7461 ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0);
7462 #endif /* ADVANSYS_STATS */
7463 ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong) reqp, ret);
7464 return ret;
7468 * Execute as many queued requests as possible for the specified queue.
7470 * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd.
7472 STATIC void
7473 asc_execute_queue(asc_queue_t *ascq)
7475 ADV_SCSI_BIT_ID_TYPE scan_tidmask;
7476 REQP reqp;
7477 int i;
7479 ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong) ascq);
7481 * Execute queued commands for devices attached to
7482 * the current board in round-robin fashion.
7484 scan_tidmask = ascq->q_tidmask;
7485 do {
7486 for (i = 0; i <= ADV_MAX_TID; i++) {
7487 if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) {
7488 if ((reqp = asc_dequeue(ascq, i)) == NULL) {
7489 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7490 } else if (asc_execute_scsi_cmnd((struct scsi_cmnd *) reqp)
7491 == ASC_BUSY) {
7492 scan_tidmask &= ~ADV_TID_TO_TIDMASK(i);
7494 * The request returned ASC_BUSY. Enqueue at the front of
7495 * target's waiting list to maintain correct ordering.
7497 asc_enqueue(ascq, reqp, ASC_FRONT);
7501 } while (scan_tidmask);
7502 return;
7505 #ifdef CONFIG_PROC_FS
7507 * asc_prt_board_devices()
7509 * Print driver information for devices attached to the board.
7511 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7512 * cf. asc_prt_line().
7514 * Return the number of characters copied into 'cp'. No more than
7515 * 'cplen' characters will be copied to 'cp'.
7517 STATIC int
7518 asc_prt_board_devices(struct Scsi_Host *shp, char *cp, int cplen)
7520 asc_board_t *boardp;
7521 int leftlen;
7522 int totlen;
7523 int len;
7524 int chip_scsi_id;
7525 int i;
7527 boardp = ASC_BOARDP(shp);
7528 leftlen = cplen;
7529 totlen = len = 0;
7531 len = asc_prt_line(cp, leftlen,
7532 "\nDevice Information for AdvanSys SCSI Host %d:\n", shp->host_no);
7533 ASC_PRT_NEXT();
7535 if (ASC_NARROW_BOARD(boardp)) {
7536 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
7537 } else {
7538 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
7541 len = asc_prt_line(cp, leftlen, "Target IDs Detected:");
7542 ASC_PRT_NEXT();
7543 for (i = 0; i <= ADV_MAX_TID; i++) {
7544 if (boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) {
7545 len = asc_prt_line(cp, leftlen, " %X,", i);
7546 ASC_PRT_NEXT();
7549 len = asc_prt_line(cp, leftlen, " (%X=Host Adapter)\n", chip_scsi_id);
7550 ASC_PRT_NEXT();
7552 return totlen;
7556 * Display Wide Board BIOS Information.
7558 STATIC int
7559 asc_prt_adv_bios(struct Scsi_Host *shp, char *cp, int cplen)
7561 asc_board_t *boardp;
7562 int leftlen;
7563 int totlen;
7564 int len;
7565 ushort major, minor, letter;
7567 boardp = ASC_BOARDP(shp);
7568 leftlen = cplen;
7569 totlen = len = 0;
7571 len = asc_prt_line(cp, leftlen, "\nROM BIOS Version: ");
7572 ASC_PRT_NEXT();
7575 * If the BIOS saved a valid signature, then fill in
7576 * the BIOS code segment base address.
7578 if (boardp->bios_signature != 0x55AA) {
7579 len = asc_prt_line(cp, leftlen, "Disabled or Pre-3.1\n");
7580 ASC_PRT_NEXT();
7581 len = asc_prt_line(cp, leftlen,
7582 "BIOS either disabled or Pre-3.1. If it is pre-3.1, then a newer version\n");
7583 ASC_PRT_NEXT();
7584 len = asc_prt_line(cp, leftlen,
7585 "can be found at the ConnectCom FTP site: ftp://ftp.connectcom.net/pub\n");
7586 ASC_PRT_NEXT();
7587 } else {
7588 major = (boardp->bios_version >> 12) & 0xF;
7589 minor = (boardp->bios_version >> 8) & 0xF;
7590 letter = (boardp->bios_version & 0xFF);
7592 len = asc_prt_line(cp, leftlen, "%d.%d%c\n",
7593 major, minor, letter >= 26 ? '?' : letter + 'A');
7594 ASC_PRT_NEXT();
7597 * Current available ROM BIOS release is 3.1I for UW
7598 * and 3.2I for U2W. This code doesn't differentiate
7599 * UW and U2W boards.
7601 if (major < 3 || (major <= 3 && minor < 1) ||
7602 (major <= 3 && minor <= 1 && letter < ('I'- 'A'))) {
7603 len = asc_prt_line(cp, leftlen,
7604 "Newer version of ROM BIOS is available at the ConnectCom FTP site:\n");
7605 ASC_PRT_NEXT();
7606 len = asc_prt_line(cp, leftlen,
7607 "ftp://ftp.connectcom.net/pub\n");
7608 ASC_PRT_NEXT();
7612 return totlen;
7616 * Add serial number to information bar if signature AAh
7617 * is found in at bit 15-9 (7 bits) of word 1.
7619 * Serial Number consists fo 12 alpha-numeric digits.
7621 * 1 - Product type (A,B,C,D..) Word0: 15-13 (3 bits)
7622 * 2 - MFG Location (A,B,C,D..) Word0: 12-10 (3 bits)
7623 * 3-4 - Product ID (0-99) Word0: 9-0 (10 bits)
7624 * 5 - Product revision (A-J) Word0: " "
7626 * Signature Word1: 15-9 (7 bits)
7627 * 6 - Year (0-9) Word1: 8-6 (3 bits) & Word2: 15 (1 bit)
7628 * 7-8 - Week of the year (1-52) Word1: 5-0 (6 bits)
7630 * 9-12 - Serial Number (A001-Z999) Word2: 14-0 (15 bits)
7632 * Note 1: Only production cards will have a serial number.
7634 * Note 2: Signature is most significant 7 bits (0xFE).
7636 * Returns ASC_TRUE if serial number found, otherwise returns ASC_FALSE.
7638 STATIC int
7639 asc_get_eeprom_string(ushort *serialnum, uchar *cp)
7641 ushort w, num;
7643 if ((serialnum[1] & 0xFE00) != ((ushort) 0xAA << 8)) {
7644 return ASC_FALSE;
7645 } else {
7647 * First word - 6 digits.
7649 w = serialnum[0];
7651 /* Product type - 1st digit. */
7652 if ((*cp = 'A' + ((w & 0xE000) >> 13)) == 'H') {
7653 /* Product type is P=Prototype */
7654 *cp += 0x8;
7656 cp++;
7658 /* Manufacturing location - 2nd digit. */
7659 *cp++ = 'A' + ((w & 0x1C00) >> 10);
7661 /* Product ID - 3rd, 4th digits. */
7662 num = w & 0x3FF;
7663 *cp++ = '0' + (num / 100);
7664 num %= 100;
7665 *cp++ = '0' + (num / 10);
7667 /* Product revision - 5th digit. */
7668 *cp++ = 'A' + (num % 10);
7671 * Second word
7673 w = serialnum[1];
7676 * Year - 6th digit.
7678 * If bit 15 of third word is set, then the
7679 * last digit of the year is greater than 7.
7681 if (serialnum[2] & 0x8000) {
7682 *cp++ = '8' + ((w & 0x1C0) >> 6);
7683 } else {
7684 *cp++ = '0' + ((w & 0x1C0) >> 6);
7687 /* Week of year - 7th, 8th digits. */
7688 num = w & 0x003F;
7689 *cp++ = '0' + num / 10;
7690 num %= 10;
7691 *cp++ = '0' + num;
7694 * Third word
7696 w = serialnum[2] & 0x7FFF;
7698 /* Serial number - 9th digit. */
7699 *cp++ = 'A' + (w / 1000);
7701 /* 10th, 11th, 12th digits. */
7702 num = w % 1000;
7703 *cp++ = '0' + num / 100;
7704 num %= 100;
7705 *cp++ = '0' + num / 10;
7706 num %= 10;
7707 *cp++ = '0' + num;
7709 *cp = '\0'; /* Null Terminate the string. */
7710 return ASC_TRUE;
7715 * asc_prt_asc_board_eeprom()
7717 * Print board EEPROM configuration.
7719 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7720 * cf. asc_prt_line().
7722 * Return the number of characters copied into 'cp'. No more than
7723 * 'cplen' characters will be copied to 'cp'.
7725 STATIC int
7726 asc_prt_asc_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
7728 asc_board_t *boardp;
7729 ASC_DVC_VAR *asc_dvc_varp;
7730 int leftlen;
7731 int totlen;
7732 int len;
7733 ASCEEP_CONFIG *ep;
7734 int i;
7735 #ifdef CONFIG_ISA
7736 int isa_dma_speed[] = { 10, 8, 7, 6, 5, 4, 3, 2 };
7737 #endif /* CONFIG_ISA */
7738 uchar serialstr[13];
7740 boardp = ASC_BOARDP(shp);
7741 asc_dvc_varp = &boardp->dvc_var.asc_dvc_var;
7742 ep = &boardp->eep_config.asc_eep;
7744 leftlen = cplen;
7745 totlen = len = 0;
7747 len = asc_prt_line(cp, leftlen,
7748 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
7749 ASC_PRT_NEXT();
7751 if (asc_get_eeprom_string((ushort *) &ep->adapter_info[0], serialstr) ==
7752 ASC_TRUE) {
7753 len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
7754 ASC_PRT_NEXT();
7755 } else {
7756 if (ep->adapter_info[5] == 0xBB) {
7757 len = asc_prt_line(cp, leftlen,
7758 " Default Settings Used for EEPROM-less Adapter.\n");
7759 ASC_PRT_NEXT();
7760 } else {
7761 len = asc_prt_line(cp, leftlen,
7762 " Serial Number Signature Not Present.\n");
7763 ASC_PRT_NEXT();
7767 len = asc_prt_line(cp, leftlen,
7768 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7769 ASC_EEP_GET_CHIP_ID(ep), ep->max_total_qng, ep->max_tag_qng);
7770 ASC_PRT_NEXT();
7772 len = asc_prt_line(cp, leftlen,
7773 " cntl 0x%x, no_scam 0x%x\n",
7774 ep->cntl, ep->no_scam);
7775 ASC_PRT_NEXT();
7777 len = asc_prt_line(cp, leftlen,
7778 " Target ID: ");
7779 ASC_PRT_NEXT();
7780 for (i = 0; i <= ASC_MAX_TID; i++) {
7781 len = asc_prt_line(cp, leftlen, " %d", i);
7782 ASC_PRT_NEXT();
7784 len = asc_prt_line(cp, leftlen, "\n");
7785 ASC_PRT_NEXT();
7787 len = asc_prt_line(cp, leftlen,
7788 " Disconnects: ");
7789 ASC_PRT_NEXT();
7790 for (i = 0; i <= ASC_MAX_TID; i++) {
7791 len = asc_prt_line(cp, leftlen, " %c",
7792 (ep->disc_enable & 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 " Command Queuing: ");
7800 ASC_PRT_NEXT();
7801 for (i = 0; i <= ASC_MAX_TID; i++) {
7802 len = asc_prt_line(cp, leftlen, " %c",
7803 (ep->use_cmd_qng & 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 " Start Motor: ");
7811 ASC_PRT_NEXT();
7812 for (i = 0; i <= ASC_MAX_TID; i++) {
7813 len = asc_prt_line(cp, leftlen, " %c",
7814 (ep->start_motor & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7815 ASC_PRT_NEXT();
7817 len = asc_prt_line(cp, leftlen, "\n");
7818 ASC_PRT_NEXT();
7820 len = asc_prt_line(cp, leftlen,
7821 " Synchronous Transfer:");
7822 ASC_PRT_NEXT();
7823 for (i = 0; i <= ASC_MAX_TID; i++) {
7824 len = asc_prt_line(cp, leftlen, " %c",
7825 (ep->init_sdtr & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
7826 ASC_PRT_NEXT();
7828 len = asc_prt_line(cp, leftlen, "\n");
7829 ASC_PRT_NEXT();
7831 #ifdef CONFIG_ISA
7832 if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
7833 len = asc_prt_line(cp, leftlen,
7834 " Host ISA DMA speed: %d MB/S\n",
7835 isa_dma_speed[ASC_EEP_GET_DMA_SPD(ep)]);
7836 ASC_PRT_NEXT();
7838 #endif /* CONFIG_ISA */
7840 return totlen;
7844 * asc_prt_adv_board_eeprom()
7846 * Print board EEPROM configuration.
7848 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
7849 * cf. asc_prt_line().
7851 * Return the number of characters copied into 'cp'. No more than
7852 * 'cplen' characters will be copied to 'cp'.
7854 STATIC int
7855 asc_prt_adv_board_eeprom(struct Scsi_Host *shp, char *cp, int cplen)
7857 asc_board_t *boardp;
7858 ADV_DVC_VAR *adv_dvc_varp;
7859 int leftlen;
7860 int totlen;
7861 int len;
7862 int i;
7863 char *termstr;
7864 uchar serialstr[13];
7865 ADVEEP_3550_CONFIG *ep_3550 = NULL;
7866 ADVEEP_38C0800_CONFIG *ep_38C0800 = NULL;
7867 ADVEEP_38C1600_CONFIG *ep_38C1600 = NULL;
7868 ushort word;
7869 ushort *wordp;
7870 ushort sdtr_speed = 0;
7872 boardp = ASC_BOARDP(shp);
7873 adv_dvc_varp = &boardp->dvc_var.adv_dvc_var;
7874 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7876 ep_3550 = &boardp->eep_config.adv_3550_eep;
7877 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7879 ep_38C0800 = &boardp->eep_config.adv_38C0800_eep;
7880 } else
7882 ep_38C1600 = &boardp->eep_config.adv_38C1600_eep;
7885 leftlen = cplen;
7886 totlen = len = 0;
7888 len = asc_prt_line(cp, leftlen,
7889 "\nEEPROM Settings for AdvanSys SCSI Host %d:\n", shp->host_no);
7890 ASC_PRT_NEXT();
7892 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7894 wordp = &ep_3550->serial_number_word1;
7895 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7897 wordp = &ep_38C0800->serial_number_word1;
7898 } else
7900 wordp = &ep_38C1600->serial_number_word1;
7903 if (asc_get_eeprom_string(wordp, serialstr) == ASC_TRUE) {
7904 len = asc_prt_line(cp, leftlen, " Serial Number: %s\n", serialstr);
7905 ASC_PRT_NEXT();
7906 } else {
7907 len = asc_prt_line(cp, leftlen,
7908 " Serial Number Signature Not Present.\n");
7909 ASC_PRT_NEXT();
7912 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7914 len = asc_prt_line(cp, leftlen,
7915 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7916 ep_3550->adapter_scsi_id, ep_3550->max_host_qng,
7917 ep_3550->max_dvc_qng);
7918 ASC_PRT_NEXT();
7919 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7921 len = asc_prt_line(cp, leftlen,
7922 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7923 ep_38C0800->adapter_scsi_id, ep_38C0800->max_host_qng,
7924 ep_38C0800->max_dvc_qng);
7925 ASC_PRT_NEXT();
7926 } else
7928 len = asc_prt_line(cp, leftlen,
7929 " Host SCSI ID: %u, Host Queue Size: %u, Device Queue Size: %u\n",
7930 ep_38C1600->adapter_scsi_id, ep_38C1600->max_host_qng,
7931 ep_38C1600->max_dvc_qng);
7932 ASC_PRT_NEXT();
7934 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7936 word = ep_3550->termination;
7937 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7939 word = ep_38C0800->termination_lvd;
7940 } else
7942 word = ep_38C1600->termination_lvd;
7944 switch (word) {
7945 case 1:
7946 termstr = "Low Off/High Off";
7947 break;
7948 case 2:
7949 termstr = "Low Off/High On";
7950 break;
7951 case 3:
7952 termstr = "Low On/High On";
7953 break;
7954 default:
7955 case 0:
7956 termstr = "Automatic";
7957 break;
7960 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7962 len = asc_prt_line(cp, leftlen,
7963 " termination: %u (%s), bios_ctrl: 0x%x\n",
7964 ep_3550->termination, termstr, ep_3550->bios_ctrl);
7965 ASC_PRT_NEXT();
7966 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7968 len = asc_prt_line(cp, leftlen,
7969 " termination: %u (%s), bios_ctrl: 0x%x\n",
7970 ep_38C0800->termination_lvd, termstr, ep_38C0800->bios_ctrl);
7971 ASC_PRT_NEXT();
7972 } else
7974 len = asc_prt_line(cp, leftlen,
7975 " termination: %u (%s), bios_ctrl: 0x%x\n",
7976 ep_38C1600->termination_lvd, termstr, ep_38C1600->bios_ctrl);
7977 ASC_PRT_NEXT();
7980 len = asc_prt_line(cp, leftlen,
7981 " Target ID: ");
7982 ASC_PRT_NEXT();
7983 for (i = 0; i <= ADV_MAX_TID; i++) {
7984 len = asc_prt_line(cp, leftlen, " %X", i);
7985 ASC_PRT_NEXT();
7987 len = asc_prt_line(cp, leftlen, "\n");
7988 ASC_PRT_NEXT();
7990 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
7992 word = ep_3550->disc_enable;
7993 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
7995 word = ep_38C0800->disc_enable;
7996 } else
7998 word = ep_38C1600->disc_enable;
8000 len = asc_prt_line(cp, leftlen,
8001 " Disconnects: ");
8002 ASC_PRT_NEXT();
8003 for (i = 0; i <= ADV_MAX_TID; i++) {
8004 len = asc_prt_line(cp, leftlen, " %c",
8005 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8006 ASC_PRT_NEXT();
8008 len = asc_prt_line(cp, leftlen, "\n");
8009 ASC_PRT_NEXT();
8011 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8013 word = ep_3550->tagqng_able;
8014 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8016 word = ep_38C0800->tagqng_able;
8017 } else
8019 word = ep_38C1600->tagqng_able;
8021 len = asc_prt_line(cp, leftlen,
8022 " Command Queuing: ");
8023 ASC_PRT_NEXT();
8024 for (i = 0; i <= ADV_MAX_TID; i++) {
8025 len = asc_prt_line(cp, leftlen, " %c",
8026 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8027 ASC_PRT_NEXT();
8029 len = asc_prt_line(cp, leftlen, "\n");
8030 ASC_PRT_NEXT();
8032 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8034 word = ep_3550->start_motor;
8035 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8037 word = ep_38C0800->start_motor;
8038 } else
8040 word = ep_38C1600->start_motor;
8042 len = asc_prt_line(cp, leftlen,
8043 " Start Motor: ");
8044 ASC_PRT_NEXT();
8045 for (i = 0; i <= ADV_MAX_TID; i++) {
8046 len = asc_prt_line(cp, leftlen, " %c",
8047 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8048 ASC_PRT_NEXT();
8050 len = asc_prt_line(cp, leftlen, "\n");
8051 ASC_PRT_NEXT();
8053 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8055 len = asc_prt_line(cp, leftlen,
8056 " Synchronous Transfer:");
8057 ASC_PRT_NEXT();
8058 for (i = 0; i <= ADV_MAX_TID; i++) {
8059 len = asc_prt_line(cp, leftlen, " %c",
8060 (ep_3550->sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8061 ASC_PRT_NEXT();
8063 len = asc_prt_line(cp, leftlen, "\n");
8064 ASC_PRT_NEXT();
8067 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8069 len = asc_prt_line(cp, leftlen,
8070 " Ultra Transfer: ");
8071 ASC_PRT_NEXT();
8072 for (i = 0; i <= ADV_MAX_TID; i++) {
8073 len = asc_prt_line(cp, leftlen, " %c",
8074 (ep_3550->ultra_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8075 ASC_PRT_NEXT();
8077 len = asc_prt_line(cp, leftlen, "\n");
8078 ASC_PRT_NEXT();
8081 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550)
8083 word = ep_3550->wdtr_able;
8084 } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800)
8086 word = ep_38C0800->wdtr_able;
8087 } else
8089 word = ep_38C1600->wdtr_able;
8091 len = asc_prt_line(cp, leftlen,
8092 " Wide Transfer: ");
8093 ASC_PRT_NEXT();
8094 for (i = 0; i <= ADV_MAX_TID; i++) {
8095 len = asc_prt_line(cp, leftlen, " %c",
8096 (word & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8097 ASC_PRT_NEXT();
8099 len = asc_prt_line(cp, leftlen, "\n");
8100 ASC_PRT_NEXT();
8102 if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800 ||
8103 adv_dvc_varp->chip_type == ADV_CHIP_ASC38C1600)
8105 len = asc_prt_line(cp, leftlen,
8106 " Synchronous Transfer Speed (Mhz):\n ");
8107 ASC_PRT_NEXT();
8108 for (i = 0; i <= ADV_MAX_TID; i++) {
8109 char *speed_str;
8111 if (i == 0)
8113 sdtr_speed = adv_dvc_varp->sdtr_speed1;
8114 } else if (i == 4)
8116 sdtr_speed = adv_dvc_varp->sdtr_speed2;
8117 } else if (i == 8)
8119 sdtr_speed = adv_dvc_varp->sdtr_speed3;
8120 } else if (i == 12)
8122 sdtr_speed = adv_dvc_varp->sdtr_speed4;
8124 switch (sdtr_speed & ADV_MAX_TID)
8126 case 0: speed_str = "Off"; break;
8127 case 1: speed_str = " 5"; break;
8128 case 2: speed_str = " 10"; break;
8129 case 3: speed_str = " 20"; break;
8130 case 4: speed_str = " 40"; break;
8131 case 5: speed_str = " 80"; break;
8132 default: speed_str = "Unk"; break;
8134 len = asc_prt_line(cp, leftlen, "%X:%s ", i, speed_str);
8135 ASC_PRT_NEXT();
8136 if (i == 7)
8138 len = asc_prt_line(cp, leftlen, "\n ");
8139 ASC_PRT_NEXT();
8141 sdtr_speed >>= 4;
8143 len = asc_prt_line(cp, leftlen, "\n");
8144 ASC_PRT_NEXT();
8147 return totlen;
8151 * asc_prt_driver_conf()
8153 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8154 * cf. asc_prt_line().
8156 * Return the number of characters copied into 'cp'. No more than
8157 * 'cplen' characters will be copied to 'cp'.
8159 STATIC int
8160 asc_prt_driver_conf(struct Scsi_Host *shp, char *cp, int cplen)
8162 asc_board_t *boardp;
8163 int leftlen;
8164 int totlen;
8165 int len;
8166 int chip_scsi_id;
8168 boardp = ASC_BOARDP(shp);
8170 leftlen = cplen;
8171 totlen = len = 0;
8173 len = asc_prt_line(cp, leftlen,
8174 "\nLinux Driver Configuration and Information for AdvanSys SCSI Host %d:\n",
8175 shp->host_no);
8176 ASC_PRT_NEXT();
8178 len = asc_prt_line(cp, leftlen,
8179 " host_busy %u, last_reset %u, max_id %u, max_lun %u, max_channel %u\n",
8180 shp->host_busy, shp->last_reset, shp->max_id, shp->max_lun,
8181 shp->max_channel);
8182 ASC_PRT_NEXT();
8184 len = asc_prt_line(cp, leftlen,
8185 " unique_id %d, can_queue %d, this_id %d, sg_tablesize %u, cmd_per_lun %u\n",
8186 shp->unique_id, shp->can_queue, shp->this_id, shp->sg_tablesize,
8187 shp->cmd_per_lun);
8188 ASC_PRT_NEXT();
8190 len = asc_prt_line(cp, leftlen,
8191 " unchecked_isa_dma %d, use_clustering %d\n",
8192 shp->unchecked_isa_dma, shp->use_clustering);
8193 ASC_PRT_NEXT();
8195 len = asc_prt_line(cp, leftlen,
8196 " flags 0x%x, last_reset 0x%x, jiffies 0x%x, asc_n_io_port 0x%x\n",
8197 boardp->flags, boardp->last_reset, jiffies, boardp->asc_n_io_port);
8198 ASC_PRT_NEXT();
8200 /* 'shp->n_io_port' may be truncated because it is only one byte. */
8201 len = asc_prt_line(cp, leftlen,
8202 " io_port 0x%x, n_io_port 0x%x\n",
8203 shp->io_port, shp->n_io_port);
8204 ASC_PRT_NEXT();
8206 if (ASC_NARROW_BOARD(boardp)) {
8207 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
8208 } else {
8209 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
8212 return totlen;
8216 * asc_prt_asc_board_info()
8218 * Print dynamic board configuration information.
8220 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8221 * cf. asc_prt_line().
8223 * Return the number of characters copied into 'cp'. No more than
8224 * 'cplen' characters will be copied to 'cp'.
8226 STATIC int
8227 asc_prt_asc_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8229 asc_board_t *boardp;
8230 int chip_scsi_id;
8231 int leftlen;
8232 int totlen;
8233 int len;
8234 ASC_DVC_VAR *v;
8235 ASC_DVC_CFG *c;
8236 int i;
8237 int renegotiate = 0;
8239 boardp = ASC_BOARDP(shp);
8240 v = &boardp->dvc_var.asc_dvc_var;
8241 c = &boardp->dvc_cfg.asc_dvc_cfg;
8242 chip_scsi_id = c->chip_scsi_id;
8244 leftlen = cplen;
8245 totlen = len = 0;
8247 len = asc_prt_line(cp, leftlen,
8248 "\nAsc Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8249 shp->host_no);
8250 ASC_PRT_NEXT();
8252 len = asc_prt_line(cp, leftlen,
8253 " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n",
8254 c->chip_version, c->lib_version, c->lib_serial_no, c->mcode_date);
8255 ASC_PRT_NEXT();
8257 len = asc_prt_line(cp, leftlen,
8258 " mcode_version 0x%x, err_code %u\n",
8259 c->mcode_version, v->err_code);
8260 ASC_PRT_NEXT();
8262 /* Current number of commands waiting for the host. */
8263 len = asc_prt_line(cp, leftlen,
8264 " Total Command Pending: %d\n", v->cur_total_qng);
8265 ASC_PRT_NEXT();
8267 len = asc_prt_line(cp, leftlen,
8268 " Command Queuing:");
8269 ASC_PRT_NEXT();
8270 for (i = 0; i <= ASC_MAX_TID; i++) {
8271 if ((chip_scsi_id == i) ||
8272 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8273 continue;
8275 len = asc_prt_line(cp, leftlen, " %X:%c",
8276 i, (v->use_tagged_qng & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8277 ASC_PRT_NEXT();
8279 len = asc_prt_line(cp, leftlen, "\n");
8280 ASC_PRT_NEXT();
8282 /* Current number of commands waiting for a device. */
8283 len = asc_prt_line(cp, leftlen,
8284 " Command Queue Pending:");
8285 ASC_PRT_NEXT();
8286 for (i = 0; i <= ASC_MAX_TID; i++) {
8287 if ((chip_scsi_id == i) ||
8288 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8289 continue;
8291 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->cur_dvc_qng[i]);
8292 ASC_PRT_NEXT();
8294 len = asc_prt_line(cp, leftlen, "\n");
8295 ASC_PRT_NEXT();
8297 /* Current limit on number of commands that can be sent to a device. */
8298 len = asc_prt_line(cp, leftlen,
8299 " Command Queue Limit:");
8300 ASC_PRT_NEXT();
8301 for (i = 0; i <= ASC_MAX_TID; i++) {
8302 if ((chip_scsi_id == i) ||
8303 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8304 continue;
8306 len = asc_prt_line(cp, leftlen, " %X:%u", i, v->max_dvc_qng[i]);
8307 ASC_PRT_NEXT();
8309 len = asc_prt_line(cp, leftlen, "\n");
8310 ASC_PRT_NEXT();
8312 /* Indicate whether the device has returned queue full status. */
8313 len = asc_prt_line(cp, leftlen,
8314 " Command Queue Full:");
8315 ASC_PRT_NEXT();
8316 for (i = 0; i <= ASC_MAX_TID; i++) {
8317 if ((chip_scsi_id == i) ||
8318 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8319 continue;
8321 if (boardp->queue_full & ADV_TID_TO_TIDMASK(i)) {
8322 len = asc_prt_line(cp, leftlen, " %X:Y-%d",
8323 i, boardp->queue_full_cnt[i]);
8324 } else {
8325 len = asc_prt_line(cp, leftlen, " %X:N", i);
8327 ASC_PRT_NEXT();
8329 len = asc_prt_line(cp, leftlen, "\n");
8330 ASC_PRT_NEXT();
8332 len = asc_prt_line(cp, leftlen,
8333 " Synchronous Transfer:");
8334 ASC_PRT_NEXT();
8335 for (i = 0; i <= ASC_MAX_TID; i++) {
8336 if ((chip_scsi_id == i) ||
8337 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8338 continue;
8340 len = asc_prt_line(cp, leftlen, " %X:%c",
8341 i, (v->sdtr_done & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8342 ASC_PRT_NEXT();
8344 len = asc_prt_line(cp, leftlen, "\n");
8345 ASC_PRT_NEXT();
8347 for (i = 0; i <= ASC_MAX_TID; i++) {
8348 uchar syn_period_ix;
8350 if ((chip_scsi_id == i) ||
8351 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
8352 ((v->init_sdtr & ADV_TID_TO_TIDMASK(i)) == 0)) {
8353 continue;
8356 len = asc_prt_line(cp, leftlen, " %X:", i);
8357 ASC_PRT_NEXT();
8359 if ((boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET) == 0)
8361 len = asc_prt_line(cp, leftlen, " Asynchronous");
8362 ASC_PRT_NEXT();
8363 } else
8365 syn_period_ix =
8366 (boardp->sdtr_data[i] >> 4) & (v->max_sdtr_index - 1);
8368 len = asc_prt_line(cp, leftlen,
8369 " Transfer Period Factor: %d (%d.%d Mhz),",
8370 v->sdtr_period_tbl[syn_period_ix],
8371 250 / v->sdtr_period_tbl[syn_period_ix],
8372 ASC_TENTHS(250, v->sdtr_period_tbl[syn_period_ix]));
8373 ASC_PRT_NEXT();
8375 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
8376 boardp->sdtr_data[i] & ASC_SYN_MAX_OFFSET);
8377 ASC_PRT_NEXT();
8380 if ((v->sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8381 len = asc_prt_line(cp, leftlen, "*\n");
8382 renegotiate = 1;
8383 } else
8385 len = asc_prt_line(cp, leftlen, "\n");
8387 ASC_PRT_NEXT();
8390 if (renegotiate)
8392 len = asc_prt_line(cp, leftlen,
8393 " * = Re-negotiation pending before next command.\n");
8394 ASC_PRT_NEXT();
8397 return totlen;
8401 * asc_prt_adv_board_info()
8403 * Print dynamic board configuration information.
8405 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8406 * cf. asc_prt_line().
8408 * Return the number of characters copied into 'cp'. No more than
8409 * 'cplen' characters will be copied to 'cp'.
8411 STATIC int
8412 asc_prt_adv_board_info(struct Scsi_Host *shp, char *cp, int cplen)
8414 asc_board_t *boardp;
8415 int leftlen;
8416 int totlen;
8417 int len;
8418 int i;
8419 ADV_DVC_VAR *v;
8420 ADV_DVC_CFG *c;
8421 AdvPortAddr iop_base;
8422 ushort chip_scsi_id;
8423 ushort lramword;
8424 uchar lrambyte;
8425 ushort tagqng_able;
8426 ushort sdtr_able, wdtr_able;
8427 ushort wdtr_done, sdtr_done;
8428 ushort period = 0;
8429 int renegotiate = 0;
8431 boardp = ASC_BOARDP(shp);
8432 v = &boardp->dvc_var.adv_dvc_var;
8433 c = &boardp->dvc_cfg.adv_dvc_cfg;
8434 iop_base = v->iop_base;
8435 chip_scsi_id = v->chip_scsi_id;
8437 leftlen = cplen;
8438 totlen = len = 0;
8440 len = asc_prt_line(cp, leftlen,
8441 "\nAdv Library Configuration and Statistics for AdvanSys SCSI Host %d:\n",
8442 shp->host_no);
8443 ASC_PRT_NEXT();
8445 len = asc_prt_line(cp, leftlen,
8446 " iop_base 0x%lx, cable_detect: %X, err_code %u\n",
8447 v->iop_base,
8448 AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1) & CABLE_DETECT,
8449 v->err_code);
8450 ASC_PRT_NEXT();
8452 len = asc_prt_line(cp, leftlen,
8453 " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n",
8454 c->chip_version, c->lib_version, c->mcode_date, c->mcode_version);
8455 ASC_PRT_NEXT();
8457 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
8458 len = asc_prt_line(cp, leftlen,
8459 " Queuing Enabled:");
8460 ASC_PRT_NEXT();
8461 for (i = 0; i <= ADV_MAX_TID; i++) {
8462 if ((chip_scsi_id == i) ||
8463 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8464 continue;
8467 len = asc_prt_line(cp, leftlen, " %X:%c",
8468 i, (tagqng_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8469 ASC_PRT_NEXT();
8471 len = asc_prt_line(cp, leftlen, "\n");
8472 ASC_PRT_NEXT();
8474 len = asc_prt_line(cp, leftlen,
8475 " Queue Limit:");
8476 ASC_PRT_NEXT();
8477 for (i = 0; i <= ADV_MAX_TID; i++) {
8478 if ((chip_scsi_id == i) ||
8479 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8480 continue;
8483 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + i, lrambyte);
8485 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
8486 ASC_PRT_NEXT();
8488 len = asc_prt_line(cp, leftlen, "\n");
8489 ASC_PRT_NEXT();
8491 len = asc_prt_line(cp, leftlen,
8492 " Command Pending:");
8493 ASC_PRT_NEXT();
8494 for (i = 0; i <= ADV_MAX_TID; i++) {
8495 if ((chip_scsi_id == i) ||
8496 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8497 continue;
8500 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_QUEUED_CMD + i, lrambyte);
8502 len = asc_prt_line(cp, leftlen, " %X:%d", i, lrambyte);
8503 ASC_PRT_NEXT();
8505 len = asc_prt_line(cp, leftlen, "\n");
8506 ASC_PRT_NEXT();
8508 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
8509 len = asc_prt_line(cp, leftlen,
8510 " Wide Enabled:");
8511 ASC_PRT_NEXT();
8512 for (i = 0; i <= ADV_MAX_TID; i++) {
8513 if ((chip_scsi_id == i) ||
8514 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8515 continue;
8518 len = asc_prt_line(cp, leftlen, " %X:%c",
8519 i, (wdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8520 ASC_PRT_NEXT();
8522 len = asc_prt_line(cp, leftlen, "\n");
8523 ASC_PRT_NEXT();
8525 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, wdtr_done);
8526 len = asc_prt_line(cp, leftlen,
8527 " Transfer Bit Width:");
8528 ASC_PRT_NEXT();
8529 for (i = 0; i <= ADV_MAX_TID; i++) {
8530 if ((chip_scsi_id == i) ||
8531 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8532 continue;
8535 AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
8536 lramword);
8538 len = asc_prt_line(cp, leftlen, " %X:%d",
8539 i, (lramword & 0x8000) ? 16 : 8);
8540 ASC_PRT_NEXT();
8542 if ((wdtr_able & ADV_TID_TO_TIDMASK(i)) &&
8543 (wdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8544 len = asc_prt_line(cp, leftlen, "*");
8545 ASC_PRT_NEXT();
8546 renegotiate = 1;
8549 len = asc_prt_line(cp, leftlen, "\n");
8550 ASC_PRT_NEXT();
8552 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
8553 len = asc_prt_line(cp, leftlen,
8554 " Synchronous Enabled:");
8555 ASC_PRT_NEXT();
8556 for (i = 0; i <= ADV_MAX_TID; i++) {
8557 if ((chip_scsi_id == i) ||
8558 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0)) {
8559 continue;
8562 len = asc_prt_line(cp, leftlen, " %X:%c",
8563 i, (sdtr_able & ADV_TID_TO_TIDMASK(i)) ? 'Y' : 'N');
8564 ASC_PRT_NEXT();
8566 len = asc_prt_line(cp, leftlen, "\n");
8567 ASC_PRT_NEXT();
8569 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, sdtr_done);
8570 for (i = 0; i <= ADV_MAX_TID; i++) {
8572 AdvReadWordLram(iop_base, ASC_MC_DEVICE_HSHK_CFG_TABLE + (2 * i),
8573 lramword);
8574 lramword &= ~0x8000;
8576 if ((chip_scsi_id == i) ||
8577 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(i)) == 0) ||
8578 ((sdtr_able & ADV_TID_TO_TIDMASK(i)) == 0)) {
8579 continue;
8582 len = asc_prt_line(cp, leftlen, " %X:", i);
8583 ASC_PRT_NEXT();
8585 if ((lramword & 0x1F) == 0) /* Check for REQ/ACK Offset 0. */
8587 len = asc_prt_line(cp, leftlen, " Asynchronous");
8588 ASC_PRT_NEXT();
8589 } else
8591 len = asc_prt_line(cp, leftlen, " Transfer Period Factor: ");
8592 ASC_PRT_NEXT();
8594 if ((lramword & 0x1F00) == 0x1100) /* 80 Mhz */
8596 len = asc_prt_line(cp, leftlen, "9 (80.0 Mhz),");
8597 ASC_PRT_NEXT();
8598 } else if ((lramword & 0x1F00) == 0x1000) /* 40 Mhz */
8600 len = asc_prt_line(cp, leftlen, "10 (40.0 Mhz),");
8601 ASC_PRT_NEXT();
8602 } else /* 20 Mhz or below. */
8604 period = (((lramword >> 8) * 25) + 50)/4;
8606 if (period == 0) /* Should never happen. */
8608 len = asc_prt_line(cp, leftlen, "%d (? Mhz), ");
8609 ASC_PRT_NEXT();
8610 } else
8612 len = asc_prt_line(cp, leftlen,
8613 "%d (%d.%d Mhz),",
8614 period, 250/period, ASC_TENTHS(250, period));
8615 ASC_PRT_NEXT();
8619 len = asc_prt_line(cp, leftlen, " REQ/ACK Offset: %d",
8620 lramword & 0x1F);
8621 ASC_PRT_NEXT();
8624 if ((sdtr_done & ADV_TID_TO_TIDMASK(i)) == 0) {
8625 len = asc_prt_line(cp, leftlen, "*\n");
8626 renegotiate = 1;
8627 } else
8629 len = asc_prt_line(cp, leftlen, "\n");
8631 ASC_PRT_NEXT();
8634 if (renegotiate)
8636 len = asc_prt_line(cp, leftlen,
8637 " * = Re-negotiation pending before next command.\n");
8638 ASC_PRT_NEXT();
8641 return totlen;
8645 * asc_proc_copy()
8647 * Copy proc information to a read buffer taking into account the current
8648 * read offset in the file and the remaining space in the read buffer.
8650 STATIC int
8651 asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
8652 char *cp, int cplen)
8654 int cnt = 0;
8656 ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
8657 (unsigned) offset, (unsigned) advoffset, cplen);
8658 if (offset <= advoffset) {
8659 /* Read offset below current offset, copy everything. */
8660 cnt = min(cplen, leftlen);
8661 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
8662 (ulong) curbuf, (ulong) cp, cnt);
8663 memcpy(curbuf, cp, cnt);
8664 } else if (offset < advoffset + cplen) {
8665 /* Read offset within current range, partial copy. */
8666 cnt = (advoffset + cplen) - offset;
8667 cp = (cp + cplen) - cnt;
8668 cnt = min(cnt, leftlen);
8669 ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n",
8670 (ulong) curbuf, (ulong) cp, cnt);
8671 memcpy(curbuf, cp, cnt);
8673 return cnt;
8677 * asc_prt_line()
8679 * If 'cp' is NULL print to the console, otherwise print to a buffer.
8681 * Return 0 if printing to the console, otherwise return the number of
8682 * bytes written to the buffer.
8684 * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack
8685 * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes.
8687 STATIC int
8688 asc_prt_line(char *buf, int buflen, char *fmt, ...)
8690 va_list args;
8691 int ret;
8692 char s[ASC_PRTLINE_SIZE];
8694 va_start(args, fmt);
8695 ret = vsprintf(s, fmt, args);
8696 ASC_ASSERT(ret < ASC_PRTLINE_SIZE);
8697 if (buf == NULL) {
8698 (void) printk(s);
8699 ret = 0;
8700 } else {
8701 ret = min(buflen, ret);
8702 memcpy(buf, s, ret);
8704 va_end(args);
8705 return ret;
8707 #endif /* CONFIG_PROC_FS */
8711 * --- Functions Required by the Asc Library
8715 * Delay for 'n' milliseconds. Don't use the 'jiffies'
8716 * global variable which is incremented once every 5 ms
8717 * from a timer interrupt, because this function may be
8718 * called when interrupts are disabled.
8720 STATIC void
8721 DvcSleepMilliSecond(ADV_DCNT n)
8723 ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong) n);
8724 mdelay(n);
8728 * Currently and inline noop but leave as a placeholder.
8729 * Leave DvcEnterCritical() as a noop placeholder.
8731 STATIC inline ulong
8732 DvcEnterCritical(void)
8734 return 0;
8738 * Critical sections are all protected by the board spinlock.
8739 * Leave DvcLeaveCritical() as a noop placeholder.
8741 STATIC inline void
8742 DvcLeaveCritical(ulong flags)
8744 return;
8748 * void
8749 * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
8751 * Calling/Exit State:
8752 * none
8754 * Description:
8755 * Output an ASC_SCSI_Q structure to the chip
8757 STATIC void
8758 DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words)
8760 int i;
8762 ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words);
8763 AscSetChipLramAddr(iop_base, s_addr);
8764 for (i = 0; i < 2 * words; i += 2) {
8765 if (i == 4 || i == 20) {
8766 continue;
8768 outpw(iop_base + IOP_RAM_DATA,
8769 ((ushort) outbuf[i + 1] << 8) | outbuf[i]);
8774 * void
8775 * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
8777 * Calling/Exit State:
8778 * none
8780 * Description:
8781 * Input an ASC_QDONE_INFO structure from the chip
8783 STATIC void
8784 DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words)
8786 int i;
8787 ushort word;
8789 AscSetChipLramAddr(iop_base, s_addr);
8790 for (i = 0; i < 2 * words; i += 2) {
8791 if (i == 10) {
8792 continue;
8794 word = inpw(iop_base + IOP_RAM_DATA);
8795 inbuf[i] = word & 0xff;
8796 inbuf[i + 1] = (word >> 8) & 0xff;
8798 ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words);
8802 * Read a PCI configuration byte.
8804 STATIC uchar __init
8805 DvcReadPCIConfigByte(
8806 ASC_DVC_VAR *asc_dvc,
8807 ushort offset)
8809 #ifdef CONFIG_PCI
8810 uchar byte_data;
8811 pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
8812 return byte_data;
8813 #else /* !defined(CONFIG_PCI) */
8814 return 0;
8815 #endif /* !defined(CONFIG_PCI) */
8819 * Write a PCI configuration byte.
8821 STATIC void __init
8822 DvcWritePCIConfigByte(
8823 ASC_DVC_VAR *asc_dvc,
8824 ushort offset,
8825 uchar byte_data)
8827 #ifdef CONFIG_PCI
8828 pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
8829 #endif /* CONFIG_PCI */
8833 * Return the BIOS address of the adapter at the specified
8834 * I/O port and with the specified bus type.
8836 STATIC ushort __init
8837 AscGetChipBiosAddress(
8838 PortAddr iop_base,
8839 ushort bus_type)
8841 ushort cfg_lsw;
8842 ushort bios_addr;
8845 * The PCI BIOS is re-located by the motherboard BIOS. Because
8846 * of this the driver can not determine where a PCI BIOS is
8847 * loaded and executes.
8849 if (bus_type & ASC_IS_PCI)
8851 return(0);
8854 #ifdef CONFIG_ISA
8855 if((bus_type & ASC_IS_EISA) != 0)
8857 cfg_lsw = AscGetEisaChipCfg(iop_base);
8858 cfg_lsw &= 0x000F;
8859 bios_addr = (ushort)(ASC_BIOS_MIN_ADDR +
8860 (cfg_lsw * ASC_BIOS_BANK_SIZE));
8861 return(bios_addr);
8862 }/* if */
8863 #endif /* CONFIG_ISA */
8865 cfg_lsw = AscGetChipCfgLsw(iop_base);
8868 * ISA PnP uses the top bit as the 32K BIOS flag
8870 if (bus_type == ASC_IS_ISAPNP)
8872 cfg_lsw &= 0x7FFF;
8873 }/* if */
8875 bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) +
8876 ASC_BIOS_MIN_ADDR);
8877 return(bios_addr);
8882 * --- Functions Required by the Adv Library
8886 * DvcGetPhyAddr()
8888 * Return the physical address of 'vaddr' and set '*lenp' to the
8889 * number of physically contiguous bytes that follow 'vaddr'.
8890 * 'flag' indicates the type of structure whose physical address
8891 * is being translated.
8893 * Note: Because Linux currently doesn't page the kernel and all
8894 * kernel buffers are physically contiguous, leave '*lenp' unchanged.
8896 ADV_PADDR
8897 DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq,
8898 uchar *vaddr, ADV_SDCNT *lenp, int flag)
8900 ADV_PADDR paddr;
8902 paddr = virt_to_bus(vaddr);
8904 ASC_DBG4(4,
8905 "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n",
8906 (ulong) vaddr, (ulong) lenp, (ulong) *((ulong *) lenp), (ulong) paddr);
8908 return paddr;
8912 * Read a PCI configuration byte.
8914 STATIC uchar __init
8915 DvcAdvReadPCIConfigByte(
8916 ADV_DVC_VAR *asc_dvc,
8917 ushort offset)
8919 #ifdef CONFIG_PCI
8920 uchar byte_data;
8921 pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data);
8922 return byte_data;
8923 #else /* CONFIG_PCI */
8924 return 0;
8925 #endif /* CONFIG_PCI */
8929 * Write a PCI configuration byte.
8931 STATIC void __init
8932 DvcAdvWritePCIConfigByte(
8933 ADV_DVC_VAR *asc_dvc,
8934 ushort offset,
8935 uchar byte_data)
8937 #ifdef CONFIG_PCI
8938 pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data);
8939 #else /* CONFIG_PCI */
8940 return;
8941 #endif /* CONFIG_PCI */
8945 * --- Tracing and Debugging Functions
8948 #ifdef ADVANSYS_STATS
8949 #ifdef CONFIG_PROC_FS
8951 * asc_prt_board_stats()
8953 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
8954 * cf. asc_prt_line().
8956 * Return the number of characters copied into 'cp'. No more than
8957 * 'cplen' characters will be copied to 'cp'.
8959 STATIC int
8960 asc_prt_board_stats(struct Scsi_Host *shp, char *cp, int cplen)
8962 int leftlen;
8963 int totlen;
8964 int len;
8965 struct asc_stats *s;
8966 asc_board_t *boardp;
8968 leftlen = cplen;
8969 totlen = len = 0;
8971 boardp = ASC_BOARDP(shp);
8972 s = &boardp->asc_stats;
8974 len = asc_prt_line(cp, leftlen,
8975 "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", shp->host_no);
8976 ASC_PRT_NEXT();
8978 len = asc_prt_line(cp, leftlen,
8979 " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n",
8980 s->queuecommand, s->reset, s->biosparam, s->interrupt);
8981 ASC_PRT_NEXT();
8983 len = asc_prt_line(cp, leftlen,
8984 " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n",
8985 s->callback, s->done, s->build_error, s->adv_build_noreq,
8986 s->adv_build_nosg);
8987 ASC_PRT_NEXT();
8989 len = asc_prt_line(cp, leftlen,
8990 " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n",
8991 s->exe_noerror, s->exe_busy, s->exe_error, s->exe_unknown);
8992 ASC_PRT_NEXT();
8995 * Display data transfer statistics.
8997 if (s->cont_cnt > 0) {
8998 len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt);
8999 ASC_PRT_NEXT();
9001 len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ",
9002 s->cont_xfer/2,
9003 ASC_TENTHS(s->cont_xfer, 2));
9004 ASC_PRT_NEXT();
9006 /* Contiguous transfer average size */
9007 len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n",
9008 (s->cont_xfer/2)/s->cont_cnt,
9009 ASC_TENTHS((s->cont_xfer/2), s->cont_cnt));
9010 ASC_PRT_NEXT();
9013 if (s->sg_cnt > 0) {
9015 len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ",
9016 s->sg_cnt, s->sg_elem);
9017 ASC_PRT_NEXT();
9019 len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n",
9020 s->sg_xfer/2,
9021 ASC_TENTHS(s->sg_xfer, 2));
9022 ASC_PRT_NEXT();
9024 /* Scatter gather transfer statistics */
9025 len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ",
9026 s->sg_elem/s->sg_cnt,
9027 ASC_TENTHS(s->sg_elem, s->sg_cnt));
9028 ASC_PRT_NEXT();
9030 len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ",
9031 (s->sg_xfer/2)/s->sg_elem,
9032 ASC_TENTHS((s->sg_xfer/2), s->sg_elem));
9033 ASC_PRT_NEXT();
9035 len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n",
9036 (s->sg_xfer/2)/s->sg_cnt,
9037 ASC_TENTHS((s->sg_xfer/2), s->sg_cnt));
9038 ASC_PRT_NEXT();
9042 * Display request queuing statistics.
9044 len = asc_prt_line(cp, leftlen,
9045 " Active and Waiting Request Queues (Time Unit: %d HZ):\n", HZ);
9046 ASC_PRT_NEXT();
9049 return totlen;
9053 * asc_prt_target_stats()
9055 * Note: no single line should be greater than ASC_PRTLINE_SIZE,
9056 * cf. asc_prt_line().
9058 * This is separated from asc_prt_board_stats because a full set
9059 * of targets will overflow ASC_PRTBUF_SIZE.
9061 * Return the number of characters copied into 'cp'. No more than
9062 * 'cplen' characters will be copied to 'cp'.
9064 STATIC int
9065 asc_prt_target_stats(struct Scsi_Host *shp, int tgt_id, char *cp, int cplen)
9067 int leftlen;
9068 int totlen;
9069 int len;
9070 struct asc_stats *s;
9071 ushort chip_scsi_id;
9072 asc_board_t *boardp;
9073 asc_queue_t *active;
9074 asc_queue_t *waiting;
9076 leftlen = cplen;
9077 totlen = len = 0;
9079 boardp = ASC_BOARDP(shp);
9080 s = &boardp->asc_stats;
9082 active = &ASC_BOARDP(shp)->active;
9083 waiting = &ASC_BOARDP(shp)->waiting;
9085 if (ASC_NARROW_BOARD(boardp)) {
9086 chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id;
9087 } else {
9088 chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id;
9091 if ((chip_scsi_id == tgt_id) ||
9092 ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) {
9093 return 0;
9096 do {
9097 if (active->q_tot_cnt[tgt_id] > 0 || waiting->q_tot_cnt[tgt_id] > 0) {
9098 len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id);
9099 ASC_PRT_NEXT();
9101 len = asc_prt_line(cp, leftlen,
9102 " active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n",
9103 active->q_cur_cnt[tgt_id], active->q_max_cnt[tgt_id],
9104 active->q_tot_cnt[tgt_id],
9105 active->q_min_tim[tgt_id], active->q_max_tim[tgt_id],
9106 (active->q_tot_cnt[tgt_id] == 0) ? 0 :
9107 (active->q_tot_tim[tgt_id]/active->q_tot_cnt[tgt_id]),
9108 (active->q_tot_cnt[tgt_id] == 0) ? 0 :
9109 ASC_TENTHS(active->q_tot_tim[tgt_id],
9110 active->q_tot_cnt[tgt_id]));
9111 ASC_PRT_NEXT();
9113 len = asc_prt_line(cp, leftlen,
9114 " waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n",
9115 waiting->q_cur_cnt[tgt_id], waiting->q_max_cnt[tgt_id],
9116 waiting->q_tot_cnt[tgt_id],
9117 waiting->q_min_tim[tgt_id], waiting->q_max_tim[tgt_id],
9118 (waiting->q_tot_cnt[tgt_id] == 0) ? 0 :
9119 (waiting->q_tot_tim[tgt_id]/waiting->q_tot_cnt[tgt_id]),
9120 (waiting->q_tot_cnt[tgt_id] == 0) ? 0 :
9121 ASC_TENTHS(waiting->q_tot_tim[tgt_id],
9122 waiting->q_tot_cnt[tgt_id]));
9123 ASC_PRT_NEXT();
9125 } while (0);
9127 return totlen;
9129 #endif /* CONFIG_PROC_FS */
9130 #endif /* ADVANSYS_STATS */
9132 #ifdef ADVANSYS_DEBUG
9134 * asc_prt_scsi_host()
9136 STATIC void
9137 asc_prt_scsi_host(struct Scsi_Host *s)
9139 asc_board_t *boardp;
9141 boardp = ASC_BOARDP(s);
9143 printk("Scsi_Host at addr 0x%lx\n", (ulong) s);
9144 printk(
9145 " host_busy %u, host_no %d, last_reset %d,\n",
9146 s->host_busy, s->host_no,
9147 (unsigned) s->last_reset);
9149 printk(
9150 " base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n",
9151 (ulong) s->base, (ulong) s->io_port, s->n_io_port, s->irq);
9153 printk(
9154 " dma_channel %d, this_id %d, can_queue %d,\n",
9155 s->dma_channel, s->this_id, s->can_queue);
9157 printk(
9158 " cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n",
9159 s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma);
9161 if (ASC_NARROW_BOARD(boardp)) {
9162 asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var);
9163 asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg);
9164 } else {
9165 asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var);
9166 asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg);
9171 * asc_prt_scsi_cmnd()
9173 STATIC void
9174 asc_prt_scsi_cmnd(struct scsi_cmnd *s)
9176 printk("struct scsi_cmnd at addr 0x%lx\n", (ulong) s);
9178 printk(
9179 " host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n",
9180 (ulong) s->device->host, (ulong) s->device, s->device->id, s->device->lun,
9181 s->device->channel);
9183 asc_prt_hex(" CDB", s->cmnd, s->cmd_len);
9185 printk (
9186 "sc_data_direction %u, resid %d\n",
9187 s->sc_data_direction, s->resid);
9189 printk(
9190 " use_sg %u, sglist_len %u\n",
9191 s->use_sg, s->sglist_len);
9193 printk(
9194 " serial_number 0x%x, retries %d, allowed %d\n",
9195 (unsigned) s->serial_number, s->retries, s->allowed);
9197 printk(
9198 " timeout_per_command %d\n",
9199 s->timeout_per_command);
9201 printk(
9202 " scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n",
9203 (ulong) s->scsi_done, (ulong) s->done,
9204 (ulong) s->host_scribble, s->result);
9206 printk(
9207 " tag %u, pid %u\n",
9208 (unsigned) s->tag, (unsigned) s->pid);
9212 * asc_prt_asc_dvc_var()
9214 STATIC void
9215 asc_prt_asc_dvc_var(ASC_DVC_VAR *h)
9217 printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong) h);
9219 printk(
9220 " iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n",
9221 h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
9223 printk(
9224 " bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n",
9225 h->bus_type, (ulong) h->isr_callback, (ulong) h->exe_callback,
9226 (unsigned) h->init_sdtr);
9228 printk(
9229 " sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n",
9230 (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng,
9231 (unsigned) h->unit_not_ready, (unsigned) h->chip_no);
9233 printk(
9234 " queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n",
9235 (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor,
9236 (unsigned) h->scsi_reset_wait);
9238 printk(
9239 " is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n",
9240 (unsigned) h->is_in_int, (unsigned) h->max_total_qng,
9241 (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt);
9243 printk(
9244 " last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n",
9245 (unsigned) h->last_q_shortage, (unsigned) h->init_state,
9246 (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer);
9248 printk(
9249 " cfg 0x%lx, irq_no 0x%x\n",
9250 (ulong) h->cfg, (unsigned) h->irq_no);
9254 * asc_prt_asc_dvc_cfg()
9256 STATIC void
9257 asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h)
9259 printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong) h);
9261 printk(
9262 " can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n",
9263 h->can_tagged_qng, h->cmd_qng_enabled);
9264 printk(
9265 " disc_enable 0x%x, sdtr_enable 0x%x,\n",
9266 h->disc_enable, h->sdtr_enable);
9268 printk(
9269 " chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
9270 h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
9271 h->chip_version);
9273 printk(
9274 " pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n",
9275 to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version,
9276 h->mcode_date);
9278 printk(
9279 " mcode_version %d, overrun_buf 0x%lx\n",
9280 h->mcode_version, (ulong) h->overrun_buf);
9284 * asc_prt_asc_scsi_q()
9286 STATIC void
9287 asc_prt_asc_scsi_q(ASC_SCSI_Q *q)
9289 ASC_SG_HEAD *sgp;
9290 int i;
9292 printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong) q);
9294 printk(
9295 " target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n",
9296 q->q2.target_ix, q->q1.target_lun,
9297 (ulong) q->q2.srb_ptr, q->q2.tag_code);
9299 printk(
9300 " data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
9301 (ulong) le32_to_cpu(q->q1.data_addr),
9302 (ulong) le32_to_cpu(q->q1.data_cnt),
9303 (ulong) le32_to_cpu(q->q1.sense_addr), q->q1.sense_len);
9305 printk(
9306 " cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n",
9307 (ulong) q->cdbptr, q->q2.cdb_len,
9308 (ulong) q->sg_head, q->q1.sg_queue_cnt);
9310 if (q->sg_head) {
9311 sgp = q->sg_head;
9312 printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong) sgp);
9313 printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt);
9314 for (i = 0; i < sgp->entry_cnt; i++) {
9315 printk(" [%u]: addr 0x%lx, bytes %lu\n",
9316 i, (ulong) le32_to_cpu(sgp->sg_list[i].addr),
9317 (ulong) le32_to_cpu(sgp->sg_list[i].bytes));
9324 * asc_prt_asc_qdone_info()
9326 STATIC void
9327 asc_prt_asc_qdone_info(ASC_QDONE_INFO *q)
9329 printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong) q);
9330 printk(
9331 " srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n",
9332 (ulong) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
9333 q->d2.tag_code);
9334 printk(
9335 " done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n",
9336 q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
9340 * asc_prt_adv_dvc_var()
9342 * Display an ADV_DVC_VAR structure.
9344 STATIC void
9345 asc_prt_adv_dvc_var(ADV_DVC_VAR *h)
9347 printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong) h);
9349 printk(
9350 " iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n",
9351 (ulong) h->iop_base, h->err_code, (unsigned) h->ultra_able);
9353 printk(
9354 " isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n",
9355 (ulong) h->isr_callback, (unsigned) h->sdtr_able,
9356 (unsigned) h->wdtr_able);
9358 printk(
9359 " start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n",
9360 (unsigned) h->start_motor,
9361 (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
9363 printk(
9364 " max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n",
9365 (unsigned) h->max_host_qng, (unsigned) h->max_dvc_qng,
9366 (ulong) h->carr_freelist);
9368 printk(
9369 " icq_sp 0x%lx, irq_sp 0x%lx\n",
9370 (ulong) h->icq_sp, (ulong) h->irq_sp);
9372 printk(
9373 " no_scam 0x%x, tagqng_able 0x%x\n",
9374 (unsigned) h->no_scam, (unsigned) h->tagqng_able);
9376 printk(
9377 " chip_scsi_id 0x%x, cfg 0x%lx\n",
9378 (unsigned) h->chip_scsi_id, (ulong) h->cfg);
9382 * asc_prt_adv_dvc_cfg()
9384 * Display an ADV_DVC_CFG structure.
9386 STATIC void
9387 asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h)
9389 printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong) h);
9391 printk(
9392 " disc_enable 0x%x, termination 0x%x\n",
9393 h->disc_enable, h->termination);
9395 printk(
9396 " chip_version 0x%x, mcode_date 0x%x\n",
9397 h->chip_version, h->mcode_date);
9399 printk(
9400 " mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n",
9401 h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version);
9403 printk(
9404 " control_flag 0x%x, pci_slot_info 0x%x\n",
9405 h->control_flag, h->pci_slot_info);
9409 * asc_prt_adv_scsi_req_q()
9411 * Display an ADV_SCSI_REQ_Q structure.
9413 STATIC void
9414 asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q)
9416 int sg_blk_cnt;
9417 struct asc_sg_block *sg_ptr;
9419 printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong) q);
9421 printk(
9422 " target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n",
9423 q->target_id, q->target_lun, (ulong) q->srb_ptr, q->a_flag);
9425 printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n",
9426 q->cntl, (ulong) le32_to_cpu(q->data_addr), (ulong) q->vdata_addr);
9428 printk(
9429 " data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n",
9430 (ulong) le32_to_cpu(q->data_cnt),
9431 (ulong) le32_to_cpu(q->sense_addr), q->sense_len);
9433 printk(
9434 " cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n",
9435 q->cdb_len, q->done_status, q->host_status, q->scsi_status);
9437 printk(
9438 " sg_working_ix 0x%x, target_cmd %u\n",
9439 q->sg_working_ix, q->target_cmd);
9441 printk(
9442 " scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n",
9443 (ulong) le32_to_cpu(q->scsiq_rptr),
9444 (ulong) le32_to_cpu(q->sg_real_addr), (ulong) q->sg_list_ptr);
9446 /* Display the request's ADV_SG_BLOCK structures. */
9447 if (q->sg_list_ptr != NULL)
9449 sg_blk_cnt = 0;
9450 while (1) {
9452 * 'sg_ptr' is a physical address. Convert it to a virtual
9453 * address by indexing 'sg_blk_cnt' into the virtual address
9454 * array 'sg_list_ptr'.
9456 * XXX - Assumes all SG physical blocks are virtually contiguous.
9458 sg_ptr = &(((ADV_SG_BLOCK *) (q->sg_list_ptr))[sg_blk_cnt]);
9459 asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr);
9460 if (sg_ptr->sg_ptr == 0)
9462 break;
9464 sg_blk_cnt++;
9470 * asc_prt_adv_sgblock()
9472 * Display an ADV_SG_BLOCK structure.
9474 STATIC void
9475 asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b)
9477 int i;
9479 printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n",
9480 (ulong) b, sgblockno);
9481 printk(" sg_cnt %u, sg_ptr 0x%lx\n",
9482 b->sg_cnt, (ulong) le32_to_cpu(b->sg_ptr));
9483 ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK);
9484 if (b->sg_ptr != 0)
9486 ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK);
9488 for (i = 0; i < b->sg_cnt; i++) {
9489 printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n",
9490 i, (ulong) b->sg_list[i].sg_addr, (ulong) b->sg_list[i].sg_count);
9495 * asc_prt_hex()
9497 * Print hexadecimal output in 4 byte groupings 32 bytes
9498 * or 8 double-words per line.
9500 STATIC void
9501 asc_prt_hex(char *f, uchar *s, int l)
9503 int i;
9504 int j;
9505 int k;
9506 int m;
9508 printk("%s: (%d bytes)\n", f, l);
9510 for (i = 0; i < l; i += 32) {
9512 /* Display a maximum of 8 double-words per line. */
9513 if ((k = (l - i) / 4) >= 8) {
9514 k = 8;
9515 m = 0;
9516 } else {
9517 m = (l - i) % 4;
9520 for (j = 0; j < k; j++) {
9521 printk(" %2.2X%2.2X%2.2X%2.2X",
9522 (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1],
9523 (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]);
9526 switch (m) {
9527 case 0:
9528 default:
9529 break;
9530 case 1:
9531 printk(" %2.2X",
9532 (unsigned) s[i+(j*4)]);
9533 break;
9534 case 2:
9535 printk(" %2.2X%2.2X",
9536 (unsigned) s[i+(j*4)],
9537 (unsigned) s[i+(j*4)+1]);
9538 break;
9539 case 3:
9540 printk(" %2.2X%2.2X%2.2X",
9541 (unsigned) s[i+(j*4)+1],
9542 (unsigned) s[i+(j*4)+2],
9543 (unsigned) s[i+(j*4)+3]);
9544 break;
9547 printk("\n");
9550 #endif /* ADVANSYS_DEBUG */
9553 * --- Asc Library Functions
9556 STATIC ushort __init
9557 AscGetEisaChipCfg(
9558 PortAddr iop_base)
9560 PortAddr eisa_cfg_iop;
9562 eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
9563 (PortAddr) (ASC_EISA_CFG_IOP_MASK);
9564 return (inpw(eisa_cfg_iop));
9567 STATIC uchar __init
9568 AscSetChipScsiID(
9569 PortAddr iop_base,
9570 uchar new_host_id
9573 ushort cfg_lsw;
9575 if (AscGetChipScsiID(iop_base) == new_host_id) {
9576 return (new_host_id);
9578 cfg_lsw = AscGetChipCfgLsw(iop_base);
9579 cfg_lsw &= 0xF8FF;
9580 cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID) << 8);
9581 AscSetChipCfgLsw(iop_base, cfg_lsw);
9582 return (AscGetChipScsiID(iop_base));
9585 STATIC uchar __init
9586 AscGetChipScsiCtrl(
9587 PortAddr iop_base)
9589 uchar sc;
9591 AscSetBank(iop_base, 1);
9592 sc = inp(iop_base + IOP_REG_SC);
9593 AscSetBank(iop_base, 0);
9594 return (sc);
9597 STATIC uchar __init
9598 AscGetChipVersion(
9599 PortAddr iop_base,
9600 ushort bus_type
9603 if ((bus_type & ASC_IS_EISA) != 0) {
9604 PortAddr eisa_iop;
9605 uchar revision;
9606 eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
9607 (PortAddr) ASC_EISA_REV_IOP_MASK;
9608 revision = inp(eisa_iop);
9609 return ((uchar) ((ASC_CHIP_MIN_VER_EISA - 1) + revision));
9611 return (AscGetChipVerNo(iop_base));
9614 STATIC ushort __init
9615 AscGetChipBusType(
9616 PortAddr iop_base)
9618 ushort chip_ver;
9620 chip_ver = AscGetChipVerNo(iop_base);
9621 if (
9622 (chip_ver >= ASC_CHIP_MIN_VER_VL)
9623 && (chip_ver <= ASC_CHIP_MAX_VER_VL)
9625 if (
9626 ((iop_base & 0x0C30) == 0x0C30)
9627 || ((iop_base & 0x0C50) == 0x0C50)
9629 return (ASC_IS_EISA);
9631 return (ASC_IS_VL);
9633 if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
9634 (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
9635 if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
9636 return (ASC_IS_ISAPNP);
9638 return (ASC_IS_ISA);
9639 } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
9640 (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
9641 return (ASC_IS_PCI);
9643 return (0);
9646 STATIC ASC_DCNT
9647 AscLoadMicroCode(
9648 PortAddr iop_base,
9649 ushort s_addr,
9650 uchar *mcode_buf,
9651 ushort mcode_size
9654 ASC_DCNT chksum;
9655 ushort mcode_word_size;
9656 ushort mcode_chksum;
9658 /* Write the microcode buffer starting at LRAM address 0. */
9659 mcode_word_size = (ushort) (mcode_size >> 1);
9660 AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
9661 AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
9663 chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
9664 ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong) chksum);
9665 mcode_chksum = (ushort) AscMemSumLramWord(iop_base,
9666 (ushort) ASC_CODE_SEC_BEG,
9667 (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2));
9668 ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n",
9669 (ulong) mcode_chksum);
9670 AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
9671 AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
9672 return (chksum);
9675 STATIC int
9676 AscFindSignature(
9677 PortAddr iop_base
9680 ushort sig_word;
9682 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n",
9683 iop_base, AscGetChipSignatureByte(iop_base));
9684 if (AscGetChipSignatureByte(iop_base) == (uchar) ASC_1000_ID1B) {
9685 ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n",
9686 iop_base, AscGetChipSignatureWord(iop_base));
9687 sig_word = AscGetChipSignatureWord(iop_base);
9688 if ((sig_word == (ushort) ASC_1000_ID0W) ||
9689 (sig_word == (ushort) ASC_1000_ID0W_FIX)) {
9690 return (1);
9693 return (0);
9696 STATIC PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __initdata =
9698 0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
9699 ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
9702 #ifdef CONFIG_ISA
9703 STATIC uchar _isa_pnp_inited __initdata = 0;
9705 STATIC PortAddr __init
9706 AscSearchIOPortAddr(
9707 PortAddr iop_beg,
9708 ushort bus_type)
9710 if (bus_type & ASC_IS_VL) {
9711 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
9712 if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL) {
9713 return (iop_beg);
9716 return (0);
9718 if (bus_type & ASC_IS_ISA) {
9719 if (_isa_pnp_inited == 0) {
9720 AscSetISAPNPWaitForKey();
9721 _isa_pnp_inited++;
9723 while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
9724 if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT) != 0) {
9725 return (iop_beg);
9728 return (0);
9730 if (bus_type & ASC_IS_EISA) {
9731 if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
9732 return (iop_beg);
9734 return (0);
9736 return (0);
9739 STATIC PortAddr __init
9740 AscSearchIOPortAddr11(
9741 PortAddr s_addr
9744 int i;
9745 PortAddr iop_base;
9747 for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
9748 if (_asc_def_iop_base[i] > s_addr) {
9749 break;
9752 for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
9753 iop_base = _asc_def_iop_base[i];
9754 if (check_region(iop_base, ASC_IOADR_GAP) != 0) {
9755 ASC_DBG1(1,
9756 "AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n",
9757 iop_base);
9758 continue;
9760 ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n", iop_base);
9761 if (AscFindSignature(iop_base)) {
9762 return (iop_base);
9765 return (0);
9768 STATIC void __init
9769 AscSetISAPNPWaitForKey(void)
9771 outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
9772 outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
9773 return;
9775 #endif /* CONFIG_ISA */
9777 STATIC void __init
9778 AscToggleIRQAct(
9779 PortAddr iop_base
9782 AscSetChipStatus(iop_base, CIW_IRQ_ACT);
9783 AscSetChipStatus(iop_base, 0);
9784 return;
9787 STATIC uchar __init
9788 AscGetChipIRQ(
9789 PortAddr iop_base,
9790 ushort bus_type)
9792 ushort cfg_lsw;
9793 uchar chip_irq;
9795 if ((bus_type & ASC_IS_EISA) != 0) {
9796 cfg_lsw = AscGetEisaChipCfg(iop_base);
9797 chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10);
9798 if ((chip_irq == 13) || (chip_irq > 15)) {
9799 return (0);
9801 return (chip_irq);
9803 if ((bus_type & ASC_IS_VL) != 0) {
9804 cfg_lsw = AscGetChipCfgLsw(iop_base);
9805 chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07));
9806 if ((chip_irq == 0) ||
9807 (chip_irq == 4) ||
9808 (chip_irq == 7)) {
9809 return (0);
9811 return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1)));
9813 cfg_lsw = AscGetChipCfgLsw(iop_base);
9814 chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03));
9815 if (chip_irq == 3)
9816 chip_irq += (uchar) 2;
9817 return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
9820 STATIC uchar __init
9821 AscSetChipIRQ(
9822 PortAddr iop_base,
9823 uchar irq_no,
9824 ushort bus_type)
9826 ushort cfg_lsw;
9828 if ((bus_type & ASC_IS_VL) != 0) {
9829 if (irq_no != 0) {
9830 if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) {
9831 irq_no = 0;
9832 } else {
9833 irq_no -= (uchar) ((ASC_MIN_IRQ_NO - 1));
9836 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE3);
9837 cfg_lsw |= (ushort) 0x0010;
9838 AscSetChipCfgLsw(iop_base, cfg_lsw);
9839 AscToggleIRQAct(iop_base);
9840 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE0);
9841 cfg_lsw |= (ushort) ((irq_no & 0x07) << 2);
9842 AscSetChipCfgLsw(iop_base, cfg_lsw);
9843 AscToggleIRQAct(iop_base);
9844 return (AscGetChipIRQ(iop_base, bus_type));
9846 if ((bus_type & (ASC_IS_ISA)) != 0) {
9847 if (irq_no == 15)
9848 irq_no -= (uchar) 2;
9849 irq_no -= (uchar) ASC_MIN_IRQ_NO;
9850 cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFF3);
9851 cfg_lsw |= (ushort) ((irq_no & 0x03) << 2);
9852 AscSetChipCfgLsw(iop_base, cfg_lsw);
9853 return (AscGetChipIRQ(iop_base, bus_type));
9855 return (0);
9858 #ifdef CONFIG_ISA
9859 STATIC void __init
9860 AscEnableIsaDma(
9861 uchar dma_channel)
9863 if (dma_channel < 4) {
9864 outp(0x000B, (ushort) (0xC0 | dma_channel));
9865 outp(0x000A, dma_channel);
9866 } else if (dma_channel < 8) {
9867 outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4)));
9868 outp(0x00D4, (ushort) (dma_channel - 4));
9870 return;
9872 #endif /* CONFIG_ISA */
9874 STATIC int
9875 AscIsrChipHalted(
9876 ASC_DVC_VAR *asc_dvc
9879 EXT_MSG ext_msg;
9880 EXT_MSG out_msg;
9881 ushort halt_q_addr;
9882 int sdtr_accept;
9883 ushort int_halt_code;
9884 ASC_SCSI_BIT_ID_TYPE scsi_busy;
9885 ASC_SCSI_BIT_ID_TYPE target_id;
9886 PortAddr iop_base;
9887 uchar tag_code;
9888 uchar q_status;
9889 uchar halt_qp;
9890 uchar sdtr_data;
9891 uchar target_ix;
9892 uchar q_cntl, tid_no;
9893 uchar cur_dvc_qng;
9894 uchar asyn_sdtr;
9895 uchar scsi_status;
9896 asc_board_t *boardp;
9898 ASC_ASSERT(asc_dvc->drv_ptr != NULL);
9899 boardp = asc_dvc->drv_ptr;
9901 iop_base = asc_dvc->iop_base;
9902 int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
9904 halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
9905 halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
9906 target_ix = AscReadLramByte(iop_base,
9907 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX));
9908 q_cntl = AscReadLramByte(iop_base,
9909 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL));
9910 tid_no = ASC_TIX_TO_TID(target_ix);
9911 target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no);
9912 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
9913 asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
9914 } else {
9915 asyn_sdtr = 0;
9917 if (int_halt_code == ASC_HALT_DISABLE_ASYN_USE_SYN_FIX) {
9918 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
9919 AscSetChipSDTR(iop_base, 0, tid_no);
9920 boardp->sdtr_data[tid_no] = 0;
9922 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9923 return (0);
9924 } else if (int_halt_code == ASC_HALT_ENABLE_ASYN_USE_SYN_FIX) {
9925 if (asc_dvc->pci_fix_asyn_xfer & target_id) {
9926 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
9927 boardp->sdtr_data[tid_no] = asyn_sdtr;
9929 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
9930 return (0);
9931 } else if (int_halt_code == ASC_HALT_EXTMSG_IN) {
9933 AscMemWordCopyPtrFromLram(iop_base,
9934 ASCV_MSGIN_BEG,
9935 (uchar *) &ext_msg,
9936 sizeof(EXT_MSG) >> 1);
9938 if (ext_msg.msg_type == MS_EXTEND &&
9939 ext_msg.msg_req == MS_SDTR_CODE &&
9940 ext_msg.msg_len == MS_SDTR_LEN) {
9941 sdtr_accept = TRUE;
9942 if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) {
9944 sdtr_accept = FALSE;
9945 ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET;
9947 if ((ext_msg.xfer_period <
9948 asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index]) ||
9949 (ext_msg.xfer_period >
9950 asc_dvc->sdtr_period_tbl[asc_dvc->max_sdtr_index])) {
9951 sdtr_accept = FALSE;
9952 ext_msg.xfer_period =
9953 asc_dvc->sdtr_period_tbl[asc_dvc->host_init_sdtr_index];
9955 if (sdtr_accept) {
9956 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
9957 ext_msg.req_ack_offset);
9958 if ((sdtr_data == 0xFF)) {
9960 q_cntl |= QC_MSG_OUT;
9961 asc_dvc->init_sdtr &= ~target_id;
9962 asc_dvc->sdtr_done &= ~target_id;
9963 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
9964 boardp->sdtr_data[tid_no] = asyn_sdtr;
9967 if (ext_msg.req_ack_offset == 0) {
9969 q_cntl &= ~QC_MSG_OUT;
9970 asc_dvc->init_sdtr &= ~target_id;
9971 asc_dvc->sdtr_done &= ~target_id;
9972 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
9973 } else {
9974 if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
9976 q_cntl &= ~QC_MSG_OUT;
9977 asc_dvc->sdtr_done |= target_id;
9978 asc_dvc->init_sdtr |= target_id;
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 } else {
9986 q_cntl |= QC_MSG_OUT;
9987 AscMsgOutSDTR(asc_dvc,
9988 ext_msg.xfer_period,
9989 ext_msg.req_ack_offset);
9990 asc_dvc->pci_fix_asyn_xfer &= ~target_id;
9991 sdtr_data = AscCalSDTRData(asc_dvc, ext_msg.xfer_period,
9992 ext_msg.req_ack_offset);
9993 AscSetChipSDTR(iop_base, sdtr_data, tid_no);
9994 boardp->sdtr_data[tid_no] = sdtr_data;
9995 asc_dvc->sdtr_done |= target_id;
9996 asc_dvc->init_sdtr |= target_id;
10000 AscWriteLramByte(iop_base,
10001 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10002 q_cntl);
10003 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10004 return (0);
10005 } else if (ext_msg.msg_type == MS_EXTEND &&
10006 ext_msg.msg_req == MS_WDTR_CODE &&
10007 ext_msg.msg_len == MS_WDTR_LEN) {
10009 ext_msg.wdtr_width = 0;
10010 AscMemWordCopyPtrToLram(iop_base,
10011 ASCV_MSGOUT_BEG,
10012 (uchar *) &ext_msg,
10013 sizeof(EXT_MSG) >> 1);
10014 q_cntl |= QC_MSG_OUT;
10015 AscWriteLramByte(iop_base,
10016 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10017 q_cntl);
10018 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10019 return (0);
10020 } else {
10022 ext_msg.msg_type = MESSAGE_REJECT;
10023 AscMemWordCopyPtrToLram(iop_base,
10024 ASCV_MSGOUT_BEG,
10025 (uchar *) &ext_msg,
10026 sizeof(EXT_MSG) >> 1);
10027 q_cntl |= QC_MSG_OUT;
10028 AscWriteLramByte(iop_base,
10029 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10030 q_cntl);
10031 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10032 return (0);
10034 } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
10036 q_cntl |= QC_REQ_SENSE;
10038 if ((asc_dvc->init_sdtr & target_id) != 0) {
10040 asc_dvc->sdtr_done &= ~target_id;
10042 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10043 q_cntl |= QC_MSG_OUT;
10044 AscMsgOutSDTR(asc_dvc,
10045 asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
10046 (uchar) (asc_dvc->max_sdtr_index - 1)],
10047 (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
10050 AscWriteLramByte(iop_base,
10051 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10052 q_cntl);
10054 tag_code = AscReadLramByte(iop_base,
10055 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
10056 tag_code &= 0xDC;
10057 if (
10058 (asc_dvc->pci_fix_asyn_xfer & target_id)
10059 && !(asc_dvc->pci_fix_asyn_xfer_always & target_id)
10062 tag_code |= (ASC_TAG_FLAG_DISABLE_DISCONNECT
10063 | ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX);
10066 AscWriteLramByte(iop_base,
10067 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE),
10068 tag_code);
10070 q_status = AscReadLramByte(iop_base,
10071 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS));
10072 q_status |= (QS_READY | QS_BUSY);
10073 AscWriteLramByte(iop_base,
10074 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10075 q_status);
10077 scsi_busy = AscReadLramByte(iop_base,
10078 (ushort) ASCV_SCSIBUSY_B);
10079 scsi_busy &= ~target_id;
10080 AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10082 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10083 return (0);
10084 } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
10086 AscMemWordCopyPtrFromLram(iop_base,
10087 ASCV_MSGOUT_BEG,
10088 (uchar *) &out_msg,
10089 sizeof(EXT_MSG) >> 1);
10091 if ((out_msg.msg_type == MS_EXTEND) &&
10092 (out_msg.msg_len == MS_SDTR_LEN) &&
10093 (out_msg.msg_req == MS_SDTR_CODE)) {
10095 asc_dvc->init_sdtr &= ~target_id;
10096 asc_dvc->sdtr_done &= ~target_id;
10097 AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
10098 boardp->sdtr_data[tid_no] = asyn_sdtr;
10100 q_cntl &= ~QC_MSG_OUT;
10101 AscWriteLramByte(iop_base,
10102 (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
10103 q_cntl);
10104 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10105 return (0);
10106 } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
10108 scsi_status = AscReadLramByte(iop_base,
10109 (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS));
10110 cur_dvc_qng = AscReadLramByte(iop_base,
10111 (ushort) ((ushort) ASC_QADR_BEG + (ushort) target_ix));
10112 if ((cur_dvc_qng > 0) &&
10113 (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
10115 scsi_busy = AscReadLramByte(iop_base,
10116 (ushort) ASCV_SCSIBUSY_B);
10117 scsi_busy |= target_id;
10118 AscWriteLramByte(iop_base,
10119 (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10120 asc_dvc->queue_full_or_busy |= target_id;
10122 if (scsi_status == SAM_STAT_TASK_SET_FULL) {
10123 if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
10124 cur_dvc_qng -= 1;
10125 asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
10127 AscWriteLramByte(iop_base,
10128 (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG +
10129 (ushort) tid_no),
10130 cur_dvc_qng);
10133 * Set the device queue depth to the number of
10134 * active requests when the QUEUE FULL condition
10135 * was encountered.
10137 boardp->queue_full |= target_id;
10138 boardp->queue_full_cnt[tid_no] = cur_dvc_qng;
10142 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10143 return (0);
10145 #if CC_VERY_LONG_SG_LIST
10146 else if (int_halt_code == ASC_HALT_HOST_COPY_SG_LIST_TO_RISC)
10148 uchar q_no;
10149 ushort q_addr;
10150 uchar sg_wk_q_no;
10151 uchar first_sg_wk_q_no;
10152 ASC_SCSI_Q *scsiq; /* Ptr to driver request. */
10153 ASC_SG_HEAD *sg_head; /* Ptr to driver SG request. */
10154 ASC_SG_LIST_Q scsi_sg_q; /* Structure written to queue. */
10155 ushort sg_list_dwords;
10156 ushort sg_entry_cnt;
10157 uchar next_qp;
10158 int i;
10160 q_no = AscReadLramByte(iop_base, (ushort) ASCV_REQ_SG_LIST_QP);
10161 if (q_no == ASC_QLINK_END)
10163 return(0);
10166 q_addr = ASC_QNO_TO_QADDR(q_no);
10169 * Convert the request's SRB pointer to a host ASC_SCSI_REQ
10170 * structure pointer using a macro provided by the driver.
10171 * The ASC_SCSI_REQ pointer provides a pointer to the
10172 * host ASC_SG_HEAD structure.
10174 /* Read request's SRB pointer. */
10175 scsiq = (ASC_SCSI_Q *)
10176 ASC_SRB2SCSIQ(
10177 ASC_U32_TO_VADDR(AscReadLramDWord(iop_base,
10178 (ushort) (q_addr + ASC_SCSIQ_D_SRBPTR))));
10181 * Get request's first and working SG queue.
10183 sg_wk_q_no = AscReadLramByte(iop_base,
10184 (ushort) (q_addr + ASC_SCSIQ_B_SG_WK_QP));
10186 first_sg_wk_q_no = AscReadLramByte(iop_base,
10187 (ushort) (q_addr + ASC_SCSIQ_B_FIRST_SG_WK_QP));
10190 * Reset request's working SG queue back to the
10191 * first SG queue.
10193 AscWriteLramByte(iop_base,
10194 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SG_WK_QP),
10195 first_sg_wk_q_no);
10197 sg_head = scsiq->sg_head;
10200 * Set sg_entry_cnt to the number of SG elements
10201 * that will be completed on this interrupt.
10203 * Note: The allocated SG queues contain ASC_MAX_SG_LIST - 1
10204 * SG elements. The data_cnt and data_addr fields which
10205 * add 1 to the SG element capacity are not used when
10206 * restarting SG handling after a halt.
10208 if (scsiq->remain_sg_entry_cnt > (ASC_MAX_SG_LIST - 1))
10210 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
10213 * Keep track of remaining number of SG elements that will
10214 * need to be handled on the next interrupt.
10216 scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1);
10217 } else
10219 sg_entry_cnt = scsiq->remain_sg_entry_cnt;
10220 scsiq->remain_sg_entry_cnt = 0;
10224 * Copy SG elements into the list of allocated SG queues.
10226 * Last index completed is saved in scsiq->next_sg_index.
10228 next_qp = first_sg_wk_q_no;
10229 q_addr = ASC_QNO_TO_QADDR(next_qp);
10230 scsi_sg_q.sg_head_qp = q_no;
10231 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
10232 for( i = 0; i < sg_head->queue_cnt; i++)
10234 scsi_sg_q.seq_no = i + 1;
10235 if (sg_entry_cnt > ASC_SG_LIST_PER_Q)
10237 sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
10238 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
10240 * After very first SG queue RISC FW uses next
10241 * SG queue first element then checks sg_list_cnt
10242 * against zero and then decrements, so set
10243 * sg_list_cnt 1 less than number of SG elements
10244 * in each SG queue.
10246 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
10247 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
10248 } else {
10250 * This is the last SG queue in the list of
10251 * allocated SG queues. If there are more
10252 * SG elements than will fit in the allocated
10253 * queues, then set the QCSG_SG_XFER_MORE flag.
10255 if (scsiq->remain_sg_entry_cnt != 0)
10257 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
10258 } else
10260 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
10262 /* equals sg_entry_cnt * 2 */
10263 sg_list_dwords = sg_entry_cnt << 1;
10264 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
10265 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
10266 sg_entry_cnt = 0;
10269 scsi_sg_q.q_no = next_qp;
10270 AscMemWordCopyPtrToLram(iop_base,
10271 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
10272 (uchar *) &scsi_sg_q,
10273 sizeof(ASC_SG_LIST_Q) >> 1);
10275 AscMemDWordCopyPtrToLram(iop_base,
10276 q_addr + ASC_SGQ_LIST_BEG,
10277 (uchar *) &sg_head->sg_list[scsiq->next_sg_index],
10278 sg_list_dwords);
10280 scsiq->next_sg_index += ASC_SG_LIST_PER_Q;
10283 * If the just completed SG queue contained the
10284 * last SG element, then no more SG queues need
10285 * to be written.
10287 if (scsi_sg_q.cntl & QCSG_SG_XFER_END)
10289 break;
10292 next_qp = AscReadLramByte( iop_base,
10293 ( ushort )( q_addr+ASC_SCSIQ_B_FWD ) );
10294 q_addr = ASC_QNO_TO_QADDR( next_qp );
10298 * Clear the halt condition so the RISC will be restarted
10299 * after the return.
10301 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
10302 return(0);
10304 #endif /* CC_VERY_LONG_SG_LIST */
10305 return (0);
10308 STATIC uchar
10309 _AscCopyLramScsiDoneQ(
10310 PortAddr iop_base,
10311 ushort q_addr,
10312 ASC_QDONE_INFO * scsiq,
10313 ASC_DCNT max_dma_count
10316 ushort _val;
10317 uchar sg_queue_cnt;
10319 DvcGetQinfo(iop_base,
10320 q_addr + ASC_SCSIQ_DONE_INFO_BEG,
10321 (uchar *) scsiq,
10322 (sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2);
10324 _val = AscReadLramWord(iop_base,
10325 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS));
10326 scsiq->q_status = (uchar) _val;
10327 scsiq->q_no = (uchar) (_val >> 8);
10328 _val = AscReadLramWord(iop_base,
10329 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL));
10330 scsiq->cntl = (uchar) _val;
10331 sg_queue_cnt = (uchar) (_val >> 8);
10332 _val = AscReadLramWord(iop_base,
10333 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN));
10334 scsiq->sense_len = (uchar) _val;
10335 scsiq->extra_bytes = (uchar) (_val >> 8);
10338 * Read high word of remain bytes from alternate location.
10340 scsiq->remain_bytes = (((ADV_DCNT) AscReadLramWord( iop_base,
10341 (ushort) (q_addr+ (ushort) ASC_SCSIQ_W_ALT_DC1))) << 16);
10343 * Read low word of remain bytes from original location.
10345 scsiq->remain_bytes += AscReadLramWord(iop_base,
10346 (ushort) (q_addr+ (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT));
10348 scsiq->remain_bytes &= max_dma_count;
10349 return (sg_queue_cnt);
10352 STATIC int
10353 AscIsrQDone(
10354 ASC_DVC_VAR *asc_dvc
10357 uchar next_qp;
10358 uchar n_q_used;
10359 uchar sg_list_qp;
10360 uchar sg_queue_cnt;
10361 uchar q_cnt;
10362 uchar done_q_tail;
10363 uchar tid_no;
10364 ASC_SCSI_BIT_ID_TYPE scsi_busy;
10365 ASC_SCSI_BIT_ID_TYPE target_id;
10366 PortAddr iop_base;
10367 ushort q_addr;
10368 ushort sg_q_addr;
10369 uchar cur_target_qng;
10370 ASC_QDONE_INFO scsiq_buf;
10371 ASC_QDONE_INFO *scsiq;
10372 int false_overrun;
10373 ASC_ISR_CALLBACK asc_isr_callback;
10375 iop_base = asc_dvc->iop_base;
10376 asc_isr_callback = asc_dvc->isr_callback;
10377 n_q_used = 1;
10378 scsiq = (ASC_QDONE_INFO *) & scsiq_buf;
10379 done_q_tail = (uchar) AscGetVarDoneQTail(iop_base);
10380 q_addr = ASC_QNO_TO_QADDR(done_q_tail);
10381 next_qp = AscReadLramByte(iop_base,
10382 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD));
10383 if (next_qp != ASC_QLINK_END) {
10384 AscPutVarDoneQTail(iop_base, next_qp);
10385 q_addr = ASC_QNO_TO_QADDR(next_qp);
10386 sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq,
10387 asc_dvc->max_dma_count);
10388 AscWriteLramByte(iop_base,
10389 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10390 (uchar) (scsiq->q_status & (uchar) ~ (QS_READY | QS_ABORTED)));
10391 tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
10392 target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
10393 if ((scsiq->cntl & QC_SG_HEAD) != 0) {
10394 sg_q_addr = q_addr;
10395 sg_list_qp = next_qp;
10396 for (q_cnt = 0; q_cnt < sg_queue_cnt; q_cnt++) {
10397 sg_list_qp = AscReadLramByte(iop_base,
10398 (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_FWD));
10399 sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
10400 if (sg_list_qp == ASC_QLINK_END) {
10401 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_Q_LINKS);
10402 scsiq->d3.done_stat = QD_WITH_ERROR;
10403 scsiq->d3.host_stat = QHSTA_D_QDONE_SG_LIST_CORRUPTED;
10404 goto FATAL_ERR_QDONE;
10406 AscWriteLramByte(iop_base,
10407 (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
10408 QS_FREE);
10410 n_q_used = sg_queue_cnt + 1;
10411 AscPutVarDoneQTail(iop_base, sg_list_qp);
10413 if (asc_dvc->queue_full_or_busy & target_id) {
10414 cur_target_qng = AscReadLramByte(iop_base,
10415 (ushort) ((ushort) ASC_QADR_BEG + (ushort) scsiq->d2.target_ix));
10416 if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
10417 scsi_busy = AscReadLramByte(iop_base,
10418 (ushort) ASCV_SCSIBUSY_B);
10419 scsi_busy &= ~target_id;
10420 AscWriteLramByte(iop_base,
10421 (ushort) ASCV_SCSIBUSY_B, scsi_busy);
10422 asc_dvc->queue_full_or_busy &= ~target_id;
10425 if (asc_dvc->cur_total_qng >= n_q_used) {
10426 asc_dvc->cur_total_qng -= n_q_used;
10427 if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
10428 asc_dvc->cur_dvc_qng[tid_no]--;
10430 } else {
10431 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
10432 scsiq->d3.done_stat = QD_WITH_ERROR;
10433 goto FATAL_ERR_QDONE;
10435 if ((scsiq->d2.srb_ptr == 0UL) ||
10436 ((scsiq->q_status & QS_ABORTED) != 0)) {
10437 return (0x11);
10438 } else if (scsiq->q_status == QS_DONE) {
10439 false_overrun = FALSE;
10440 if (scsiq->extra_bytes != 0) {
10441 scsiq->remain_bytes += (ADV_DCNT) scsiq->extra_bytes;
10443 if (scsiq->d3.done_stat == QD_WITH_ERROR) {
10444 if (scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN) {
10445 if ((scsiq->cntl & (QC_DATA_IN | QC_DATA_OUT)) == 0) {
10446 scsiq->d3.done_stat = QD_NO_ERROR;
10447 scsiq->d3.host_stat = QHSTA_NO_ERROR;
10448 } else if (false_overrun) {
10449 scsiq->d3.done_stat = QD_NO_ERROR;
10450 scsiq->d3.host_stat = QHSTA_NO_ERROR;
10452 } else if (scsiq->d3.host_stat ==
10453 QHSTA_M_HUNG_REQ_SCSI_BUS_RESET) {
10454 AscStopChip(iop_base);
10455 AscSetChipControl(iop_base,
10456 (uchar) (CC_SCSI_RESET | CC_HALT));
10457 DvcDelayNanoSecond(asc_dvc, 60000);
10458 AscSetChipControl(iop_base, CC_HALT);
10459 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10460 AscSetChipStatus(iop_base, 0);
10461 AscSetChipControl(iop_base, 0);
10464 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
10465 (*asc_isr_callback) (asc_dvc, scsiq);
10466 } else {
10467 if ((AscReadLramByte(iop_base,
10468 (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) ==
10469 START_STOP)) {
10470 asc_dvc->unit_not_ready &= ~target_id;
10471 if (scsiq->d3.done_stat != QD_NO_ERROR) {
10472 asc_dvc->start_motor &= ~target_id;
10476 return (1);
10477 } else {
10478 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
10479 FATAL_ERR_QDONE:
10480 if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
10481 (*asc_isr_callback) (asc_dvc, scsiq);
10483 return (0x80);
10486 return (0);
10489 STATIC int
10490 AscISR(
10491 ASC_DVC_VAR *asc_dvc
10494 ASC_CS_TYPE chipstat;
10495 PortAddr iop_base;
10496 ushort saved_ram_addr;
10497 uchar ctrl_reg;
10498 uchar saved_ctrl_reg;
10499 int int_pending;
10500 int status;
10501 uchar host_flag;
10503 iop_base = asc_dvc->iop_base;
10504 int_pending = FALSE;
10506 if (AscIsIntPending(iop_base) == 0)
10508 return int_pending;
10511 if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0)
10512 || (asc_dvc->isr_callback == 0)
10514 return (ERR);
10516 if (asc_dvc->in_critical_cnt != 0) {
10517 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
10518 return (ERR);
10520 if (asc_dvc->is_in_int) {
10521 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
10522 return (ERR);
10524 asc_dvc->is_in_int = TRUE;
10525 ctrl_reg = AscGetChipControl(iop_base);
10526 saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
10527 CC_SINGLE_STEP | CC_DIAG | CC_TEST));
10528 chipstat = AscGetChipStatus(iop_base);
10529 if (chipstat & CSW_SCSI_RESET_LATCH) {
10530 if (!(asc_dvc->bus_type & (ASC_IS_VL | ASC_IS_EISA))) {
10531 int i = 10;
10532 int_pending = TRUE;
10533 asc_dvc->sdtr_done = 0;
10534 saved_ctrl_reg &= (uchar) (~CC_HALT);
10535 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) &&
10536 (i-- > 0))
10538 DvcSleepMilliSecond(100);
10540 AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT));
10541 AscSetChipControl(iop_base, CC_HALT);
10542 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
10543 AscSetChipStatus(iop_base, 0);
10544 chipstat = AscGetChipStatus(iop_base);
10547 saved_ram_addr = AscGetChipLramAddr(iop_base);
10548 host_flag = AscReadLramByte(iop_base,
10549 ASCV_HOST_FLAG_B) & (uchar) (~ASC_HOST_FLAG_IN_ISR);
10550 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
10551 (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR));
10552 if ((chipstat & CSW_INT_PENDING)
10553 || (int_pending)
10555 AscAckInterrupt(iop_base);
10556 int_pending = TRUE;
10557 if ((chipstat & CSW_HALTED) &&
10558 (ctrl_reg & CC_SINGLE_STEP)) {
10559 if (AscIsrChipHalted(asc_dvc) == ERR) {
10560 goto ISR_REPORT_QDONE_FATAL_ERROR;
10561 } else {
10562 saved_ctrl_reg &= (uchar) (~CC_HALT);
10564 } else {
10565 ISR_REPORT_QDONE_FATAL_ERROR:
10566 if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
10567 while (((status = AscIsrQDone(asc_dvc)) & 0x01) != 0) {
10569 } else {
10570 do {
10571 if ((status = AscIsrQDone(asc_dvc)) == 1) {
10572 break;
10574 } while (status == 0x11);
10576 if ((status & 0x80) != 0)
10577 int_pending = ERR;
10580 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
10581 AscSetChipLramAddr(iop_base, saved_ram_addr);
10582 AscSetChipControl(iop_base, saved_ctrl_reg);
10583 asc_dvc->is_in_int = FALSE;
10584 return (int_pending);
10587 /* Microcode buffer is kept after initialization for error recovery. */
10588 STATIC uchar _asc_mcode_buf[] =
10590 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10591 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10593 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10594 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
10595 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10596 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
10597 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00,
10598 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
10599 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2, 0xC2, 0x00, 0x92, 0x80,
10600 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80,
10601 0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
10602 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8, 0xCD, 0x04, 0x4D, 0x00,
10603 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1,
10604 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88,
10605 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00, 0x84, 0x97, 0x07, 0xA6,
10606 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00,
10607 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6,
10608 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6, 0x34, 0x01, 0x00, 0x33,
10609 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04,
10610 0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23,
10611 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01, 0x00, 0x33, 0x0A, 0x00,
10612 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04,
10613 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01,
10614 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3, 0x3C, 0x01, 0x00, 0x05,
10615 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01,
10616 0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0,
10617 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00, 0xC2, 0x88, 0x06, 0x23,
10618 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0,
10619 0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61,
10620 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC, 0x4F, 0x00, 0x84, 0x97,
10621 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80,
10622 0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
10623 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88, 0x04, 0x98, 0xF0, 0x80,
10624 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6,
10625 0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95,
10626 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02, 0x07, 0xA6, 0x5A, 0x02,
10627 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96,
10628 0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC,
10629 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01, 0x6F, 0x00, 0xA5, 0x01,
10630 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02,
10631 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02,
10632 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E, 0x80, 0x63, 0x00, 0x43,
10633 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01,
10634 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82,
10635 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8, 0x00, 0x33, 0x1F, 0x00,
10636 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6,
10637 0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6,
10638 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xEE, 0x82,
10639 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8,
10640 0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98,
10641 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6, 0x3C, 0x04, 0x06, 0xA6,
10642 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83,
10643 0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33,
10644 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05, 0xFF, 0xA2, 0x7A, 0x03,
10645 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03,
10646 0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03,
10647 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6, 0xA4, 0x03, 0x00, 0xA6,
10648 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03,
10649 0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42,
10650 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95, 0xC0, 0x83, 0x00, 0x33,
10651 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23,
10652 0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
10653 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04, 0x06, 0xA6, 0x0A, 0x04,
10654 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84,
10655 0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
10656 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6, 0x38, 0x04, 0x00, 0x33,
10657 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC,
10658 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
10659 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0xA3, 0x01,
10660 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00,
10661 0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
10662 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04, 0x08, 0x23, 0x22, 0xA3,
10663 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23,
10664 0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98,
10665 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20, 0x81, 0x62, 0xE8, 0x81,
10666 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81,
10667 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23,
10668 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3, 0xF4, 0x04, 0x00, 0x33,
10669 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01,
10670 0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
10671 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85, 0x46, 0x97, 0xCD, 0x04,
10672 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85,
10673 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
10674 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x49, 0x00, 0x81, 0x01,
10675 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01,
10676 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
10677 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63, 0x07, 0xA4, 0xF8, 0x05,
10678 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0,
10679 0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
10680 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00, 0x62, 0x97, 0x04, 0x85,
10681 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0,
10682 0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
10683 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05, 0x80, 0x67, 0x80, 0x63,
10684 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23,
10685 0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
10686 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23, 0x07, 0x41, 0x83, 0x03,
10687 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6,
10688 0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
10689 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00, 0x52, 0x00, 0x06, 0x61,
10690 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01,
10691 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
10692 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23, 0xDF, 0x00, 0x06, 0xA6,
10693 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20,
10694 0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
10695 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B, 0x40, 0x0E, 0x80, 0x63,
10696 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43,
10697 0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
10698 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x07, 0xA6, 0xD6, 0x06,
10699 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6,
10700 0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
10701 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20, 0x81, 0x62, 0x04, 0x01,
10702 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33,
10703 0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
10704 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88, 0x00, 0x00, 0x80, 0x67,
10705 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61,
10706 0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
10707 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04, 0x80, 0x05, 0x81, 0x05,
10708 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01,
10709 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
10710 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01, 0xF1, 0x00, 0x70, 0x00,
10711 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00,
10712 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
10713 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1, 0xC4, 0x07, 0x00, 0x33,
10714 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01,
10715 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
10716 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x05, 0x05, 0x00, 0x63,
10717 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02,
10718 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
10719 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63, 0xF3, 0x04,
10720 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08,
10721 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
10722 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04, 0x5A, 0x88, 0x02, 0x01,
10723 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08,
10724 0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
10725 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x38, 0x2B,
10726 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09,
10727 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
10728 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32, 0x40, 0x36, 0x40, 0x3A,
10729 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3,
10730 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
10731 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01, 0xA1, 0x23, 0xA1, 0x01,
10732 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2,
10733 0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
10736 STATIC ushort _asc_mcode_size = sizeof(_asc_mcode_buf);
10737 STATIC ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
10739 #define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16
10740 STATIC uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] =
10742 INQUIRY,
10743 REQUEST_SENSE,
10744 READ_CAPACITY,
10745 READ_TOC,
10746 MODE_SELECT,
10747 MODE_SENSE,
10748 MODE_SELECT_10,
10749 MODE_SENSE_10,
10750 0xFF,
10751 0xFF,
10752 0xFF,
10753 0xFF,
10754 0xFF,
10755 0xFF,
10756 0xFF,
10757 0xFF
10760 STATIC int
10761 AscExeScsiQueue(
10762 ASC_DVC_VAR *asc_dvc,
10763 ASC_SCSI_Q *scsiq
10766 PortAddr iop_base;
10767 ulong last_int_level;
10768 int sta;
10769 int n_q_required;
10770 int disable_syn_offset_one_fix;
10771 int i;
10772 ASC_PADDR addr;
10773 ASC_EXE_CALLBACK asc_exe_callback;
10774 ushort sg_entry_cnt = 0;
10775 ushort sg_entry_cnt_minus_one = 0;
10776 uchar target_ix;
10777 uchar tid_no;
10778 uchar sdtr_data;
10779 uchar extra_bytes;
10780 uchar scsi_cmd;
10781 uchar disable_cmd;
10782 ASC_SG_HEAD *sg_head;
10783 ASC_DCNT data_cnt;
10785 iop_base = asc_dvc->iop_base;
10786 sg_head = scsiq->sg_head;
10787 asc_exe_callback = asc_dvc->exe_callback;
10788 if (asc_dvc->err_code != 0)
10789 return (ERR);
10790 if (scsiq == (ASC_SCSI_Q *) 0L) {
10791 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
10792 return (ERR);
10794 scsiq->q1.q_no = 0;
10795 if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) {
10796 scsiq->q1.extra_bytes = 0;
10798 sta = 0;
10799 target_ix = scsiq->q2.target_ix;
10800 tid_no = ASC_TIX_TO_TID(target_ix);
10801 n_q_required = 1;
10802 if (scsiq->cdbptr[0] == REQUEST_SENSE) {
10803 if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) {
10804 asc_dvc->sdtr_done &= ~scsiq->q1.target_id;
10805 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
10806 AscMsgOutSDTR(asc_dvc,
10807 asc_dvc->sdtr_period_tbl[(sdtr_data >> 4) &
10808 (uchar) (asc_dvc->max_sdtr_index - 1)],
10809 (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
10810 scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
10813 last_int_level = DvcEnterCritical();
10814 if (asc_dvc->in_critical_cnt != 0) {
10815 DvcLeaveCritical(last_int_level);
10816 AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
10817 return (ERR);
10819 asc_dvc->in_critical_cnt++;
10820 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10821 if ((sg_entry_cnt = sg_head->entry_cnt) == 0) {
10822 asc_dvc->in_critical_cnt--;
10823 DvcLeaveCritical(last_int_level);
10824 return (ERR);
10826 #if !CC_VERY_LONG_SG_LIST
10827 if (sg_entry_cnt > ASC_MAX_SG_LIST)
10829 asc_dvc->in_critical_cnt--;
10830 DvcLeaveCritical(last_int_level);
10831 return(ERR);
10833 #endif /* !CC_VERY_LONG_SG_LIST */
10834 if (sg_entry_cnt == 1) {
10835 scsiq->q1.data_addr = (ADV_PADDR) sg_head->sg_list[0].addr;
10836 scsiq->q1.data_cnt = (ADV_DCNT) sg_head->sg_list[0].bytes;
10837 scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
10839 sg_entry_cnt_minus_one = sg_entry_cnt - 1;
10841 scsi_cmd = scsiq->cdbptr[0];
10842 disable_syn_offset_one_fix = FALSE;
10843 if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) &&
10844 !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) {
10845 if (scsiq->q1.cntl & QC_SG_HEAD) {
10846 data_cnt = 0;
10847 for (i = 0; i < sg_entry_cnt; i++) {
10848 data_cnt += (ADV_DCNT) le32_to_cpu(sg_head->sg_list[i].bytes);
10850 } else {
10851 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
10853 if (data_cnt != 0UL) {
10854 if (data_cnt < 512UL) {
10855 disable_syn_offset_one_fix = TRUE;
10856 } else {
10857 for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST; i++) {
10858 disable_cmd = _syn_offset_one_disable_cmd[i];
10859 if (disable_cmd == 0xFF) {
10860 break;
10862 if (scsi_cmd == disable_cmd) {
10863 disable_syn_offset_one_fix = TRUE;
10864 break;
10870 if (disable_syn_offset_one_fix) {
10871 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG;
10872 scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX |
10873 ASC_TAG_FLAG_DISABLE_DISCONNECT);
10874 } else {
10875 scsiq->q2.tag_code &= 0x27;
10877 if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
10878 if (asc_dvc->bug_fix_cntl) {
10879 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10880 if ((scsi_cmd == READ_6) ||
10881 (scsi_cmd == READ_10)) {
10882 addr =
10883 (ADV_PADDR) le32_to_cpu(
10884 sg_head->sg_list[sg_entry_cnt_minus_one].addr) +
10885 (ADV_DCNT) le32_to_cpu(
10886 sg_head->sg_list[sg_entry_cnt_minus_one].bytes);
10887 extra_bytes = (uchar) ((ushort) addr & 0x0003);
10888 if ((extra_bytes != 0) &&
10889 ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
10890 == 0)) {
10891 scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
10892 scsiq->q1.extra_bytes = extra_bytes;
10893 data_cnt = le32_to_cpu(
10894 sg_head->sg_list[sg_entry_cnt_minus_one].bytes);
10895 data_cnt -= (ASC_DCNT) extra_bytes;
10896 sg_head->sg_list[sg_entry_cnt_minus_one].bytes =
10897 cpu_to_le32(data_cnt);
10902 sg_head->entry_to_copy = sg_head->entry_cnt;
10903 #if CC_VERY_LONG_SG_LIST
10905 * Set the sg_entry_cnt to the maximum possible. The rest of
10906 * the SG elements will be copied when the RISC completes the
10907 * SG elements that fit and halts.
10909 if (sg_entry_cnt > ASC_MAX_SG_LIST)
10911 sg_entry_cnt = ASC_MAX_SG_LIST;
10913 #endif /* CC_VERY_LONG_SG_LIST */
10914 n_q_required = AscSgListToQueue(sg_entry_cnt);
10915 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >=
10916 (uint) n_q_required) || ((scsiq->q1.cntl & QC_URGENT) != 0)) {
10917 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
10918 n_q_required)) == 1) {
10919 asc_dvc->in_critical_cnt--;
10920 if (asc_exe_callback != 0) {
10921 (*asc_exe_callback) (asc_dvc, scsiq);
10923 DvcLeaveCritical(last_int_level);
10924 return (sta);
10927 } else {
10928 if (asc_dvc->bug_fix_cntl) {
10929 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) {
10930 if ((scsi_cmd == READ_6) ||
10931 (scsi_cmd == READ_10)) {
10932 addr = le32_to_cpu(scsiq->q1.data_addr) +
10933 le32_to_cpu(scsiq->q1.data_cnt);
10934 extra_bytes = (uchar) ((ushort) addr & 0x0003);
10935 if ((extra_bytes != 0) &&
10936 ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES)
10937 == 0)) {
10938 data_cnt = le32_to_cpu(scsiq->q1.data_cnt);
10939 if (((ushort) data_cnt & 0x01FF) == 0) {
10940 scsiq->q2.tag_code |= ASC_TAG_FLAG_EXTRA_BYTES;
10941 data_cnt -= (ASC_DCNT) extra_bytes;
10942 scsiq->q1.data_cnt = cpu_to_le32(data_cnt);
10943 scsiq->q1.extra_bytes = extra_bytes;
10949 n_q_required = 1;
10950 if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
10951 ((scsiq->q1.cntl & QC_URGENT) != 0)) {
10952 if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
10953 n_q_required)) == 1) {
10954 asc_dvc->in_critical_cnt--;
10955 if (asc_exe_callback != 0) {
10956 (*asc_exe_callback) (asc_dvc, scsiq);
10958 DvcLeaveCritical(last_int_level);
10959 return (sta);
10963 asc_dvc->in_critical_cnt--;
10964 DvcLeaveCritical(last_int_level);
10965 return (sta);
10968 STATIC int
10969 AscSendScsiQueue(
10970 ASC_DVC_VAR *asc_dvc,
10971 ASC_SCSI_Q *scsiq,
10972 uchar n_q_required
10975 PortAddr iop_base;
10976 uchar free_q_head;
10977 uchar next_qp;
10978 uchar tid_no;
10979 uchar target_ix;
10980 int sta;
10982 iop_base = asc_dvc->iop_base;
10983 target_ix = scsiq->q2.target_ix;
10984 tid_no = ASC_TIX_TO_TID(target_ix);
10985 sta = 0;
10986 free_q_head = (uchar) AscGetVarFreeQHead(iop_base);
10987 if (n_q_required > 1) {
10988 if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
10989 free_q_head, (uchar) (n_q_required)))
10990 != (uchar) ASC_QLINK_END) {
10991 asc_dvc->last_q_shortage = 0;
10992 scsiq->sg_head->queue_cnt = n_q_required - 1;
10993 scsiq->q1.q_no = free_q_head;
10994 if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
10995 free_q_head)) == 1) {
10996 AscPutVarFreeQHead(iop_base, next_qp);
10997 asc_dvc->cur_total_qng += (uchar) (n_q_required);
10998 asc_dvc->cur_dvc_qng[tid_no]++;
11000 return (sta);
11002 } else if (n_q_required == 1) {
11003 if ((next_qp = AscAllocFreeQueue(iop_base,
11004 free_q_head)) != ASC_QLINK_END) {
11005 scsiq->q1.q_no = free_q_head;
11006 if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
11007 free_q_head)) == 1) {
11008 AscPutVarFreeQHead(iop_base, next_qp);
11009 asc_dvc->cur_total_qng++;
11010 asc_dvc->cur_dvc_qng[tid_no]++;
11012 return (sta);
11015 return (sta);
11018 STATIC int
11019 AscSgListToQueue(
11020 int sg_list
11023 int n_sg_list_qs;
11025 n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
11026 if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
11027 n_sg_list_qs++;
11028 return (n_sg_list_qs + 1);
11032 STATIC uint
11033 AscGetNumOfFreeQueue(
11034 ASC_DVC_VAR *asc_dvc,
11035 uchar target_ix,
11036 uchar n_qs
11039 uint cur_used_qs;
11040 uint cur_free_qs;
11041 ASC_SCSI_BIT_ID_TYPE target_id;
11042 uchar tid_no;
11044 target_id = ASC_TIX_TO_TARGET_ID(target_ix);
11045 tid_no = ASC_TIX_TO_TID(target_ix);
11046 if ((asc_dvc->unit_not_ready & target_id) ||
11047 (asc_dvc->queue_full_or_busy & target_id)) {
11048 return (0);
11050 if (n_qs == 1) {
11051 cur_used_qs = (uint) asc_dvc->cur_total_qng +
11052 (uint) asc_dvc->last_q_shortage +
11053 (uint) ASC_MIN_FREE_Q;
11054 } else {
11055 cur_used_qs = (uint) asc_dvc->cur_total_qng +
11056 (uint) ASC_MIN_FREE_Q;
11058 if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
11059 cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
11060 if (asc_dvc->cur_dvc_qng[tid_no] >=
11061 asc_dvc->max_dvc_qng[tid_no]) {
11062 return (0);
11064 return (cur_free_qs);
11066 if (n_qs > 1) {
11067 if ((n_qs > asc_dvc->last_q_shortage) && (n_qs <= (asc_dvc->max_total_qng - ASC_MIN_FREE_Q))) {
11068 asc_dvc->last_q_shortage = n_qs;
11071 return (0);
11074 STATIC int
11075 AscPutReadyQueue(
11076 ASC_DVC_VAR *asc_dvc,
11077 ASC_SCSI_Q *scsiq,
11078 uchar q_no
11081 ushort q_addr;
11082 uchar tid_no;
11083 uchar sdtr_data;
11084 uchar syn_period_ix;
11085 uchar syn_offset;
11086 PortAddr iop_base;
11088 iop_base = asc_dvc->iop_base;
11089 if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
11090 ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
11091 tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
11092 sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no);
11093 syn_period_ix = (sdtr_data >> 4) & (asc_dvc->max_sdtr_index - 1);
11094 syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
11095 AscMsgOutSDTR(asc_dvc,
11096 asc_dvc->sdtr_period_tbl[syn_period_ix],
11097 syn_offset);
11098 scsiq->q1.cntl |= QC_MSG_OUT;
11100 q_addr = ASC_QNO_TO_QADDR(q_no);
11101 if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
11102 scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG ;
11104 scsiq->q1.status = QS_FREE;
11105 AscMemWordCopyPtrToLram(iop_base,
11106 q_addr + ASC_SCSIQ_CDB_BEG,
11107 (uchar *) scsiq->cdbptr,
11108 scsiq->q2.cdb_len >> 1);
11110 DvcPutScsiQ(iop_base,
11111 q_addr + ASC_SCSIQ_CPY_BEG,
11112 (uchar *) &scsiq->q1.cntl,
11113 ((sizeof(ASC_SCSIQ_1) + sizeof(ASC_SCSIQ_2)) / 2) - 1);
11114 AscWriteLramWord(iop_base,
11115 (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
11116 (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY));
11117 return (1);
11120 STATIC int
11121 AscPutReadySgListQueue(
11122 ASC_DVC_VAR *asc_dvc,
11123 ASC_SCSI_Q *scsiq,
11124 uchar q_no
11127 int sta;
11128 int i;
11129 ASC_SG_HEAD *sg_head;
11130 ASC_SG_LIST_Q scsi_sg_q;
11131 ASC_DCNT saved_data_addr;
11132 ASC_DCNT saved_data_cnt;
11133 PortAddr iop_base;
11134 ushort sg_list_dwords;
11135 ushort sg_index;
11136 ushort sg_entry_cnt;
11137 ushort q_addr;
11138 uchar next_qp;
11140 iop_base = asc_dvc->iop_base;
11141 sg_head = scsiq->sg_head;
11142 saved_data_addr = scsiq->q1.data_addr;
11143 saved_data_cnt = scsiq->q1.data_cnt;
11144 scsiq->q1.data_addr = (ASC_PADDR) sg_head->sg_list[0].addr;
11145 scsiq->q1.data_cnt = (ASC_DCNT) sg_head->sg_list[0].bytes;
11146 #if CC_VERY_LONG_SG_LIST
11148 * If sg_head->entry_cnt is greater than ASC_MAX_SG_LIST
11149 * then not all SG elements will fit in the allocated queues.
11150 * The rest of the SG elements will be copied when the RISC
11151 * completes the SG elements that fit and halts.
11153 if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
11156 * Set sg_entry_cnt to be the number of SG elements that
11157 * will fit in the allocated SG queues. It is minus 1, because
11158 * the first SG element is handled above. ASC_MAX_SG_LIST is
11159 * already inflated by 1 to account for this. For example it
11160 * may be 50 which is 1 + 7 queues * 7 SG elements.
11162 sg_entry_cnt = ASC_MAX_SG_LIST - 1;
11165 * Keep track of remaining number of SG elements that will
11166 * need to be handled from a_isr.c.
11168 scsiq->remain_sg_entry_cnt = sg_head->entry_cnt - ASC_MAX_SG_LIST;
11169 } else
11171 #endif /* CC_VERY_LONG_SG_LIST */
11173 * Set sg_entry_cnt to be the number of SG elements that
11174 * will fit in the allocated SG queues. It is minus 1, because
11175 * the first SG element is handled above.
11177 sg_entry_cnt = sg_head->entry_cnt - 1;
11178 #if CC_VERY_LONG_SG_LIST
11180 #endif /* CC_VERY_LONG_SG_LIST */
11181 if (sg_entry_cnt != 0) {
11182 scsiq->q1.cntl |= QC_SG_HEAD;
11183 q_addr = ASC_QNO_TO_QADDR(q_no);
11184 sg_index = 1;
11185 scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
11186 scsi_sg_q.sg_head_qp = q_no;
11187 scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
11188 for (i = 0; i < sg_head->queue_cnt; i++) {
11189 scsi_sg_q.seq_no = i + 1;
11190 if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
11191 sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
11192 sg_entry_cnt -= ASC_SG_LIST_PER_Q;
11193 if (i == 0) {
11194 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q;
11195 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q;
11196 } else {
11197 scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
11198 scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
11200 } else {
11201 #if CC_VERY_LONG_SG_LIST
11203 * This is the last SG queue in the list of
11204 * allocated SG queues. If there are more
11205 * SG elements than will fit in the allocated
11206 * queues, then set the QCSG_SG_XFER_MORE flag.
11208 if (sg_head->entry_cnt > ASC_MAX_SG_LIST)
11210 scsi_sg_q.cntl |= QCSG_SG_XFER_MORE;
11211 } else
11213 #endif /* CC_VERY_LONG_SG_LIST */
11214 scsi_sg_q.cntl |= QCSG_SG_XFER_END;
11215 #if CC_VERY_LONG_SG_LIST
11217 #endif /* CC_VERY_LONG_SG_LIST */
11218 sg_list_dwords = sg_entry_cnt << 1;
11219 if (i == 0) {
11220 scsi_sg_q.sg_list_cnt = sg_entry_cnt;
11221 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt;
11222 } else {
11223 scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
11224 scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
11226 sg_entry_cnt = 0;
11228 next_qp = AscReadLramByte(iop_base,
11229 (ushort) (q_addr + ASC_SCSIQ_B_FWD));
11230 scsi_sg_q.q_no = next_qp;
11231 q_addr = ASC_QNO_TO_QADDR(next_qp);
11232 AscMemWordCopyPtrToLram(iop_base,
11233 q_addr + ASC_SCSIQ_SGHD_CPY_BEG,
11234 (uchar *) &scsi_sg_q,
11235 sizeof(ASC_SG_LIST_Q) >> 1);
11236 AscMemDWordCopyPtrToLram(iop_base,
11237 q_addr + ASC_SGQ_LIST_BEG,
11238 (uchar *) &sg_head->sg_list[sg_index],
11239 sg_list_dwords);
11240 sg_index += ASC_SG_LIST_PER_Q;
11241 scsiq->next_sg_index = sg_index;
11243 } else {
11244 scsiq->q1.cntl &= ~QC_SG_HEAD;
11246 sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
11247 scsiq->q1.data_addr = saved_data_addr;
11248 scsiq->q1.data_cnt = saved_data_cnt;
11249 return (sta);
11252 STATIC int
11253 AscSetRunChipSynRegAtID(
11254 PortAddr iop_base,
11255 uchar tid_no,
11256 uchar sdtr_data
11259 int sta = FALSE;
11261 if (AscHostReqRiscHalt(iop_base)) {
11262 sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
11263 AscStartChip(iop_base);
11264 return (sta);
11266 return (sta);
11269 STATIC int
11270 AscSetChipSynRegAtID(
11271 PortAddr iop_base,
11272 uchar id,
11273 uchar sdtr_data
11276 ASC_SCSI_BIT_ID_TYPE org_id;
11277 int i;
11278 int sta = TRUE;
11280 AscSetBank(iop_base, 1);
11281 org_id = AscReadChipDvcID(iop_base);
11282 for (i = 0; i <= ASC_MAX_TID; i++) {
11283 if (org_id == (0x01 << i))
11284 break;
11286 org_id = (ASC_SCSI_BIT_ID_TYPE) i;
11287 AscWriteChipDvcID(iop_base, id);
11288 if (AscReadChipDvcID(iop_base) == (0x01 << id)) {
11289 AscSetBank(iop_base, 0);
11290 AscSetChipSyn(iop_base, sdtr_data);
11291 if (AscGetChipSyn(iop_base) != sdtr_data) {
11292 sta = FALSE;
11294 } else {
11295 sta = FALSE;
11297 AscSetBank(iop_base, 1);
11298 AscWriteChipDvcID(iop_base, org_id);
11299 AscSetBank(iop_base, 0);
11300 return (sta);
11303 STATIC ushort
11304 AscInitLram(
11305 ASC_DVC_VAR *asc_dvc
11308 uchar i;
11309 ushort s_addr;
11310 PortAddr iop_base;
11311 ushort warn_code;
11313 iop_base = asc_dvc->iop_base;
11314 warn_code = 0;
11315 AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
11316 (ushort) (((int) (asc_dvc->max_total_qng + 2 + 1) * 64) >> 1)
11318 i = ASC_MIN_ACTIVE_QNO;
11319 s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
11320 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11321 (uchar) (i + 1));
11322 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11323 (uchar) (asc_dvc->max_total_qng));
11324 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11325 (uchar) i);
11326 i++;
11327 s_addr += ASC_QBLK_SIZE;
11328 for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
11329 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11330 (uchar) (i + 1));
11331 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11332 (uchar) (i - 1));
11333 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11334 (uchar) i);
11336 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
11337 (uchar) ASC_QLINK_END);
11338 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
11339 (uchar) (asc_dvc->max_total_qng - 1));
11340 AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
11341 (uchar) asc_dvc->max_total_qng);
11342 i++;
11343 s_addr += ASC_QBLK_SIZE;
11344 for (; i <= (uchar) (asc_dvc->max_total_qng + 3);
11345 i++, s_addr += ASC_QBLK_SIZE) {
11346 AscWriteLramByte(iop_base,
11347 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_FWD), i);
11348 AscWriteLramByte(iop_base,
11349 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_BWD), i);
11350 AscWriteLramByte(iop_base,
11351 (ushort) (s_addr + (ushort) ASC_SCSIQ_B_QNO), i);
11353 return (warn_code);
11356 STATIC ushort
11357 AscInitQLinkVar(
11358 ASC_DVC_VAR *asc_dvc
11361 PortAddr iop_base;
11362 int i;
11363 ushort lram_addr;
11365 iop_base = asc_dvc->iop_base;
11366 AscPutRiscVarFreeQHead(iop_base, 1);
11367 AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
11368 AscPutVarFreeQHead(iop_base, 1);
11369 AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
11370 AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
11371 (uchar) ((int) asc_dvc->max_total_qng + 1));
11372 AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
11373 (uchar) ((int) asc_dvc->max_total_qng + 2));
11374 AscWriteLramByte(iop_base, (ushort) ASCV_TOTAL_READY_Q_B,
11375 asc_dvc->max_total_qng);
11376 AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
11377 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
11378 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
11379 AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
11380 AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
11381 AscPutQDoneInProgress(iop_base, 0);
11382 lram_addr = ASC_QADR_BEG;
11383 for (i = 0; i < 32; i++, lram_addr += 2) {
11384 AscWriteLramWord(iop_base, lram_addr, 0);
11386 return (0);
11389 STATIC int
11390 AscSetLibErrorCode(
11391 ASC_DVC_VAR *asc_dvc,
11392 ushort err_code
11395 if (asc_dvc->err_code == 0) {
11396 asc_dvc->err_code = err_code;
11397 AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
11398 err_code);
11400 return (err_code);
11404 STATIC uchar
11405 AscMsgOutSDTR(
11406 ASC_DVC_VAR *asc_dvc,
11407 uchar sdtr_period,
11408 uchar sdtr_offset
11411 EXT_MSG sdtr_buf;
11412 uchar sdtr_period_index;
11413 PortAddr iop_base;
11415 iop_base = asc_dvc->iop_base;
11416 sdtr_buf.msg_type = MS_EXTEND;
11417 sdtr_buf.msg_len = MS_SDTR_LEN;
11418 sdtr_buf.msg_req = MS_SDTR_CODE;
11419 sdtr_buf.xfer_period = sdtr_period;
11420 sdtr_offset &= ASC_SYN_MAX_OFFSET;
11421 sdtr_buf.req_ack_offset = sdtr_offset;
11422 if ((sdtr_period_index =
11423 AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <=
11424 asc_dvc->max_sdtr_index) {
11425 AscMemWordCopyPtrToLram(iop_base,
11426 ASCV_MSGOUT_BEG,
11427 (uchar *) &sdtr_buf,
11428 sizeof (EXT_MSG) >> 1);
11429 return ((sdtr_period_index << 4) | sdtr_offset);
11430 } else {
11432 sdtr_buf.req_ack_offset = 0;
11433 AscMemWordCopyPtrToLram(iop_base,
11434 ASCV_MSGOUT_BEG,
11435 (uchar *) &sdtr_buf,
11436 sizeof (EXT_MSG) >> 1);
11437 return (0);
11441 STATIC uchar
11442 AscCalSDTRData(
11443 ASC_DVC_VAR *asc_dvc,
11444 uchar sdtr_period,
11445 uchar syn_offset
11448 uchar byte;
11449 uchar sdtr_period_ix;
11451 sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period);
11452 if (
11453 (sdtr_period_ix > asc_dvc->max_sdtr_index)
11455 return (0xFF);
11457 byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
11458 return (byte);
11461 STATIC void
11462 AscSetChipSDTR(
11463 PortAddr iop_base,
11464 uchar sdtr_data,
11465 uchar tid_no
11468 AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
11469 AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data);
11470 return;
11473 STATIC uchar
11474 AscGetSynPeriodIndex(
11475 ASC_DVC_VAR *asc_dvc,
11476 uchar syn_time
11479 uchar *period_table;
11480 int max_index;
11481 int min_index;
11482 int i;
11484 period_table = asc_dvc->sdtr_period_tbl;
11485 max_index = (int) asc_dvc->max_sdtr_index;
11486 min_index = (int)asc_dvc->host_init_sdtr_index;
11487 if ((syn_time <= period_table[max_index])) {
11488 for (i = min_index; i < (max_index - 1); i++) {
11489 if (syn_time <= period_table[i]) {
11490 return ((uchar) i);
11493 return ((uchar) max_index);
11494 } else {
11495 return ((uchar) (max_index + 1));
11499 STATIC uchar
11500 AscAllocFreeQueue(
11501 PortAddr iop_base,
11502 uchar free_q_head
11505 ushort q_addr;
11506 uchar next_qp;
11507 uchar q_status;
11509 q_addr = ASC_QNO_TO_QADDR(free_q_head);
11510 q_status = (uchar) AscReadLramByte(iop_base,
11511 (ushort) (q_addr + ASC_SCSIQ_B_STATUS));
11512 next_qp = AscReadLramByte(iop_base,
11513 (ushort) (q_addr + ASC_SCSIQ_B_FWD));
11514 if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) {
11515 return (next_qp);
11517 return (ASC_QLINK_END);
11520 STATIC uchar
11521 AscAllocMultipleFreeQueue(
11522 PortAddr iop_base,
11523 uchar free_q_head,
11524 uchar n_free_q
11527 uchar i;
11529 for (i = 0; i < n_free_q; i++) {
11530 if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
11531 == ASC_QLINK_END) {
11532 return (ASC_QLINK_END);
11535 return (free_q_head);
11538 STATIC int
11539 AscHostReqRiscHalt(
11540 PortAddr iop_base
11543 int count = 0;
11544 int sta = 0;
11545 uchar saved_stop_code;
11547 if (AscIsChipHalted(iop_base))
11548 return (1);
11549 saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
11550 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11551 ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP
11553 do {
11554 if (AscIsChipHalted(iop_base)) {
11555 sta = 1;
11556 break;
11558 DvcSleepMilliSecond(100);
11559 } while (count++ < 20);
11560 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
11561 return (sta);
11564 STATIC int
11565 AscStopQueueExe(
11566 PortAddr iop_base
11569 int count = 0;
11571 if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
11572 AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
11573 ASC_STOP_REQ_RISC_STOP);
11574 do {
11575 if (
11576 AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
11577 ASC_STOP_ACK_RISC_STOP) {
11578 return (1);
11580 DvcSleepMilliSecond(100);
11581 } while (count++ < 20);
11583 return (0);
11586 STATIC void
11587 DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec)
11589 udelay(micro_sec);
11592 STATIC void
11593 DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec)
11595 udelay((nano_sec + 999)/1000);
11598 #ifdef CONFIG_ISA
11599 STATIC ASC_DCNT __init
11600 AscGetEisaProductID(
11601 PortAddr iop_base)
11603 PortAddr eisa_iop;
11604 ushort product_id_high, product_id_low;
11605 ASC_DCNT product_id;
11607 eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
11608 product_id_low = inpw(eisa_iop);
11609 product_id_high = inpw(eisa_iop + 2);
11610 product_id = ((ASC_DCNT) product_id_high << 16) |
11611 (ASC_DCNT) product_id_low;
11612 return (product_id);
11615 STATIC PortAddr __init
11616 AscSearchIOPortAddrEISA(
11617 PortAddr iop_base)
11619 ASC_DCNT eisa_product_id;
11621 if (iop_base == 0) {
11622 iop_base = ASC_EISA_MIN_IOP_ADDR;
11623 } else {
11624 if (iop_base == ASC_EISA_MAX_IOP_ADDR)
11625 return (0);
11626 if ((iop_base & 0x0050) == 0x0050) {
11627 iop_base += ASC_EISA_BIG_IOP_GAP;
11628 } else {
11629 iop_base += ASC_EISA_SMALL_IOP_GAP;
11632 while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
11633 eisa_product_id = AscGetEisaProductID(iop_base);
11634 if ((eisa_product_id == ASC_EISA_ID_740) ||
11635 (eisa_product_id == ASC_EISA_ID_750)) {
11636 if (AscFindSignature(iop_base)) {
11637 inpw(iop_base + 4);
11638 return (iop_base);
11641 if (iop_base == ASC_EISA_MAX_IOP_ADDR)
11642 return (0);
11643 if ((iop_base & 0x0050) == 0x0050) {
11644 iop_base += ASC_EISA_BIG_IOP_GAP;
11645 } else {
11646 iop_base += ASC_EISA_SMALL_IOP_GAP;
11649 return (0);
11651 #endif /* CONFIG_ISA */
11653 STATIC int
11654 AscStartChip(
11655 PortAddr iop_base
11658 AscSetChipControl(iop_base, 0);
11659 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
11660 return (0);
11662 return (1);
11665 STATIC int
11666 AscStopChip(
11667 PortAddr iop_base
11670 uchar cc_val;
11672 cc_val = AscGetChipControl(iop_base) & (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
11673 AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT));
11674 AscSetChipIH(iop_base, INS_HALT);
11675 AscSetChipIH(iop_base, INS_RFLAG_WTM);
11676 if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
11677 return (0);
11679 return (1);
11682 STATIC int
11683 AscIsChipHalted(
11684 PortAddr iop_base
11687 if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
11688 if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
11689 return (1);
11692 return (0);
11695 STATIC void
11696 AscSetChipIH(
11697 PortAddr iop_base,
11698 ushort ins_code
11701 AscSetBank(iop_base, 1);
11702 AscWriteChipIH(iop_base, ins_code);
11703 AscSetBank(iop_base, 0);
11704 return;
11707 STATIC void
11708 AscAckInterrupt(
11709 PortAddr iop_base
11712 uchar host_flag;
11713 uchar risc_flag;
11714 ushort loop;
11716 loop = 0;
11717 do {
11718 risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
11719 if (loop++ > 0x7FFF) {
11720 break;
11722 } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
11723 host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT);
11724 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
11725 (uchar) (host_flag | ASC_HOST_FLAG_ACK_INT));
11726 AscSetChipStatus(iop_base, CIW_INT_ACK);
11727 loop = 0;
11728 while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
11729 AscSetChipStatus(iop_base, CIW_INT_ACK);
11730 if (loop++ > 3) {
11731 break;
11734 AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
11735 return;
11738 STATIC void
11739 AscDisableInterrupt(
11740 PortAddr iop_base
11743 ushort cfg;
11745 cfg = AscGetChipCfgLsw(iop_base);
11746 AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
11747 return;
11750 STATIC void
11751 AscEnableInterrupt(
11752 PortAddr iop_base
11755 ushort cfg;
11757 cfg = AscGetChipCfgLsw(iop_base);
11758 AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
11759 return;
11764 STATIC void
11765 AscSetBank(
11766 PortAddr iop_base,
11767 uchar bank
11770 uchar val;
11772 val = AscGetChipControl(iop_base) &
11773 (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | CC_CHIP_RESET));
11774 if (bank == 1) {
11775 val |= CC_BANK_ONE;
11776 } else if (bank == 2) {
11777 val |= CC_DIAG | CC_BANK_ONE;
11778 } else {
11779 val &= ~CC_BANK_ONE;
11781 AscSetChipControl(iop_base, val);
11782 return;
11785 STATIC int
11786 AscResetChipAndScsiBus(
11787 ASC_DVC_VAR *asc_dvc
11790 PortAddr iop_base;
11791 int i = 10;
11793 iop_base = asc_dvc->iop_base;
11794 while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) && (i-- > 0))
11796 DvcSleepMilliSecond(100);
11798 AscStopChip(iop_base);
11799 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
11800 DvcDelayNanoSecond(asc_dvc, 60000);
11801 AscSetChipIH(iop_base, INS_RFLAG_WTM);
11802 AscSetChipIH(iop_base, INS_HALT);
11803 AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
11804 AscSetChipControl(iop_base, CC_HALT);
11805 DvcSleepMilliSecond(200);
11806 AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT);
11807 AscSetChipStatus(iop_base, 0);
11808 return (AscIsChipHalted(iop_base));
11811 STATIC ASC_DCNT __init
11812 AscGetMaxDmaCount(
11813 ushort bus_type)
11815 if (bus_type & ASC_IS_ISA)
11816 return (ASC_MAX_ISA_DMA_COUNT);
11817 else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
11818 return (ASC_MAX_VL_DMA_COUNT);
11819 return (ASC_MAX_PCI_DMA_COUNT);
11822 #ifdef CONFIG_ISA
11823 STATIC ushort __init
11824 AscGetIsaDmaChannel(
11825 PortAddr iop_base)
11827 ushort channel;
11829 channel = AscGetChipCfgLsw(iop_base) & 0x0003;
11830 if (channel == 0x03)
11831 return (0);
11832 else if (channel == 0x00)
11833 return (7);
11834 return (channel + 4);
11837 STATIC ushort __init
11838 AscSetIsaDmaChannel(
11839 PortAddr iop_base,
11840 ushort dma_channel)
11842 ushort cfg_lsw;
11843 uchar value;
11845 if ((dma_channel >= 5) && (dma_channel <= 7)) {
11846 if (dma_channel == 7)
11847 value = 0x00;
11848 else
11849 value = dma_channel - 4;
11850 cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
11851 cfg_lsw |= value;
11852 AscSetChipCfgLsw(iop_base, cfg_lsw);
11853 return (AscGetIsaDmaChannel(iop_base));
11855 return (0);
11858 STATIC uchar __init
11859 AscSetIsaDmaSpeed(
11860 PortAddr iop_base,
11861 uchar speed_value)
11863 speed_value &= 0x07;
11864 AscSetBank(iop_base, 1);
11865 AscWriteChipDmaSpeed(iop_base, speed_value);
11866 AscSetBank(iop_base, 0);
11867 return (AscGetIsaDmaSpeed(iop_base));
11870 STATIC uchar __init
11871 AscGetIsaDmaSpeed(
11872 PortAddr iop_base
11875 uchar speed_value;
11877 AscSetBank(iop_base, 1);
11878 speed_value = AscReadChipDmaSpeed(iop_base);
11879 speed_value &= 0x07;
11880 AscSetBank(iop_base, 0);
11881 return (speed_value);
11883 #endif /* CONFIG_ISA */
11885 STATIC ushort __init
11886 AscReadPCIConfigWord(
11887 ASC_DVC_VAR *asc_dvc,
11888 ushort pci_config_offset)
11890 uchar lsb, msb;
11892 lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset);
11893 msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1);
11894 return ((ushort) ((msb << 8) | lsb));
11897 STATIC ushort __init
11898 AscInitGetConfig(
11899 ASC_DVC_VAR *asc_dvc
11902 ushort warn_code;
11903 PortAddr iop_base;
11904 ushort PCIDeviceID;
11905 ushort PCIVendorID;
11906 uchar PCIRevisionID;
11907 uchar prevCmdRegBits;
11909 warn_code = 0;
11910 iop_base = asc_dvc->iop_base;
11911 asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
11912 if (asc_dvc->err_code != 0) {
11913 return (UW_ERR);
11915 if (asc_dvc->bus_type == ASC_IS_PCI) {
11916 PCIVendorID = AscReadPCIConfigWord(asc_dvc,
11917 AscPCIConfigVendorIDRegister);
11919 PCIDeviceID = AscReadPCIConfigWord(asc_dvc,
11920 AscPCIConfigDeviceIDRegister);
11922 PCIRevisionID = DvcReadPCIConfigByte(asc_dvc,
11923 AscPCIConfigRevisionIDRegister);
11925 if (PCIVendorID != ASC_PCI_VENDORID) {
11926 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
11928 prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc,
11929 AscPCIConfigCommandRegister);
11931 if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) !=
11932 AscPCICmdRegBits_IOMemBusMaster) {
11933 DvcWritePCIConfigByte(asc_dvc,
11934 AscPCIConfigCommandRegister,
11935 (prevCmdRegBits |
11936 AscPCICmdRegBits_IOMemBusMaster));
11938 if ((DvcReadPCIConfigByte(asc_dvc,
11939 AscPCIConfigCommandRegister)
11940 & AscPCICmdRegBits_IOMemBusMaster)
11941 != AscPCICmdRegBits_IOMemBusMaster) {
11942 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
11945 if ((PCIDeviceID == ASC_PCI_DEVICEID_1200A) ||
11946 (PCIDeviceID == ASC_PCI_DEVICEID_1200B)) {
11947 DvcWritePCIConfigByte(asc_dvc,
11948 AscPCIConfigLatencyTimer, 0x00);
11949 if (DvcReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer)
11950 != 0x00) {
11951 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
11953 } else if (PCIDeviceID == ASC_PCI_DEVICEID_ULTRA) {
11954 if (DvcReadPCIConfigByte(asc_dvc,
11955 AscPCIConfigLatencyTimer) < 0x20) {
11956 DvcWritePCIConfigByte(asc_dvc,
11957 AscPCIConfigLatencyTimer, 0x20);
11959 if (DvcReadPCIConfigByte(asc_dvc,
11960 AscPCIConfigLatencyTimer) < 0x20) {
11961 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
11967 if (AscFindSignature(iop_base)) {
11968 warn_code |= AscInitAscDvcVar(asc_dvc);
11969 warn_code |= AscInitFromEEP(asc_dvc);
11970 asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
11971 if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) {
11972 asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
11974 } else {
11975 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11977 return(warn_code);
11980 STATIC ushort __init
11981 AscInitSetConfig(
11982 ASC_DVC_VAR *asc_dvc
11985 ushort warn_code = 0;
11987 asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
11988 if (asc_dvc->err_code != 0)
11989 return (UW_ERR);
11990 if (AscFindSignature(asc_dvc->iop_base)) {
11991 warn_code |= AscInitFromAscDvcVar(asc_dvc);
11992 asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
11993 } else {
11994 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
11996 return (warn_code);
11999 STATIC ushort __init
12000 AscInitFromAscDvcVar(
12001 ASC_DVC_VAR *asc_dvc
12004 PortAddr iop_base;
12005 ushort cfg_msw;
12006 ushort warn_code;
12007 ushort pci_device_id = 0;
12009 iop_base = asc_dvc->iop_base;
12010 #ifdef CONFIG_PCI
12011 if (asc_dvc->cfg->dev)
12012 pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device;
12013 #endif
12014 warn_code = 0;
12015 cfg_msw = AscGetChipCfgMsw(iop_base);
12016 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12017 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
12018 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12019 AscSetChipCfgMsw(iop_base, cfg_msw);
12021 if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
12022 asc_dvc->cfg->cmd_qng_enabled) {
12023 asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
12024 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12026 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12027 warn_code |= ASC_WARN_AUTO_CONFIG;
12029 if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
12030 if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
12031 != asc_dvc->irq_no) {
12032 asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
12035 if (asc_dvc->bus_type & ASC_IS_PCI) {
12036 cfg_msw &= 0xFFC0;
12037 AscSetChipCfgMsw(iop_base, cfg_msw);
12038 if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) {
12039 } else {
12040 if ((pci_device_id == ASC_PCI_DEVICE_ID_REV_A) ||
12041 (pci_device_id == ASC_PCI_DEVICE_ID_REV_B)) {
12042 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB;
12043 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
12046 } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) {
12047 if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
12048 == ASC_CHIP_VER_ASYN_BUG) {
12049 asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN;
12052 if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
12053 asc_dvc->cfg->chip_scsi_id) {
12054 asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
12056 #ifdef CONFIG_ISA
12057 if (asc_dvc->bus_type & ASC_IS_ISA) {
12058 AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
12059 AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
12061 #endif /* CONFIG_ISA */
12062 return (warn_code);
12065 STATIC ushort
12066 AscInitAsc1000Driver(
12067 ASC_DVC_VAR *asc_dvc
12070 ushort warn_code;
12071 PortAddr iop_base;
12073 iop_base = asc_dvc->iop_base;
12074 warn_code = 0;
12075 if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
12076 !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
12077 AscResetChipAndScsiBus(asc_dvc);
12078 DvcSleepMilliSecond((ASC_DCNT)
12079 ((ushort) asc_dvc->scsi_reset_wait * 1000));
12081 asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
12082 if (asc_dvc->err_code != 0)
12083 return (UW_ERR);
12084 if (!AscFindSignature(asc_dvc->iop_base)) {
12085 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
12086 return (warn_code);
12088 AscDisableInterrupt(iop_base);
12089 warn_code |= AscInitLram(asc_dvc);
12090 if (asc_dvc->err_code != 0)
12091 return (UW_ERR);
12092 ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n",
12093 (ulong) _asc_mcode_chksum);
12094 if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
12095 _asc_mcode_size) != _asc_mcode_chksum) {
12096 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
12097 return (warn_code);
12099 warn_code |= AscInitMicroCodeVar(asc_dvc);
12100 asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
12101 AscEnableInterrupt(iop_base);
12102 return (warn_code);
12105 STATIC ushort __init
12106 AscInitAscDvcVar(
12107 ASC_DVC_VAR *asc_dvc)
12109 int i;
12110 PortAddr iop_base;
12111 ushort warn_code;
12112 uchar chip_version;
12114 iop_base = asc_dvc->iop_base;
12115 warn_code = 0;
12116 asc_dvc->err_code = 0;
12117 if ((asc_dvc->bus_type &
12118 (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
12119 asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
12121 AscSetChipControl(iop_base, CC_HALT);
12122 AscSetChipStatus(iop_base, 0);
12123 asc_dvc->bug_fix_cntl = 0;
12124 asc_dvc->pci_fix_asyn_xfer = 0;
12125 asc_dvc->pci_fix_asyn_xfer_always = 0;
12126 /* asc_dvc->init_state initalized in AscInitGetConfig(). */
12127 asc_dvc->sdtr_done = 0;
12128 asc_dvc->cur_total_qng = 0;
12129 asc_dvc->is_in_int = 0;
12130 asc_dvc->in_critical_cnt = 0;
12131 asc_dvc->last_q_shortage = 0;
12132 asc_dvc->use_tagged_qng = 0;
12133 asc_dvc->no_scam = 0;
12134 asc_dvc->unit_not_ready = 0;
12135 asc_dvc->queue_full_or_busy = 0;
12136 asc_dvc->redo_scam = 0;
12137 asc_dvc->res2 = 0;
12138 asc_dvc->host_init_sdtr_index = 0;
12139 asc_dvc->cfg->can_tagged_qng = 0;
12140 asc_dvc->cfg->cmd_qng_enabled = 0;
12141 asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
12142 asc_dvc->init_sdtr = 0;
12143 asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
12144 asc_dvc->scsi_reset_wait = 3;
12145 asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
12146 asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
12147 asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET;
12148 asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
12149 asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
12150 asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
12151 asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
12152 ASC_LIB_VERSION_MINOR;
12153 chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type);
12154 asc_dvc->cfg->chip_version = chip_version;
12155 asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0;
12156 asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1;
12157 asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2;
12158 asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3;
12159 asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4;
12160 asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5;
12161 asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6;
12162 asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7;
12163 asc_dvc->max_sdtr_index = 7;
12164 if ((asc_dvc->bus_type & ASC_IS_PCI) &&
12165 (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) {
12166 asc_dvc->bus_type = ASC_IS_PCI_ULTRA;
12167 asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0;
12168 asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1;
12169 asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2;
12170 asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3;
12171 asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4;
12172 asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5;
12173 asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6;
12174 asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7;
12175 asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8;
12176 asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9;
12177 asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10;
12178 asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11;
12179 asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12;
12180 asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13;
12181 asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14;
12182 asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15;
12183 asc_dvc->max_sdtr_index = 15;
12184 if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150)
12186 AscSetExtraControl(iop_base,
12187 (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
12188 } else if (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3050) {
12189 AscSetExtraControl(iop_base,
12190 (SEC_ACTIVE_NEGATE | SEC_ENABLE_FILTER));
12193 if (asc_dvc->bus_type == ASC_IS_PCI) {
12194 AscSetExtraControl(iop_base, (SEC_ACTIVE_NEGATE | SEC_SLEW_RATE));
12197 asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
12198 if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
12199 AscSetChipIFC(iop_base, IFC_INIT_DEFAULT);
12200 asc_dvc->bus_type = ASC_IS_ISAPNP;
12202 #ifdef CONFIG_ISA
12203 if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
12204 asc_dvc->cfg->isa_dma_channel = (uchar) AscGetIsaDmaChannel(iop_base);
12206 #endif /* CONFIG_ISA */
12207 for (i = 0; i <= ASC_MAX_TID; i++) {
12208 asc_dvc->cur_dvc_qng[i] = 0;
12209 asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
12210 asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q *) 0L;
12211 asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *) 0L;
12212 asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG;
12214 return (warn_code);
12217 STATIC ushort __init
12218 AscInitFromEEP(ASC_DVC_VAR *asc_dvc)
12220 ASCEEP_CONFIG eep_config_buf;
12221 ASCEEP_CONFIG *eep_config;
12222 PortAddr iop_base;
12223 ushort chksum;
12224 ushort warn_code;
12225 ushort cfg_msw, cfg_lsw;
12226 int i;
12227 int write_eep = 0;
12229 iop_base = asc_dvc->iop_base;
12230 warn_code = 0;
12231 AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
12232 AscStopQueueExe(iop_base);
12233 if ((AscStopChip(iop_base) == FALSE) ||
12234 (AscGetChipScsiCtrl(iop_base) != 0)) {
12235 asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
12236 AscResetChipAndScsiBus(asc_dvc);
12237 DvcSleepMilliSecond((ASC_DCNT)
12238 ((ushort) asc_dvc->scsi_reset_wait * 1000));
12240 if (AscIsChipHalted(iop_base) == FALSE) {
12241 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
12242 return (warn_code);
12244 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
12245 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
12246 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
12247 return (warn_code);
12249 eep_config = (ASCEEP_CONFIG *) &eep_config_buf;
12250 cfg_msw = AscGetChipCfgMsw(iop_base);
12251 cfg_lsw = AscGetChipCfgLsw(iop_base);
12252 if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
12253 cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
12254 warn_code |= ASC_WARN_CFG_MSW_RECOVER;
12255 AscSetChipCfgMsw(iop_base, cfg_msw);
12257 chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
12258 ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum);
12259 if (chksum == 0) {
12260 chksum = 0xaa55;
12262 if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
12263 warn_code |= ASC_WARN_AUTO_CONFIG;
12264 if (asc_dvc->cfg->chip_version == 3) {
12265 if (eep_config->cfg_lsw != cfg_lsw) {
12266 warn_code |= ASC_WARN_EEPROM_RECOVER;
12267 eep_config->cfg_lsw = AscGetChipCfgLsw(iop_base);
12269 if (eep_config->cfg_msw != cfg_msw) {
12270 warn_code |= ASC_WARN_EEPROM_RECOVER;
12271 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
12275 eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK;
12276 eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
12277 ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n",
12278 eep_config->chksum);
12279 if (chksum != eep_config->chksum) {
12280 if (AscGetChipVersion(iop_base, asc_dvc->bus_type) ==
12281 ASC_CHIP_VER_PCI_ULTRA_3050 )
12283 ASC_DBG(1,
12284 "AscInitFromEEP: chksum error ignored; EEPROM-less board\n");
12285 eep_config->init_sdtr = 0xFF;
12286 eep_config->disc_enable = 0xFF;
12287 eep_config->start_motor = 0xFF;
12288 eep_config->use_cmd_qng = 0;
12289 eep_config->max_total_qng = 0xF0;
12290 eep_config->max_tag_qng = 0x20;
12291 eep_config->cntl = 0xBFFF;
12292 ASC_EEP_SET_CHIP_ID(eep_config, 7);
12293 eep_config->no_scam = 0;
12294 eep_config->adapter_info[0] = 0;
12295 eep_config->adapter_info[1] = 0;
12296 eep_config->adapter_info[2] = 0;
12297 eep_config->adapter_info[3] = 0;
12298 eep_config->adapter_info[4] = 0;
12299 /* Indicate EEPROM-less board. */
12300 eep_config->adapter_info[5] = 0xBB;
12301 } else {
12302 ASC_PRINT(
12303 "AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n");
12304 write_eep = 1;
12305 warn_code |= ASC_WARN_EEPROM_CHKSUM;
12308 asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr;
12309 asc_dvc->cfg->disc_enable = eep_config->disc_enable;
12310 asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
12311 asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config);
12312 asc_dvc->start_motor = eep_config->start_motor;
12313 asc_dvc->dvc_cntl = eep_config->cntl;
12314 asc_dvc->no_scam = eep_config->no_scam;
12315 asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0];
12316 asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1];
12317 asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2];
12318 asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3];
12319 asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4];
12320 asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5];
12321 if (!AscTestExternalLram(asc_dvc)) {
12322 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA)) {
12323 eep_config->max_total_qng = ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG;
12324 eep_config->max_tag_qng = ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG;
12325 } else {
12326 eep_config->cfg_msw |= 0x0800;
12327 cfg_msw |= 0x0800;
12328 AscSetChipCfgMsw(iop_base, cfg_msw);
12329 eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
12330 eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
12332 } else {
12334 if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
12335 eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
12337 if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
12338 eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
12340 if (eep_config->max_tag_qng > eep_config->max_total_qng) {
12341 eep_config->max_tag_qng = eep_config->max_total_qng;
12343 if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
12344 eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
12346 asc_dvc->max_total_qng = eep_config->max_total_qng;
12347 if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
12348 eep_config->use_cmd_qng) {
12349 eep_config->disc_enable = eep_config->use_cmd_qng;
12350 warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
12352 if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
12353 asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
12355 ASC_EEP_SET_CHIP_ID(eep_config, ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID);
12356 asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config);
12357 if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) &&
12358 !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) {
12359 asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX;
12362 for (i = 0; i <= ASC_MAX_TID; i++) {
12363 asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i];
12364 asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
12365 asc_dvc->cfg->sdtr_period_offset[i] =
12366 (uchar) (ASC_DEF_SDTR_OFFSET |
12367 (asc_dvc->host_init_sdtr_index << 4));
12369 eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
12370 if (write_eep) {
12371 if ((i = AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type)) !=
12372 0) {
12373 ASC_PRINT1(
12374 "AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n", i);
12375 } else {
12376 ASC_PRINT("AscInitFromEEP: Successfully re-wrote EEPROM.\n");
12379 return (warn_code);
12382 STATIC ushort
12383 AscInitMicroCodeVar(
12384 ASC_DVC_VAR *asc_dvc
12387 int i;
12388 ushort warn_code;
12389 PortAddr iop_base;
12390 ASC_PADDR phy_addr;
12391 ASC_DCNT phy_size;
12393 iop_base = asc_dvc->iop_base;
12394 warn_code = 0;
12395 for (i = 0; i <= ASC_MAX_TID; i++) {
12396 AscPutMCodeInitSDTRAtID(iop_base, i,
12397 asc_dvc->cfg->sdtr_period_offset[i]
12401 AscInitQLinkVar(asc_dvc);
12402 AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
12403 asc_dvc->cfg->disc_enable);
12404 AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
12405 ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
12407 /* Align overrun buffer on an 8 byte boundary. */
12408 phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf);
12409 phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7);
12410 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
12411 (uchar *) &phy_addr, 1);
12412 phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8);
12413 AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D,
12414 (uchar *) &phy_size, 1);
12416 asc_dvc->cfg->mcode_date =
12417 AscReadLramWord(iop_base, (ushort) ASCV_MC_DATE_W);
12418 asc_dvc->cfg->mcode_version =
12419 AscReadLramWord(iop_base, (ushort) ASCV_MC_VER_W);
12421 AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
12422 if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
12423 asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
12424 return (warn_code);
12426 if (AscStartChip(iop_base) != 1) {
12427 asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
12428 return (warn_code);
12431 return (warn_code);
12434 STATIC int __init
12435 AscTestExternalLram(
12436 ASC_DVC_VAR *asc_dvc)
12438 PortAddr iop_base;
12439 ushort q_addr;
12440 ushort saved_word;
12441 int sta;
12443 iop_base = asc_dvc->iop_base;
12444 sta = 0;
12445 q_addr = ASC_QNO_TO_QADDR(241);
12446 saved_word = AscReadLramWord(iop_base, q_addr);
12447 AscSetChipLramAddr(iop_base, q_addr);
12448 AscSetChipLramData(iop_base, 0x55AA);
12449 DvcSleepMilliSecond(10);
12450 AscSetChipLramAddr(iop_base, q_addr);
12451 if (AscGetChipLramData(iop_base) == 0x55AA) {
12452 sta = 1;
12453 AscWriteLramWord(iop_base, q_addr, saved_word);
12455 return (sta);
12458 STATIC int __init
12459 AscWriteEEPCmdReg(
12460 PortAddr iop_base,
12461 uchar cmd_reg
12464 uchar read_back;
12465 int retry;
12467 retry = 0;
12468 while (TRUE) {
12469 AscSetChipEEPCmd(iop_base, cmd_reg);
12470 DvcSleepMilliSecond(1);
12471 read_back = AscGetChipEEPCmd(iop_base);
12472 if (read_back == cmd_reg) {
12473 return (1);
12475 if (retry++ > ASC_EEP_MAX_RETRY) {
12476 return (0);
12481 STATIC int __init
12482 AscWriteEEPDataReg(
12483 PortAddr iop_base,
12484 ushort data_reg
12487 ushort read_back;
12488 int retry;
12490 retry = 0;
12491 while (TRUE) {
12492 AscSetChipEEPData(iop_base, data_reg);
12493 DvcSleepMilliSecond(1);
12494 read_back = AscGetChipEEPData(iop_base);
12495 if (read_back == data_reg) {
12496 return (1);
12498 if (retry++ > ASC_EEP_MAX_RETRY) {
12499 return (0);
12504 STATIC void __init
12505 AscWaitEEPRead(void)
12507 DvcSleepMilliSecond(1);
12508 return;
12511 STATIC void __init
12512 AscWaitEEPWrite(void)
12514 DvcSleepMilliSecond(20);
12515 return;
12518 STATIC ushort __init
12519 AscReadEEPWord(
12520 PortAddr iop_base,
12521 uchar addr)
12523 ushort read_wval;
12524 uchar cmd_reg;
12526 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
12527 AscWaitEEPRead();
12528 cmd_reg = addr | ASC_EEP_CMD_READ;
12529 AscWriteEEPCmdReg(iop_base, cmd_reg);
12530 AscWaitEEPRead();
12531 read_wval = AscGetChipEEPData(iop_base);
12532 AscWaitEEPRead();
12533 return (read_wval);
12536 STATIC ushort __init
12537 AscWriteEEPWord(
12538 PortAddr iop_base,
12539 uchar addr,
12540 ushort word_val)
12542 ushort read_wval;
12544 read_wval = AscReadEEPWord(iop_base, addr);
12545 if (read_wval != word_val) {
12546 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
12547 AscWaitEEPRead();
12548 AscWriteEEPDataReg(iop_base, word_val);
12549 AscWaitEEPRead();
12550 AscWriteEEPCmdReg(iop_base,
12551 (uchar) ((uchar) ASC_EEP_CMD_WRITE | addr));
12552 AscWaitEEPWrite();
12553 AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
12554 AscWaitEEPRead();
12555 return (AscReadEEPWord(iop_base, addr));
12557 return (read_wval);
12560 STATIC ushort __init
12561 AscGetEEPConfig(
12562 PortAddr iop_base,
12563 ASCEEP_CONFIG * cfg_buf, ushort bus_type)
12565 ushort wval;
12566 ushort sum;
12567 ushort *wbuf;
12568 int cfg_beg;
12569 int cfg_end;
12570 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
12571 int s_addr;
12573 wbuf = (ushort *) cfg_buf;
12574 sum = 0;
12575 /* Read two config words; Byte-swapping done by AscReadEEPWord(). */
12576 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12577 *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
12578 sum += *wbuf;
12580 if (bus_type & ASC_IS_VL) {
12581 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
12582 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
12583 } else {
12584 cfg_beg = ASC_EEP_DVC_CFG_BEG;
12585 cfg_end = ASC_EEP_MAX_DVC_ADDR;
12587 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
12588 wval = AscReadEEPWord( iop_base, ( uchar )s_addr ) ;
12589 if (s_addr <= uchar_end_in_config) {
12591 * Swap all char fields - must unswap bytes already swapped
12592 * by AscReadEEPWord().
12594 *wbuf = le16_to_cpu(wval);
12595 } else {
12596 /* Don't swap word field at the end - cntl field. */
12597 *wbuf = wval;
12599 sum += wval; /* Checksum treats all EEPROM data as words. */
12602 * Read the checksum word which will be compared against 'sum'
12603 * by the caller. Word field already swapped.
12605 *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
12606 return (sum);
12609 STATIC int __init
12610 AscSetEEPConfigOnce(
12611 PortAddr iop_base,
12612 ASCEEP_CONFIG * cfg_buf, ushort bus_type)
12614 int n_error;
12615 ushort *wbuf;
12616 ushort word;
12617 ushort sum;
12618 int s_addr;
12619 int cfg_beg;
12620 int cfg_end;
12621 int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2;
12624 wbuf = (ushort *) cfg_buf;
12625 n_error = 0;
12626 sum = 0;
12627 /* Write two config words; AscWriteEEPWord() will swap bytes. */
12628 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12629 sum += *wbuf;
12630 if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
12631 n_error++;
12634 if (bus_type & ASC_IS_VL) {
12635 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
12636 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
12637 } else {
12638 cfg_beg = ASC_EEP_DVC_CFG_BEG;
12639 cfg_end = ASC_EEP_MAX_DVC_ADDR;
12641 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
12642 if (s_addr <= uchar_end_in_config) {
12644 * This is a char field. Swap char fields before they are
12645 * swapped again by AscWriteEEPWord().
12647 word = cpu_to_le16(*wbuf);
12648 if (word != AscWriteEEPWord( iop_base, (uchar) s_addr, word)) {
12649 n_error++;
12651 } else {
12652 /* Don't swap word field at the end - cntl field. */
12653 if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
12654 n_error++;
12657 sum += *wbuf; /* Checksum calculated from word values. */
12659 /* Write checksum word. It will be swapped by AscWriteEEPWord(). */
12660 *wbuf = sum;
12661 if (sum != AscWriteEEPWord(iop_base, (uchar) s_addr, sum)) {
12662 n_error++;
12665 /* Read EEPROM back again. */
12666 wbuf = (ushort *) cfg_buf;
12668 * Read two config words; Byte-swapping done by AscReadEEPWord().
12670 for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
12671 if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
12672 n_error++;
12675 if (bus_type & ASC_IS_VL) {
12676 cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
12677 cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
12678 } else {
12679 cfg_beg = ASC_EEP_DVC_CFG_BEG;
12680 cfg_end = ASC_EEP_MAX_DVC_ADDR;
12682 for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) {
12683 if (s_addr <= uchar_end_in_config) {
12685 * Swap all char fields. Must unswap bytes already swapped
12686 * by AscReadEEPWord().
12688 word = le16_to_cpu(AscReadEEPWord(iop_base, (uchar) s_addr));
12689 } else {
12690 /* Don't swap word field at the end - cntl field. */
12691 word = AscReadEEPWord(iop_base, (uchar) s_addr);
12693 if (*wbuf != word) {
12694 n_error++;
12697 /* Read checksum; Byte swapping not needed. */
12698 if (AscReadEEPWord(iop_base, (uchar) s_addr) != sum) {
12699 n_error++;
12701 return (n_error);
12704 STATIC int __init
12705 AscSetEEPConfig(
12706 PortAddr iop_base,
12707 ASCEEP_CONFIG * cfg_buf, ushort bus_type
12710 int retry;
12711 int n_error;
12713 retry = 0;
12714 while (TRUE) {
12715 if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
12716 bus_type)) == 0) {
12717 break;
12719 if (++retry > ASC_EEP_MAX_RETRY) {
12720 break;
12723 return (n_error);
12726 STATIC void
12727 AscAsyncFix(
12728 ASC_DVC_VAR *asc_dvc,
12729 uchar tid_no,
12730 ASC_SCSI_INQUIRY *inq)
12732 uchar dvc_type;
12733 ASC_SCSI_BIT_ID_TYPE tid_bits;
12735 dvc_type = ASC_INQ_DVC_TYPE(inq);
12736 tid_bits = ASC_TIX_TO_TARGET_ID(tid_no);
12738 if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN)
12740 if (!(asc_dvc->init_sdtr & tid_bits))
12742 if ((dvc_type == TYPE_ROM) &&
12743 (AscCompareString((uchar *) inq->vendor_id,
12744 (uchar *) "HP ", 3) == 0))
12746 asc_dvc->pci_fix_asyn_xfer_always |= tid_bits;
12748 asc_dvc->pci_fix_asyn_xfer |= tid_bits;
12749 if ((dvc_type == TYPE_PROCESSOR) ||
12750 (dvc_type == TYPE_SCANNER) ||
12751 (dvc_type == TYPE_ROM) ||
12752 (dvc_type == TYPE_TAPE))
12754 asc_dvc->pci_fix_asyn_xfer &= ~tid_bits;
12757 if (asc_dvc->pci_fix_asyn_xfer & tid_bits)
12759 AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no,
12760 ASYN_SDTR_DATA_FIX_PCI_REV_AB);
12764 return;
12767 STATIC int
12768 AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq)
12770 if ((inq->add_len >= 32) &&
12771 (AscCompareString((uchar *) inq->vendor_id,
12772 (uchar *) "QUANTUM XP34301", 15) == 0) &&
12773 (AscCompareString((uchar *) inq->product_rev_level,
12774 (uchar *) "1071", 4) == 0))
12776 return 0;
12778 return 1;
12781 STATIC void
12782 AscInquiryHandling(ASC_DVC_VAR *asc_dvc,
12783 uchar tid_no, ASC_SCSI_INQUIRY *inq)
12785 ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no);
12786 ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng;
12788 orig_init_sdtr = asc_dvc->init_sdtr;
12789 orig_use_tagged_qng = asc_dvc->use_tagged_qng;
12791 asc_dvc->init_sdtr &= ~tid_bit;
12792 asc_dvc->cfg->can_tagged_qng &= ~tid_bit;
12793 asc_dvc->use_tagged_qng &= ~tid_bit;
12795 if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) {
12796 if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) {
12797 asc_dvc->init_sdtr |= tid_bit;
12799 if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) &&
12800 ASC_INQ_CMD_QUEUE(inq)) {
12801 if (AscTagQueuingSafe(inq)) {
12802 asc_dvc->use_tagged_qng |= tid_bit;
12803 asc_dvc->cfg->can_tagged_qng |= tid_bit;
12807 if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) {
12808 AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B,
12809 asc_dvc->cfg->disc_enable);
12810 AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B,
12811 asc_dvc->use_tagged_qng);
12812 AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B,
12813 asc_dvc->cfg->can_tagged_qng);
12815 asc_dvc->max_dvc_qng[tid_no] =
12816 asc_dvc->cfg->max_tag_qng[tid_no];
12817 AscWriteLramByte(asc_dvc->iop_base,
12818 (ushort) (ASCV_MAX_DVC_QNG_BEG + tid_no),
12819 asc_dvc->max_dvc_qng[tid_no]);
12821 if (orig_init_sdtr != asc_dvc->init_sdtr) {
12822 AscAsyncFix(asc_dvc, tid_no, inq);
12824 return;
12827 STATIC int
12828 AscCompareString(
12829 uchar *str1,
12830 uchar *str2,
12831 int len
12834 int i;
12835 int diff;
12837 for (i = 0; i < len; i++) {
12838 diff = (int) (str1[i] - str2[i]);
12839 if (diff != 0)
12840 return (diff);
12842 return (0);
12845 STATIC uchar
12846 AscReadLramByte(
12847 PortAddr iop_base,
12848 ushort addr
12851 uchar byte_data;
12852 ushort word_data;
12854 if (isodd_word(addr)) {
12855 AscSetChipLramAddr(iop_base, addr - 1);
12856 word_data = AscGetChipLramData(iop_base);
12857 byte_data = (uchar) ((word_data >> 8) & 0xFF);
12858 } else {
12859 AscSetChipLramAddr(iop_base, addr);
12860 word_data = AscGetChipLramData(iop_base);
12861 byte_data = (uchar) (word_data & 0xFF);
12863 return (byte_data);
12865 STATIC ushort
12866 AscReadLramWord(
12867 PortAddr iop_base,
12868 ushort addr
12871 ushort word_data;
12873 AscSetChipLramAddr(iop_base, addr);
12874 word_data = AscGetChipLramData(iop_base);
12875 return (word_data);
12878 #if CC_VERY_LONG_SG_LIST
12879 STATIC ASC_DCNT
12880 AscReadLramDWord(
12881 PortAddr iop_base,
12882 ushort addr
12885 ushort val_low, val_high;
12886 ASC_DCNT dword_data;
12888 AscSetChipLramAddr(iop_base, addr);
12889 val_low = AscGetChipLramData(iop_base);
12890 val_high = AscGetChipLramData(iop_base);
12891 dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low;
12892 return (dword_data);
12894 #endif /* CC_VERY_LONG_SG_LIST */
12896 STATIC void
12897 AscWriteLramWord(
12898 PortAddr iop_base,
12899 ushort addr,
12900 ushort word_val
12903 AscSetChipLramAddr(iop_base, addr);
12904 AscSetChipLramData(iop_base, word_val);
12905 return;
12908 STATIC void
12909 AscWriteLramByte(
12910 PortAddr iop_base,
12911 ushort addr,
12912 uchar byte_val
12915 ushort word_data;
12917 if (isodd_word(addr)) {
12918 addr--;
12919 word_data = AscReadLramWord(iop_base, addr);
12920 word_data &= 0x00FF;
12921 word_data |= (((ushort) byte_val << 8) & 0xFF00);
12922 } else {
12923 word_data = AscReadLramWord(iop_base, addr);
12924 word_data &= 0xFF00;
12925 word_data |= ((ushort) byte_val & 0x00FF);
12927 AscWriteLramWord(iop_base, addr, word_data);
12928 return;
12932 * Copy 2 bytes to LRAM.
12934 * The source data is assumed to be in little-endian order in memory
12935 * and is maintained in little-endian order when written to LRAM.
12937 STATIC void
12938 AscMemWordCopyPtrToLram(
12939 PortAddr iop_base,
12940 ushort s_addr,
12941 uchar *s_buffer,
12942 int words
12945 int i;
12947 AscSetChipLramAddr(iop_base, s_addr);
12948 for (i = 0; i < 2 * words; i += 2) {
12950 * On a little-endian system the second argument below
12951 * produces a little-endian ushort which is written to
12952 * LRAM in little-endian order. On a big-endian system
12953 * the second argument produces a big-endian ushort which
12954 * is "transparently" byte-swapped by outpw() and written
12955 * in little-endian order to LRAM.
12957 outpw(iop_base + IOP_RAM_DATA,
12958 ((ushort) s_buffer[i + 1] << 8) | s_buffer[i]);
12960 return;
12964 * Copy 4 bytes to LRAM.
12966 * The source data is assumed to be in little-endian order in memory
12967 * and is maintained in little-endian order when writen to LRAM.
12969 STATIC void
12970 AscMemDWordCopyPtrToLram(
12971 PortAddr iop_base,
12972 ushort s_addr,
12973 uchar *s_buffer,
12974 int dwords
12977 int i;
12979 AscSetChipLramAddr(iop_base, s_addr);
12980 for (i = 0; i < 4 * dwords; i += 4) {
12981 outpw(iop_base + IOP_RAM_DATA,
12982 ((ushort) s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */
12983 outpw(iop_base + IOP_RAM_DATA,
12984 ((ushort) s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */
12986 return;
12990 * Copy 2 bytes from LRAM.
12992 * The source data is assumed to be in little-endian order in LRAM
12993 * and is maintained in little-endian order when written to memory.
12995 STATIC void
12996 AscMemWordCopyPtrFromLram(
12997 PortAddr iop_base,
12998 ushort s_addr,
12999 uchar *d_buffer,
13000 int words
13003 int i;
13004 ushort word;
13006 AscSetChipLramAddr(iop_base, s_addr);
13007 for (i = 0; i < 2 * words; i += 2) {
13008 word = inpw(iop_base + IOP_RAM_DATA);
13009 d_buffer[i] = word & 0xff;
13010 d_buffer[i + 1] = (word >> 8) & 0xff;
13012 return;
13015 STATIC ASC_DCNT
13016 AscMemSumLramWord(
13017 PortAddr iop_base,
13018 ushort s_addr,
13019 int words
13022 ASC_DCNT sum;
13023 int i;
13025 sum = 0L;
13026 for (i = 0; i < words; i++, s_addr += 2) {
13027 sum += AscReadLramWord(iop_base, s_addr);
13029 return (sum);
13032 STATIC void
13033 AscMemWordSetLram(
13034 PortAddr iop_base,
13035 ushort s_addr,
13036 ushort set_wval,
13037 int words
13040 int i;
13042 AscSetChipLramAddr(iop_base, s_addr);
13043 for (i = 0; i < words; i++) {
13044 AscSetChipLramData(iop_base, set_wval);
13046 return;
13051 * --- Adv Library Functions
13054 /* a_mcode.h */
13056 /* Microcode buffer is kept after initialization for error recovery. */
13057 STATIC unsigned char _adv_asc3550_buf[] = {
13058 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc, 0x01, 0x00, 0x48, 0xe4,
13059 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7,
13060 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6,
13061 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00, 0x00, 0xec, 0x85, 0xf0,
13062 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00,
13063 0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80,
13064 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea,
13065 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00,
13066 0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54,
13067 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00, 0x3e, 0x00, 0x80, 0x00,
13068 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01,
13069 0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55,
13070 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
13071 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15,
13072 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0,
13073 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01,
13074 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c,
13075 0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0,
13076 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00,
13077 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10,
13078 0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15,
13079 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45,
13080 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6,
13081 0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa,
13082 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00, 0x9e, 0x00, 0xa8, 0x00,
13083 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01,
13084 0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08,
13085 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x06, 0x12,
13086 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17,
13087 0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47,
13088 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55, 0x14, 0x56, 0x77, 0x57,
13089 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe,
13090 0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff,
13091 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, 0x00, 0xfe, 0x57, 0x24,
13092 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08,
13093 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f,
13094 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xcf,
13095 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe,
13096 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe,
13097 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b, 0x02, 0xfe, 0xd4, 0x0c,
13098 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6,
13099 0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02,
13100 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02, 0xfe, 0x46, 0xf0, 0xfe,
13101 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44,
13102 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18,
13103 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9,
13104 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e,
13105 0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd,
13106 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, 0x1c, 0x17, 0x06,
13107 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe,
13108 0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f,
13109 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe, 0x69, 0x10, 0x17, 0x06,
13110 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe,
13111 0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40,
13112 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0x99, 0x01,
13113 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02,
13114 0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b,
13115 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0, 0xfe, 0x56, 0x03, 0xfe,
13116 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe,
13117 0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04,
13118 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40, 0x01, 0x0e, 0xac, 0x75,
13119 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe,
13120 0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4,
13121 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe, 0x0a, 0xf0, 0xfe, 0x7a,
13122 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe,
13123 0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c,
13124 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3, 0x0a, 0xca, 0x01, 0x0e,
13125 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f,
13126 0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f,
13127 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2b, 0xff, 0x02,
13128 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5,
13129 0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
13130 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d, 0xfe, 0x2a, 0x13, 0x2f,
13131 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86,
13132 0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12,
13133 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22,
13134 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29,
13135 0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4,
13136 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a, 0xfe, 0x70, 0x12, 0x49,
13137 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31,
13138 0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12,
13139 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05, 0x11, 0xfe, 0xe3, 0x00,
13140 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24,
13141 0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08,
13142 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01, 0x86, 0x24, 0x06, 0x12,
13143 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92,
13144 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe,
13145 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13, 0x47, 0x01, 0xa7, 0x26,
13146 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14,
13147 0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c,
13148 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x14,
13149 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57,
13150 0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04,
13151 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68, 0x06, 0x11, 0x9a, 0x01,
13152 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72,
13153 0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe,
13154 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07, 0x8d, 0x81, 0x02, 0x22,
13155 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00,
13156 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32,
13157 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15, 0xfe, 0x1b, 0x00, 0x01,
13158 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01,
13159 0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d,
13160 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12,
13161 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d,
13162 0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02,
13163 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x77, 0xfe, 0xca,
13164 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12,
13165 0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1,
13166 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f, 0x40, 0x12, 0x58, 0x01,
13167 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe,
13168 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe,
13169 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a, 0xfe, 0x2a, 0x12, 0xfe,
13170 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe,
13171 0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe,
13172 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x39, 0x18, 0x3a,
13173 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48,
13174 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80,
13175 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x7a, 0x08, 0x8d,
13176 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06,
13177 0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c,
13178 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe, 0x52, 0x12, 0xfe, 0x2c,
13179 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10,
13180 0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe,
13181 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xb5, 0xfe,
13182 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d,
13183 0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33,
13184 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a, 0xfe, 0x74, 0x18, 0x1c,
13185 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27,
13186 0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe,
13187 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc, 0xfe, 0x83, 0x80, 0xfe,
13188 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59,
13189 0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf,
13190 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e, 0x79, 0x56, 0x68, 0x57,
13191 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b,
13192 0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39,
13193 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x10, 0x58, 0xfe,
13194 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09,
13195 0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe,
13196 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08, 0x11, 0x9b, 0x09, 0x04,
13197 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe,
13198 0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12,
13199 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9, 0x14, 0x7a, 0x01, 0x33,
13200 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf,
13201 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10,
13202 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x84, 0x05, 0xcb, 0x1c,
13203 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a,
13204 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca,
13205 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe, 0x22, 0x00, 0x02, 0x5a,
13206 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe,
13207 0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10,
13208 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00, 0x2a, 0x13, 0xfe, 0x4e,
13209 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73,
13210 0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48,
13211 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xdb, 0x10, 0x11, 0xfe,
13212 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8,
13213 0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42,
13214 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c, 0x09, 0x04, 0x0b, 0xfe,
13215 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6,
13216 0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01,
13217 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x02, 0x29,
13218 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b,
13219 0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe,
13220 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01, 0xe8, 0x59, 0x11, 0x2d,
13221 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e,
13222 0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe,
13223 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d,
13224 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe,
13225 0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00,
13226 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa, 0xab, 0x70, 0x05, 0x6b,
13227 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01,
13228 0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01,
13229 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e, 0x1d, 0xfe, 0xce, 0x45,
13230 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe,
13231 0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d,
13232 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe,
13233 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee,
13234 0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e,
13235 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12, 0xce, 0x1e, 0x2d, 0x47,
13236 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe,
13237 0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02,
13238 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
13239 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea,
13240 0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01,
13241 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01,
13242 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e,
13243 0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24,
13244 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57,
13245 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe,
13246 0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04,
13247 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xe1,
13248 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c,
13249 0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d,
13250 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01, 0xe8, 0x11, 0xfe, 0xe9,
13251 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14,
13252 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe,
13253 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80, 0x40, 0x12, 0x20, 0x63,
13254 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac,
13255 0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe,
13256 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x24, 0x69, 0x12, 0xc9,
13257 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91,
13258 0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe,
13259 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c, 0x46, 0x1e, 0x20, 0xed,
13260 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c,
13261 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d,
13262 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46, 0xfa, 0xef, 0xfe, 0x42,
13263 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0,
13264 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10,
13265 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e, 0x10, 0x07, 0x7e, 0x45,
13266 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97,
13267 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe,
13268 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b, 0xfe, 0x48, 0x12, 0x07,
13269 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07,
13270 0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe,
13271 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b, 0x01, 0x08, 0x8c, 0x43,
13272 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b,
13273 0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04,
13274 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe, 0xc6, 0x10, 0x1e, 0x58,
13275 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23,
13276 0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1,
13277 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0xfe,
13278 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57,
13279 0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
13280 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e, 0x58, 0xfe, 0x1f, 0x40,
13281 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44,
13282 0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39,
13283 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06, 0x12, 0xcd, 0x02, 0x5b,
13284 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21,
13285 0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe,
13286 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51,
13287 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32,
13288 0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01,
13289 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44, 0x01, 0x08, 0x1f, 0xa2,
13290 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49,
13291 0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda,
13292 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1, 0x05, 0xc6, 0x28, 0x84,
13293 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
13294 0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02,
13295 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06, 0x21, 0x44, 0x01, 0xfe,
13296 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b,
13297 0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05,
13298 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xd8, 0x14, 0x02, 0x5c,
13299 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72,
13300 0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01,
13301 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0xfe, 0xff, 0x7f,
13302 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c,
13303 0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
13304 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58, 0x03, 0x0a, 0x50, 0x01,
13305 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4,
13306 0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27,
13307 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe,
13308 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60,
13309 0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14,
13310 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe, 0xcc, 0x12, 0x49, 0x04,
13311 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13,
13312 0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83,
13313 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c, 0x13, 0x06, 0xfe, 0x56,
13314 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93,
13315 0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4,
13316 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90, 0x01, 0xba, 0xfe, 0x4e,
13317 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe,
13318 0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c,
13319 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba, 0xfe, 0x9c, 0x14, 0xb7,
13320 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7,
13321 0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe,
13322 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x0b, 0x01,
13323 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03,
13324 0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08,
13325 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89, 0x4a, 0x01, 0x08, 0x03,
13326 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00,
13327 0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe,
13328 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd, 0x01, 0x43, 0x1e, 0xcd,
13329 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10,
13330 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88,
13331 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3, 0x88, 0x03, 0x0a, 0x42,
13332 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2,
13333 0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17,
13334 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe,
13335 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe,
13336 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10,
13337 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58, 0x05, 0xfe, 0x66, 0x01,
13338 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66,
13339 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6,
13340 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17, 0x10, 0x71, 0xfe, 0x83,
13341 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe,
13342 0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
13343 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71, 0xfe, 0x30, 0xbc, 0xfe,
13344 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a,
13345 0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02,
13346 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc, 0xfe, 0x1d, 0xf7, 0x4f,
13347 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58,
13348 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63,
13349 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14, 0x06, 0x37, 0x95, 0xa9,
13350 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d,
13351 0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c,
13352 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x3c, 0x8a, 0x0a,
13353 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc,
13354 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f,
13355 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xf6, 0xfe, 0xd6, 0xf0,
13356 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76,
13357 0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f,
13358 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68, 0xc8, 0xfe, 0x48, 0x55,
13359 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0,
13360 0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42,
13361 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01, 0x0e, 0x73, 0x75, 0x03,
13362 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b,
13363 0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b,
13364 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05, 0xfe, 0x94, 0x00, 0xfe,
13365 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e,
13366 0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe,
13367 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1b, 0xfe, 0x5a,
13368 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07,
13369 0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14,
13370 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9, 0x03, 0x25, 0xfe, 0xca,
13371 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00,
13374 STATIC unsigned short _adv_asc3550_size =
13375 sizeof(_adv_asc3550_buf); /* 0x13AD */
13376 STATIC ADV_DCNT _adv_asc3550_chksum =
13377 0x04D52DDDUL; /* Expanded little-endian checksum. */
13379 /* Microcode buffer is kept after initialization for error recovery. */
13380 STATIC unsigned char _adv_asc38C0800_buf[] = {
13381 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4, 0x01, 0x00, 0x48, 0xe4,
13382 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6,
13383 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0,
13384 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0, 0x18, 0xf4, 0x08, 0x00,
13385 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0,
13386 0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00,
13387 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13, 0xba, 0x13, 0x18, 0x40,
13388 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01,
13389 0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
13390 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12, 0x08, 0x12, 0x02, 0x4a,
13391 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa,
13392 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
13393 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d, 0x06, 0x13, 0x4c, 0x1c,
13394 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00,
13395 0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44,
13396 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa, 0x05, 0x00, 0x34, 0x00,
13397 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f,
13398 0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54,
13399 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0,
13400 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00,
13401 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03,
13402 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13, 0x12, 0x13, 0x24, 0x14,
13403 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44,
13404 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55,
13405 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0, 0x04, 0xf8,
13406 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00,
13407 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01,
13408 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08, 0x68, 0x08, 0x69, 0x08,
13409 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10,
13410 0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14,
13411 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18, 0xca, 0x18, 0xe6, 0x19,
13412 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe,
13413 0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff,
13414 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, 0x00, 0xfe, 0x57, 0x24,
13415 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08,
13416 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11,
13417 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xd6,
13418 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe,
13419 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe,
13420 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d, 0x02, 0xfe, 0xc8, 0x0d,
13421 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6,
13422 0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02,
13423 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02, 0xfe, 0x46, 0xf0, 0xfe,
13424 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44,
13425 0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14,
13426 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9,
13427 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8,
13428 0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd,
13429 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, 0x1c, 0x18, 0x06,
13430 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe,
13431 0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10,
13432 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe, 0x69, 0x10, 0x18, 0x06,
13433 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe,
13434 0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
13435 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x09,
13436 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
13437 0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe,
13438 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x40, 0x1c, 0x1c,
13439 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0,
13440 0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02,
13441 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13, 0x21, 0x22, 0xa3, 0xb7,
13442 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9,
13443 0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27,
13444 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe, 0x06, 0xf0, 0xfe, 0xc8,
13445 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe,
13446 0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19,
13447 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x74, 0x01, 0xaf, 0x8c,
13448 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79,
13449 0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02,
13450 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d, 0xfe, 0x3c, 0x04, 0x3b,
13451 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b,
13452 0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe,
13453 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0x4f, 0x79, 0x2a,
13454 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32,
13455 0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe,
13456 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x08, 0x13, 0x32, 0x07,
13457 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d,
13458 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6,
13459 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36, 0x02, 0x2b, 0xfe, 0x42,
13460 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe,
13461 0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c,
13462 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28, 0x17, 0xfe, 0x90, 0x05,
13463 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe,
13464 0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48,
13465 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0x12, 0xfe, 0xe3, 0x00,
13466 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25,
13467 0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02,
13468 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2, 0x08, 0x53, 0x05, 0xcb,
13469 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22,
13470 0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36,
13471 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb, 0x03, 0x5c, 0x28, 0xfe,
13472 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02,
13473 0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe,
13474 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62, 0x12, 0x03, 0x45, 0x28,
13475 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc,
13476 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2,
13477 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01, 0xfe, 0xcc, 0x15, 0x1d,
13478 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45,
13479 0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb,
13480 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07, 0xfe, 0x06, 0xf0, 0xfe,
13481 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b,
13482 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01,
13483 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38, 0x12, 0x08, 0x05, 0x1a,
13484 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
13485 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe,
13486 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b, 0xfe, 0x09, 0x6f, 0xba,
13487 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c,
13488 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01,
13489 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
13490 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07,
13491 0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe,
13492 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b, 0x37, 0x01, 0xb3, 0xb8,
13493 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51,
13494 0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c,
13495 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d, 0x14, 0x3e, 0xfe, 0x4a,
13496 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14,
13497 0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe,
13498 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f,
13499 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c,
13500 0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e,
13501 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe, 0x9a, 0x08, 0xc6, 0xfe,
13502 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24,
13503 0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12,
13504 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e, 0x1c, 0x02, 0xfe, 0x18,
13505 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa,
13506 0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7,
13507 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18, 0xfe, 0xf1, 0x18, 0xfe,
13508 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95,
13509 0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5,
13510 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18, 0x0b, 0xb6, 0xfe, 0xbf,
13511 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2,
13512 0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5,
13513 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15, 0x9d, 0x01, 0x36, 0x10,
13514 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19,
13515 0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe,
13516 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0x08, 0x05,
13517 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c,
13518 0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49,
13519 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18, 0x8f, 0xfe, 0xe3, 0x54,
13520 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b,
13521 0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b,
13522 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00, 0xad, 0xfe, 0x01, 0x59,
13523 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3,
13524 0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b,
13525 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63, 0x02, 0x4a, 0x08, 0x05,
13526 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1,
13527 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a,
13528 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29, 0x61, 0x0c, 0x7f, 0x14,
13529 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c,
13530 0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef,
13531 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40, 0xe4, 0x08, 0x05, 0x1f,
13532 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f,
13533 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05,
13534 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19, 0x81, 0x50, 0xfe, 0x10,
13535 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6,
13536 0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c,
13537 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7, 0x08, 0x05, 0x0a, 0xfe,
13538 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e,
13539 0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed,
13540 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe, 0x00, 0xff, 0x35, 0xfe,
13541 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03,
13542 0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe,
13543 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0,
13544 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00,
13545 0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0,
13546 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea, 0x0b, 0x10, 0x58, 0xfe,
13547 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f,
13548 0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34,
13549 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20, 0x0c, 0x1c, 0x34, 0x94,
13550 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10,
13551 0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33,
13552 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24, 0x33, 0x31, 0xdf, 0xbc,
13553 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d,
13554 0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28,
13555 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x44, 0xfe, 0x28, 0x00,
13556 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f,
13557 0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10,
13558 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xac,
13559 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01,
13560 0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08,
13561 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05, 0x1a, 0xfe, 0x58, 0x12,
13562 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe,
13563 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10,
13564 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10, 0xfe, 0x13, 0x00, 0xfe,
13565 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5,
13566 0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe,
13567 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0, 0xb4, 0x15, 0xfe, 0x31,
13568 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44,
13569 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75,
13570 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x44, 0x48,
13571 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09,
13572 0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d,
13573 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0xce, 0x47, 0xfe, 0xad,
13574 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13,
13575 0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06,
13576 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe, 0x3a, 0x01, 0x56, 0xfe,
13577 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05,
13578 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe,
13579 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13, 0x15, 0x1a, 0x39, 0xa0,
13580 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01,
13581 0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12,
13582 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12, 0x22, 0x9f, 0xb7, 0x13,
13583 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9,
13584 0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc,
13585 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21, 0xfe, 0x00, 0xcc, 0x04,
13586 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07,
13587 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe,
13588 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x0a, 0xfe, 0x3c, 0x50,
13589 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b,
13590 0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01,
13591 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01,
13592 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01,
13593 0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79,
13594 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00,
13596 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09,
13597 0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52,
13598 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc, 0x0f, 0x44, 0x11, 0x0f,
13599 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20,
13600 0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
13601 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x04, 0x42,
13602 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01,
13603 0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f,
13604 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45,
13605 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09,
13606 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14,
13607 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d, 0xfe, 0x01, 0xec, 0xa2,
13608 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe,
13609 0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07,
13610 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17, 0xfe, 0x32, 0x12, 0x07,
13611 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12,
13612 0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d,
13613 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d, 0x32, 0x07, 0xa6, 0xfe,
13614 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12,
13615 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03,
13616 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21, 0x0c, 0x7f, 0x0c, 0x80,
13617 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55,
13618 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f,
13619 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40, 0x88, 0x9b, 0x2e, 0x9c,
13620 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14,
13621 0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61,
13622 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50,
13623 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40,
13624 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d,
13625 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23, 0x72, 0x01, 0xaf, 0x1e,
13626 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe,
13627 0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19,
13628 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31,
13629 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d,
13630 0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8,
13631 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53, 0x05, 0x1f, 0x35, 0xa9,
13632 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c,
13633 0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35,
13634 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x03, 0x5c, 0xc1, 0x0c,
13635 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c,
13636 0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1,
13637 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a, 0xf4, 0x06, 0xea, 0x32,
13638 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89,
13639 0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13,
13640 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0, 0x13, 0x1c, 0xfe, 0xd0,
13641 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02,
13642 0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f,
13643 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04,
13644 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52,
13645 0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03,
13646 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52, 0xfe, 0x00, 0x7d, 0xfe,
13647 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f,
13648 0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01,
13649 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33,
13650 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59,
13651 0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee,
13652 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c, 0x30, 0xfe, 0x78, 0x10,
13653 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00,
13654 0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00,
13655 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28, 0x10, 0x69, 0x06, 0xfe,
13656 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06,
13657 0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe,
13658 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4, 0x9e, 0xfe, 0xf3, 0x10,
13659 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
13660 0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
13661 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d, 0xf4, 0x00, 0xe9, 0x91,
13662 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01,
13663 0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76,
13664 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x19, 0x01, 0x0b,
13665 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76,
13666 0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8,
13667 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01,
13668 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00,
13669 0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06,
13670 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e, 0x07, 0x11, 0xae, 0x09,
13671 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80,
13672 0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e,
13673 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xfe, 0x80, 0x4c,
13674 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87,
13675 0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24,
13676 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4, 0x17, 0xad, 0x9a, 0x1b,
13677 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10,
13678 0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe,
13679 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c,
13680 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17,
13681 0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75,
13682 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x2e, 0x97, 0xfe, 0x5a,
13683 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
13684 0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe,
13685 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0xcb, 0x97, 0xfe, 0x92,
13686 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02,
13687 0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d,
13688 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x9a, 0x5b, 0x41, 0xfe,
13689 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd,
13690 0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39,
13691 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04, 0xfe, 0x7e, 0x18, 0x1e,
13692 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10,
13693 0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09,
13694 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc,
13695 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c,
13696 0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14,
13697 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c, 0xe7, 0x0a, 0x10, 0xfe,
13698 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37,
13699 0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b,
13700 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77, 0x13, 0xa3, 0x04, 0x09,
13701 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8,
13702 0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09,
13703 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe, 0x1c, 0x19, 0x03, 0xfe,
13704 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19,
13705 0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b,
13706 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe, 0x08, 0x10, 0x03, 0xfe,
13707 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7,
13708 0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00,
13709 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19, 0x04, 0x07, 0x7e, 0xfe,
13710 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a,
13711 0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07,
13712 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59, 0xa9, 0xb8, 0x04, 0x15,
13713 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c,
13714 0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0,
13715 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
13718 STATIC unsigned short _adv_asc38C0800_size =
13719 sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
13720 STATIC ADV_DCNT _adv_asc38C0800_chksum =
13721 0x050D3FD8UL; /* Expanded little-endian checksum. */
13723 /* Microcode buffer is kept after initialization for error recovery. */
13724 STATIC unsigned char _adv_asc38C1600_buf[] = {
13725 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0, 0x18, 0xe4, 0x01, 0x00,
13726 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f,
13727 0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0,
13728 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00, 0x98, 0x57, 0x01, 0xe6,
13729 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0,
13730 0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0,
13731 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01, 0x06, 0x13, 0x0c, 0x1c,
13732 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80,
13733 0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea,
13734 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x04, 0x13, 0xbb, 0x55,
13735 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00,
13736 0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c,
13737 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01,
13738 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01,
13739 0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48,
13740 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x06, 0x00,
13741 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c,
13742 0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0,
13743 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00,
13744 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09,
13745 0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16,
13746 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
13747 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00,
13748 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c,
13749 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x42, 0x1d, 0x08, 0x44,
13750 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59,
13751 0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8,
13752 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0xa8, 0x00, 0xaa, 0x00,
13753 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01,
13754 0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d,
13755 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10, 0xf3, 0x10, 0x06, 0x12,
13756 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe,
13757 0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff,
13758 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, 0x00, 0xfe, 0x57, 0x24,
13759 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08,
13760 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13,
13761 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xe8,
13762 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe,
13763 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe,
13764 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d, 0x05, 0xfe, 0x08, 0x0f,
13765 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe,
13766 0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90,
13767 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8, 0x02, 0xfe, 0x46, 0xf0,
13768 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe,
13769 0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07,
13770 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02, 0x1c, 0xf5, 0xfe, 0x1e,
13771 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01,
13772 0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe,
13773 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, 0x1c, 0x1c,
13774 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02,
13775 0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01,
13776 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09, 0x1a, 0x31, 0xfe, 0x69,
13777 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c,
13778 0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51,
13779 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00,
13780 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54,
13781 0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30,
13782 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0, 0xfe, 0xe4, 0x01, 0xfe,
13783 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66,
13784 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f,
13785 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05, 0x70, 0x37, 0xfe, 0x48,
13786 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20,
13787 0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe,
13788 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32, 0x15, 0xfe, 0xe4, 0x00,
13789 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe,
13790 0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b,
13791 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xfe, 0x46, 0x1c,
13792 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75,
13793 0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77,
13794 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02,
13795 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04,
13796 0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01,
13797 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25, 0xee, 0xfe, 0x4c, 0x44,
13798 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d,
13799 0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe,
13800 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10, 0x13, 0x34, 0xfe, 0x4c,
13801 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06,
13802 0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f,
13803 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f, 0xfe, 0xa4, 0x0e, 0x05,
13804 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b,
13805 0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46,
13806 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04, 0xfe, 0x87, 0x83, 0xfe,
13807 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20,
13808 0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06,
13809 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda, 0x05, 0xd0, 0x54, 0x01,
13810 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff,
13811 0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe,
13812 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01, 0x38, 0xfe, 0x4a, 0xf0,
13813 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e,
13814 0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0,
13815 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe, 0x1c, 0x00, 0x4d, 0x01,
13816 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12,
13817 0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42,
13818 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13, 0x03, 0xb6, 0x1e, 0xfe,
13819 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a,
13820 0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68,
13821 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x03, 0x9a, 0x1e, 0xfe,
13822 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06,
13823 0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00,
13824 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17, 0xfe, 0xea, 0x06, 0x01,
13825 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15,
13826 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae,
13827 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a, 0x1e, 0xfe, 0x1a, 0x12,
13828 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80,
13829 0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6,
13830 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x17, 0xfe,
13831 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01,
13832 0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05,
13833 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0x9c, 0x32, 0x5f,
13834 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe,
13835 0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29,
13836 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14,
13837 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe,
13838 0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13,
13839 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
13840 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe,
13841 0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c,
13842 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x53, 0x63, 0x4e,
13843 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0,
13844 0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c,
13845 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe, 0x1e, 0xfe, 0x99, 0x58,
13846 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c,
13847 0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a,
13848 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40, 0x01, 0x0c, 0x61, 0x65,
13849 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50,
13850 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e,
13851 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e, 0x01, 0xfe, 0xfe, 0x1e,
13852 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06,
13853 0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b,
13854 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04, 0xfe, 0x9f, 0x83, 0x33,
13855 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6,
13856 0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e,
13857 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90, 0x04, 0xfe, 0xc0, 0x93,
13858 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c,
13859 0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
13860 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
13861 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a,
13862 0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41,
13863 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07, 0xfe, 0x14, 0x12, 0x01,
13864 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe,
13865 0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe,
13866 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe, 0x92, 0x10, 0xc4, 0xf6,
13867 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b,
13868 0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0,
13869 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07, 0x1b, 0xbf, 0xd4, 0x5b,
13870 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f,
13871 0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74,
13872 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78, 0x0f, 0x4d, 0x01, 0xfe,
13873 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2,
13874 0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21,
13875 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe, 0x83, 0x83, 0xfe, 0xc9,
13876 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84,
13877 0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b,
13878 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0x10,
13879 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64,
13880 0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64,
13881 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97, 0x10, 0x98, 0x91, 0x6c,
13882 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01,
13883 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58,
13884 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x01, 0x0c,
13885 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04,
13886 0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe,
13887 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb, 0x01, 0x0c, 0x06, 0x0d,
13888 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d,
13889 0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e,
13890 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41,
13891 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00,
13892 0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51,
13893 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe, 0x76, 0x10, 0xac, 0xfe,
13894 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe,
13895 0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92,
13896 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2, 0x0c, 0xfe, 0x3e, 0x10,
13897 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe,
13898 0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94,
13899 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3, 0xfe, 0xcc, 0xf0, 0xef,
13900 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
13901 0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
13902 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32, 0x2f, 0xfe, 0x3e, 0x0d,
13903 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f,
13904 0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99,
13905 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8, 0x9c, 0x2f, 0xfe, 0x8c,
13906 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70,
13907 0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13,
13908 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b, 0xfe, 0xda, 0x0e, 0x0a,
13909 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4,
13910 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85,
13911 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe, 0xcc, 0x10, 0x01, 0xa7,
13912 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe,
13913 0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2,
13914 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x40, 0x15,
13915 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01,
13916 0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe,
13917 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe,
13918 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44,
13919 0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19,
13920 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19, 0xfe, 0x41, 0x00, 0xa2,
13921 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04,
13922 0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c,
13923 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01, 0xfe, 0xd4, 0x11, 0x05,
13924 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51,
13925 0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56,
13926 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01, 0x0c, 0x06, 0x28, 0xfe,
13927 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe,
13928 0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe,
13929 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x05,
13930 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c,
13931 0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b,
13932 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe, 0xf0, 0x1a, 0x03, 0xfe,
13933 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00,
13934 0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b,
13935 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02, 0xea, 0xe7, 0x53, 0x92,
13936 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23,
13937 0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e,
13938 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02, 0x26, 0x02, 0x21, 0x96,
13939 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10,
13940 0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe,
13941 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe, 0x00, 0xcc, 0x02, 0xfe,
13942 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80,
13943 0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80,
13944 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe, 0x1d, 0x80, 0x04, 0xfe,
13945 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14,
13946 0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4,
13947 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09, 0x56, 0xfb, 0x01, 0xfe,
13948 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15,
13949 0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e,
13950 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe, 0x96, 0x90, 0x04, 0xfe,
13951 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06,
13952 0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01,
13953 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40, 0x21, 0x2c, 0xfe, 0x00,
13954 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe,
13955 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00,
13956 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10, 0x66, 0x10, 0x55, 0x10,
13957 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88,
13958 0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe,
13959 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c,
13960 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe,
13961 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47,
13962 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01, 0xa7, 0x90, 0x34, 0x60,
13963 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34,
13964 0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
13965 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a,
13966 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe,
13967 0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e,
13968 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01, 0xf4, 0xfe, 0xdd, 0x10,
13969 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe,
13970 0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23,
13971 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09, 0x24, 0xfe, 0x12, 0x12,
13972 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32,
13973 0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43,
13974 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80, 0x13, 0x01, 0x0c, 0x06,
13975 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe,
13976 0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10,
13977 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49, 0x88, 0x20, 0x6e, 0x01,
13978 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa,
13979 0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe,
13980 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe, 0xe5,
13981 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01,
13982 0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50,
13983 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50, 0x03, 0x68, 0x3b,
13984 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2,
13985 0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25,
13986 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01, 0xa6, 0x23, 0x3f, 0x1b,
13987 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31,
13988 0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01,
13989 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0,
13990 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05,
13991 0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08,
13992 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03, 0xb6, 0x1e, 0x83, 0x01,
13993 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01,
13994 0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82,
13995 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e, 0x05, 0x72, 0xfe, 0xc0,
13996 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17,
13997 0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd,
13998 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe, 0xe8, 0x14, 0x01, 0xa6,
13999 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43,
14000 0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73,
14001 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd, 0x09,
14002 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8,
14003 0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72,
14004 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0xc0, 0x19, 0x05,
14005 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26,
14006 0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32,
14007 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0xfe, 0xff,
14008 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad,
14009 0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
14010 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e, 0x02, 0x13, 0x58, 0xff,
14011 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01,
14012 0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54,
14013 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07, 0x7c, 0x3a, 0x0b, 0x0e,
14014 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00,
14015 0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe,
14016 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77, 0x02, 0x01, 0xc6, 0xfe,
14017 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08,
14018 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe,
14019 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12, 0x48, 0xfe, 0x08, 0x17,
14020 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07,
14021 0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55,
14022 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x1c, 0x63, 0x13,
14023 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80,
14024 0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60,
14025 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8, 0x00, 0x1c, 0x95, 0x13,
14026 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96,
14027 0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b,
14028 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x49,
14029 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe,
14030 0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13,
14031 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xbe, 0xfe, 0x03,
14032 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16,
14033 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9,
14034 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27,
14035 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24,
14036 0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e,
14037 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10, 0xfe, 0x40, 0x5a, 0x23,
14038 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa,
14039 0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
14040 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe, 0x43, 0x48, 0x2d, 0x93,
14041 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4,
14042 0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0,
14043 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa, 0x18, 0x45, 0xfe, 0x1c,
14044 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4,
14045 0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01,
14046 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe, 0x7e, 0x01, 0xfe, 0xc8,
14047 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01,
14048 0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14,
14049 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14,
14050 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07,
14051 0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
14052 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01, 0x08, 0x02, 0x50, 0x02,
14053 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08,
14054 0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe,
14055 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17, 0x74, 0x5f, 0xcc, 0x01,
14056 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00,
14057 0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f,
14058 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13, 0x16, 0xfe, 0x64, 0x1a,
14059 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02,
14060 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01,
14061 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa, 0xfe, 0x80, 0xe7, 0x1a,
14062 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18,
14063 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80,
14064 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x0a,
14065 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
14066 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3,
14067 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe, 0xf4, 0x1a, 0xfe, 0xfa,
14068 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03,
14069 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07,
14070 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x24, 0xb1, 0xfe,
14071 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c,
14072 0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1,
14073 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe, 0xaf, 0x19, 0xfe, 0x98,
14074 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f,
14075 0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04,
14076 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a, 0x7c, 0x12, 0xfe, 0x0f,
14077 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b,
14078 0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe,
14079 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee, 0x1b, 0xfe, 0x36, 0x14,
14080 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a,
14081 0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45,
14082 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe, 0x39, 0xf0, 0x75, 0x26,
14083 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe,
14084 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13,
14085 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe,
14086 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb,
14087 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01,
14088 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14, 0x56,
14089 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15,
14090 0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80,
14091 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90,
14092 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20,
14093 0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44,
14094 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09, 0x1a, 0xa4, 0x0a, 0x67,
14095 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52,
14096 0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b,
14097 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10, 0xfe, 0x4e, 0xe4, 0xfe,
14098 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03,
14099 0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1,
14100 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe,
14101 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a,
14102 0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8,
14103 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe, 0x1a, 0x10, 0x09, 0x0d,
14104 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42,
14105 0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08,
14106 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e, 0xfe, 0x82, 0xf0, 0xfe,
14107 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18,
14108 0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82,
14109 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86, 0x83, 0x33, 0x0b, 0x0e,
14110 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04,
14111 0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80,
14112 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04, 0xfe, 0x99, 0x83, 0xfe,
14113 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47,
14114 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
14115 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x08, 0x90, 0x04,
14116 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79,
14117 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
14118 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x3c, 0x90, 0x04,
14119 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83,
14120 0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
14123 STATIC unsigned short _adv_asc38C1600_size =
14124 sizeof(_adv_asc38C1600_buf); /* 0x1673 */
14125 STATIC ADV_DCNT _adv_asc38C1600_chksum =
14126 0x0604EF77UL; /* Expanded little-endian checksum. */
14128 /* a_init.c */
14130 * EEPROM Configuration.
14132 * All drivers should use this structure to set the default EEPROM
14133 * configuration. The BIOS now uses this structure when it is built.
14134 * Additional structure information can be found in a_condor.h where
14135 * the structure is defined.
14137 * The *_Field_IsChar structs are needed to correct for endianness.
14138 * These values are read from the board 16 bits at a time directly
14139 * into the structs. Because some fields are char, the values will be
14140 * in the wrong order. The *_Field_IsChar tells when to flip the
14141 * bytes. Data read and written to PCI memory is automatically swapped
14142 * on big-endian platforms so char fields read as words are actually being
14143 * unswapped on big-endian platforms.
14145 STATIC ADVEEP_3550_CONFIG
14146 Default_3550_EEPROM_Config __initdata = {
14147 ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */
14148 0x0000, /* cfg_msw */
14149 0xFFFF, /* disc_enable */
14150 0xFFFF, /* wdtr_able */
14151 0xFFFF, /* sdtr_able */
14152 0xFFFF, /* start_motor */
14153 0xFFFF, /* tagqng_able */
14154 0xFFFF, /* bios_scan */
14155 0, /* scam_tolerant */
14156 7, /* adapter_scsi_id */
14157 0, /* bios_boot_delay */
14158 3, /* scsi_reset_delay */
14159 0, /* bios_id_lun */
14160 0, /* termination */
14161 0, /* reserved1 */
14162 0xFFE7, /* bios_ctrl */
14163 0xFFFF, /* ultra_able */
14164 0, /* reserved2 */
14165 ASC_DEF_MAX_HOST_QNG, /* max_host_qng */
14166 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
14167 0, /* dvc_cntl */
14168 0, /* bug_fix */
14169 0, /* serial_number_word1 */
14170 0, /* serial_number_word2 */
14171 0, /* serial_number_word3 */
14172 0, /* check_sum */
14173 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* oem_name[16] */
14174 0, /* dvc_err_code */
14175 0, /* adv_err_code */
14176 0, /* adv_err_addr */
14177 0, /* saved_dvc_err_code */
14178 0, /* saved_adv_err_code */
14179 0, /* saved_adv_err_addr */
14180 0 /* num_of_err */
14183 STATIC ADVEEP_3550_CONFIG
14184 ADVEEP_3550_Config_Field_IsChar __initdata = {
14185 0, /* cfg_lsw */
14186 0, /* cfg_msw */
14187 0, /* -disc_enable */
14188 0, /* wdtr_able */
14189 0, /* sdtr_able */
14190 0, /* start_motor */
14191 0, /* tagqng_able */
14192 0, /* bios_scan */
14193 0, /* scam_tolerant */
14194 1, /* adapter_scsi_id */
14195 1, /* bios_boot_delay */
14196 1, /* scsi_reset_delay */
14197 1, /* bios_id_lun */
14198 1, /* termination */
14199 1, /* reserved1 */
14200 0, /* bios_ctrl */
14201 0, /* ultra_able */
14202 0, /* reserved2 */
14203 1, /* max_host_qng */
14204 1, /* max_dvc_qng */
14205 0, /* dvc_cntl */
14206 0, /* bug_fix */
14207 0, /* serial_number_word1 */
14208 0, /* serial_number_word2 */
14209 0, /* serial_number_word3 */
14210 0, /* check_sum */
14211 { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* oem_name[16] */
14212 0, /* dvc_err_code */
14213 0, /* adv_err_code */
14214 0, /* adv_err_addr */
14215 0, /* saved_dvc_err_code */
14216 0, /* saved_adv_err_code */
14217 0, /* saved_adv_err_addr */
14218 0 /* num_of_err */
14221 STATIC ADVEEP_38C0800_CONFIG
14222 Default_38C0800_EEPROM_Config __initdata = {
14223 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
14224 0x0000, /* 01 cfg_msw */
14225 0xFFFF, /* 02 disc_enable */
14226 0xFFFF, /* 03 wdtr_able */
14227 0x4444, /* 04 sdtr_speed1 */
14228 0xFFFF, /* 05 start_motor */
14229 0xFFFF, /* 06 tagqng_able */
14230 0xFFFF, /* 07 bios_scan */
14231 0, /* 08 scam_tolerant */
14232 7, /* 09 adapter_scsi_id */
14233 0, /* bios_boot_delay */
14234 3, /* 10 scsi_reset_delay */
14235 0, /* bios_id_lun */
14236 0, /* 11 termination_se */
14237 0, /* termination_lvd */
14238 0xFFE7, /* 12 bios_ctrl */
14239 0x4444, /* 13 sdtr_speed2 */
14240 0x4444, /* 14 sdtr_speed3 */
14241 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
14242 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
14243 0, /* 16 dvc_cntl */
14244 0x4444, /* 17 sdtr_speed4 */
14245 0, /* 18 serial_number_word1 */
14246 0, /* 19 serial_number_word2 */
14247 0, /* 20 serial_number_word3 */
14248 0, /* 21 check_sum */
14249 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */
14250 0, /* 30 dvc_err_code */
14251 0, /* 31 adv_err_code */
14252 0, /* 32 adv_err_addr */
14253 0, /* 33 saved_dvc_err_code */
14254 0, /* 34 saved_adv_err_code */
14255 0, /* 35 saved_adv_err_addr */
14256 0, /* 36 reserved */
14257 0, /* 37 reserved */
14258 0, /* 38 reserved */
14259 0, /* 39 reserved */
14260 0, /* 40 reserved */
14261 0, /* 41 reserved */
14262 0, /* 42 reserved */
14263 0, /* 43 reserved */
14264 0, /* 44 reserved */
14265 0, /* 45 reserved */
14266 0, /* 46 reserved */
14267 0, /* 47 reserved */
14268 0, /* 48 reserved */
14269 0, /* 49 reserved */
14270 0, /* 50 reserved */
14271 0, /* 51 reserved */
14272 0, /* 52 reserved */
14273 0, /* 53 reserved */
14274 0, /* 54 reserved */
14275 0, /* 55 reserved */
14276 0, /* 56 cisptr_lsw */
14277 0, /* 57 cisprt_msw */
14278 ADV_PCI_VENDOR_ID, /* 58 subsysvid */
14279 ADV_PCI_DEVID_38C0800_REV1, /* 59 subsysid */
14280 0, /* 60 reserved */
14281 0, /* 61 reserved */
14282 0, /* 62 reserved */
14283 0 /* 63 reserved */
14286 STATIC ADVEEP_38C0800_CONFIG
14287 ADVEEP_38C0800_Config_Field_IsChar __initdata = {
14288 0, /* 00 cfg_lsw */
14289 0, /* 01 cfg_msw */
14290 0, /* 02 disc_enable */
14291 0, /* 03 wdtr_able */
14292 0, /* 04 sdtr_speed1 */
14293 0, /* 05 start_motor */
14294 0, /* 06 tagqng_able */
14295 0, /* 07 bios_scan */
14296 0, /* 08 scam_tolerant */
14297 1, /* 09 adapter_scsi_id */
14298 1, /* bios_boot_delay */
14299 1, /* 10 scsi_reset_delay */
14300 1, /* bios_id_lun */
14301 1, /* 11 termination_se */
14302 1, /* termination_lvd */
14303 0, /* 12 bios_ctrl */
14304 0, /* 13 sdtr_speed2 */
14305 0, /* 14 sdtr_speed3 */
14306 1, /* 15 max_host_qng */
14307 1, /* max_dvc_qng */
14308 0, /* 16 dvc_cntl */
14309 0, /* 17 sdtr_speed4 */
14310 0, /* 18 serial_number_word1 */
14311 0, /* 19 serial_number_word2 */
14312 0, /* 20 serial_number_word3 */
14313 0, /* 21 check_sum */
14314 { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* 22-29 oem_name[16] */
14315 0, /* 30 dvc_err_code */
14316 0, /* 31 adv_err_code */
14317 0, /* 32 adv_err_addr */
14318 0, /* 33 saved_dvc_err_code */
14319 0, /* 34 saved_adv_err_code */
14320 0, /* 35 saved_adv_err_addr */
14321 0, /* 36 reserved */
14322 0, /* 37 reserved */
14323 0, /* 38 reserved */
14324 0, /* 39 reserved */
14325 0, /* 40 reserved */
14326 0, /* 41 reserved */
14327 0, /* 42 reserved */
14328 0, /* 43 reserved */
14329 0, /* 44 reserved */
14330 0, /* 45 reserved */
14331 0, /* 46 reserved */
14332 0, /* 47 reserved */
14333 0, /* 48 reserved */
14334 0, /* 49 reserved */
14335 0, /* 50 reserved */
14336 0, /* 51 reserved */
14337 0, /* 52 reserved */
14338 0, /* 53 reserved */
14339 0, /* 54 reserved */
14340 0, /* 55 reserved */
14341 0, /* 56 cisptr_lsw */
14342 0, /* 57 cisprt_msw */
14343 0, /* 58 subsysvid */
14344 0, /* 59 subsysid */
14345 0, /* 60 reserved */
14346 0, /* 61 reserved */
14347 0, /* 62 reserved */
14348 0 /* 63 reserved */
14351 STATIC ADVEEP_38C1600_CONFIG
14352 Default_38C1600_EEPROM_Config __initdata = {
14353 ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */
14354 0x0000, /* 01 cfg_msw */
14355 0xFFFF, /* 02 disc_enable */
14356 0xFFFF, /* 03 wdtr_able */
14357 0x5555, /* 04 sdtr_speed1 */
14358 0xFFFF, /* 05 start_motor */
14359 0xFFFF, /* 06 tagqng_able */
14360 0xFFFF, /* 07 bios_scan */
14361 0, /* 08 scam_tolerant */
14362 7, /* 09 adapter_scsi_id */
14363 0, /* bios_boot_delay */
14364 3, /* 10 scsi_reset_delay */
14365 0, /* bios_id_lun */
14366 0, /* 11 termination_se */
14367 0, /* termination_lvd */
14368 0xFFE7, /* 12 bios_ctrl */
14369 0x5555, /* 13 sdtr_speed2 */
14370 0x5555, /* 14 sdtr_speed3 */
14371 ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */
14372 ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */
14373 0, /* 16 dvc_cntl */
14374 0x5555, /* 17 sdtr_speed4 */
14375 0, /* 18 serial_number_word1 */
14376 0, /* 19 serial_number_word2 */
14377 0, /* 20 serial_number_word3 */
14378 0, /* 21 check_sum */
14379 { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */
14380 0, /* 30 dvc_err_code */
14381 0, /* 31 adv_err_code */
14382 0, /* 32 adv_err_addr */
14383 0, /* 33 saved_dvc_err_code */
14384 0, /* 34 saved_adv_err_code */
14385 0, /* 35 saved_adv_err_addr */
14386 0, /* 36 reserved */
14387 0, /* 37 reserved */
14388 0, /* 38 reserved */
14389 0, /* 39 reserved */
14390 0, /* 40 reserved */
14391 0, /* 41 reserved */
14392 0, /* 42 reserved */
14393 0, /* 43 reserved */
14394 0, /* 44 reserved */
14395 0, /* 45 reserved */
14396 0, /* 46 reserved */
14397 0, /* 47 reserved */
14398 0, /* 48 reserved */
14399 0, /* 49 reserved */
14400 0, /* 50 reserved */
14401 0, /* 51 reserved */
14402 0, /* 52 reserved */
14403 0, /* 53 reserved */
14404 0, /* 54 reserved */
14405 0, /* 55 reserved */
14406 0, /* 56 cisptr_lsw */
14407 0, /* 57 cisprt_msw */
14408 ADV_PCI_VENDOR_ID, /* 58 subsysvid */
14409 ADV_PCI_DEVID_38C1600_REV1, /* 59 subsysid */
14410 0, /* 60 reserved */
14411 0, /* 61 reserved */
14412 0, /* 62 reserved */
14413 0 /* 63 reserved */
14416 STATIC ADVEEP_38C1600_CONFIG
14417 ADVEEP_38C1600_Config_Field_IsChar __initdata = {
14418 0, /* 00 cfg_lsw */
14419 0, /* 01 cfg_msw */
14420 0, /* 02 disc_enable */
14421 0, /* 03 wdtr_able */
14422 0, /* 04 sdtr_speed1 */
14423 0, /* 05 start_motor */
14424 0, /* 06 tagqng_able */
14425 0, /* 07 bios_scan */
14426 0, /* 08 scam_tolerant */
14427 1, /* 09 adapter_scsi_id */
14428 1, /* bios_boot_delay */
14429 1, /* 10 scsi_reset_delay */
14430 1, /* bios_id_lun */
14431 1, /* 11 termination_se */
14432 1, /* termination_lvd */
14433 0, /* 12 bios_ctrl */
14434 0, /* 13 sdtr_speed2 */
14435 0, /* 14 sdtr_speed3 */
14436 1, /* 15 max_host_qng */
14437 1, /* max_dvc_qng */
14438 0, /* 16 dvc_cntl */
14439 0, /* 17 sdtr_speed4 */
14440 0, /* 18 serial_number_word1 */
14441 0, /* 19 serial_number_word2 */
14442 0, /* 20 serial_number_word3 */
14443 0, /* 21 check_sum */
14444 { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, /* 22-29 oem_name[16] */
14445 0, /* 30 dvc_err_code */
14446 0, /* 31 adv_err_code */
14447 0, /* 32 adv_err_addr */
14448 0, /* 33 saved_dvc_err_code */
14449 0, /* 34 saved_adv_err_code */
14450 0, /* 35 saved_adv_err_addr */
14451 0, /* 36 reserved */
14452 0, /* 37 reserved */
14453 0, /* 38 reserved */
14454 0, /* 39 reserved */
14455 0, /* 40 reserved */
14456 0, /* 41 reserved */
14457 0, /* 42 reserved */
14458 0, /* 43 reserved */
14459 0, /* 44 reserved */
14460 0, /* 45 reserved */
14461 0, /* 46 reserved */
14462 0, /* 47 reserved */
14463 0, /* 48 reserved */
14464 0, /* 49 reserved */
14465 0, /* 50 reserved */
14466 0, /* 51 reserved */
14467 0, /* 52 reserved */
14468 0, /* 53 reserved */
14469 0, /* 54 reserved */
14470 0, /* 55 reserved */
14471 0, /* 56 cisptr_lsw */
14472 0, /* 57 cisprt_msw */
14473 0, /* 58 subsysvid */
14474 0, /* 59 subsysid */
14475 0, /* 60 reserved */
14476 0, /* 61 reserved */
14477 0, /* 62 reserved */
14478 0 /* 63 reserved */
14482 * Initialize the ADV_DVC_VAR structure.
14484 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14486 * For a non-fatal error return a warning code. If there are no warnings
14487 * then 0 is returned.
14489 STATIC int __init
14490 AdvInitGetConfig(ADV_DVC_VAR *asc_dvc)
14492 ushort warn_code;
14493 AdvPortAddr iop_base;
14494 uchar pci_cmd_reg;
14495 int status;
14497 warn_code = 0;
14498 asc_dvc->err_code = 0;
14499 iop_base = asc_dvc->iop_base;
14502 * PCI Command Register
14504 * Note: AscPCICmdRegBits_BusMastering definition (0x0007) includes
14505 * I/O Space Control, Memory Space Control and Bus Master Control bits.
14508 if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc,
14509 AscPCIConfigCommandRegister))
14510 & AscPCICmdRegBits_BusMastering)
14511 != AscPCICmdRegBits_BusMastering)
14513 pci_cmd_reg |= AscPCICmdRegBits_BusMastering;
14515 DvcAdvWritePCIConfigByte(asc_dvc,
14516 AscPCIConfigCommandRegister, pci_cmd_reg);
14518 if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister))
14519 & AscPCICmdRegBits_BusMastering)
14520 != AscPCICmdRegBits_BusMastering)
14522 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14527 * PCI Latency Timer
14529 * If the "latency timer" register is 0x20 or above, then we don't need
14530 * to change it. Otherwise, set it to 0x20 (i.e. set it to 0x20 if it
14531 * comes up less than 0x20).
14533 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) {
14534 DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer, 0x20);
14535 if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20)
14537 warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE;
14542 * Save the state of the PCI Configuration Command Register
14543 * "Parity Error Response Control" Bit. If the bit is clear (0),
14544 * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore
14545 * DMA parity errors.
14547 asc_dvc->cfg->control_flag = 0;
14548 if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister)
14549 & AscPCICmdRegBits_ParErrRespCtrl)) == 0)
14551 asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR;
14554 asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) |
14555 ADV_LIB_VERSION_MINOR;
14556 asc_dvc->cfg->chip_version =
14557 AdvGetChipVersion(iop_base, asc_dvc->bus_type);
14559 ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n",
14560 (ushort) AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1),
14561 (ushort) ADV_CHIP_ID_BYTE);
14563 ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n",
14564 (ushort) AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0),
14565 (ushort) ADV_CHIP_ID_WORD);
14568 * Reset the chip to start and allow register writes.
14570 if (AdvFindSignature(iop_base) == 0)
14572 asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
14573 return ADV_ERROR;
14575 else {
14577 * The caller must set 'chip_type' to a valid setting.
14579 if (asc_dvc->chip_type != ADV_CHIP_ASC3550 &&
14580 asc_dvc->chip_type != ADV_CHIP_ASC38C0800 &&
14581 asc_dvc->chip_type != ADV_CHIP_ASC38C1600)
14583 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14584 return ADV_ERROR;
14588 * Reset Chip.
14590 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14591 ADV_CTRL_REG_CMD_RESET);
14592 DvcSleepMilliSecond(100);
14593 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG,
14594 ADV_CTRL_REG_CMD_WR_IO_REG);
14596 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
14598 if ((status = AdvInitFrom38C1600EEP(asc_dvc)) == ADV_ERROR)
14600 return ADV_ERROR;
14602 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
14604 if ((status = AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR)
14606 return ADV_ERROR;
14608 } else
14610 if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR)
14612 return ADV_ERROR;
14615 warn_code |= status;
14618 return warn_code;
14622 * Initialize the ASC-3550.
14624 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
14626 * For a non-fatal error return a warning code. If there are no warnings
14627 * then 0 is returned.
14629 * Needed after initialization for error recovery.
14631 STATIC int
14632 AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
14634 AdvPortAddr iop_base;
14635 ushort warn_code;
14636 ADV_DCNT sum;
14637 int begin_addr;
14638 int end_addr;
14639 ushort code_sum;
14640 int word;
14641 int j;
14642 int adv_asc3550_expanded_size;
14643 ADV_CARR_T *carrp;
14644 ADV_DCNT contig_len;
14645 ADV_SDCNT buf_size;
14646 ADV_PADDR carr_paddr;
14647 int i;
14648 ushort scsi_cfg1;
14649 uchar tid;
14650 ushort bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
14651 ushort wdtr_able = 0, sdtr_able, tagqng_able;
14652 uchar max_cmd[ADV_MAX_TID + 1];
14654 /* If there is already an error, don't continue. */
14655 if (asc_dvc->err_code != 0)
14657 return ADV_ERROR;
14661 * The caller must set 'chip_type' to ADV_CHIP_ASC3550.
14663 if (asc_dvc->chip_type != ADV_CHIP_ASC3550)
14665 asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE;
14666 return ADV_ERROR;
14669 warn_code = 0;
14670 iop_base = asc_dvc->iop_base;
14673 * Save the RISC memory BIOS region before writing the microcode.
14674 * The BIOS may already be loaded and using its RISC LRAM region
14675 * so its region must be saved and restored.
14677 * Note: This code makes the assumption, which is currently true,
14678 * that a chip reset does not clear RISC LRAM.
14680 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
14682 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
14686 * Save current per TID negotiated values.
14688 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
14690 ushort bios_version, major, minor;
14692 bios_version = bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM)/2];
14693 major = (bios_version >> 12) & 0xF;
14694 minor = (bios_version >> 8) & 0xF;
14695 if (major < 3 || (major == 3 && minor == 1))
14697 /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */
14698 AdvReadWordLram(iop_base, 0x120, wdtr_able);
14699 } else
14701 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
14704 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
14705 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
14706 for (tid = 0; tid <= ADV_MAX_TID; tid++)
14708 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
14709 max_cmd[tid]);
14713 * Load the Microcode
14715 * Write the microcode image to RISC memory starting at address 0.
14717 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14718 /* Assume the following compressed format of the microcode buffer:
14720 * 254 word (508 byte) table indexed by byte code followed
14721 * by the following byte codes:
14723 * 1-Byte Code:
14724 * 00: Emit word 0 in table.
14725 * 01: Emit word 1 in table.
14727 * FD: Emit word 253 in table.
14729 * Multi-Byte Code:
14730 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
14731 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
14733 word = 0;
14734 for (i = 253 * 2; i < _adv_asc3550_size; i++)
14736 if (_adv_asc3550_buf[i] == 0xff)
14738 for (j = 0; j < _adv_asc3550_buf[i + 1]; j++)
14740 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14741 _adv_asc3550_buf[i + 3] << 8) |
14742 _adv_asc3550_buf[i + 2]));
14743 word++;
14745 i += 3;
14746 } else if (_adv_asc3550_buf[i] == 0xfe)
14748 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14749 _adv_asc3550_buf[i + 2] << 8) |
14750 _adv_asc3550_buf[i + 1]));
14751 i += 2;
14752 word++;
14753 } else
14755 AdvWriteWordAutoIncLram(iop_base, (((ushort)
14756 _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) |
14757 _adv_asc3550_buf[_adv_asc3550_buf[i] * 2]));
14758 word++;
14763 * Set 'word' for later use to clear the rest of memory and save
14764 * the expanded mcode size.
14766 word *= 2;
14767 adv_asc3550_expanded_size = word;
14770 * Clear the rest of ASC-3550 Internal RAM (8KB).
14772 for (; word < ADV_3550_MEMSIZE; word += 2)
14774 AdvWriteWordAutoIncLram(iop_base, 0);
14778 * Verify the microcode checksum.
14780 sum = 0;
14781 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
14783 for (word = 0; word < adv_asc3550_expanded_size; word += 2)
14785 sum += AdvReadWordAutoIncLram(iop_base);
14788 if (sum != _adv_asc3550_chksum)
14790 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
14791 return ADV_ERROR;
14795 * Restore the RISC memory BIOS region.
14797 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
14799 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
14803 * Calculate and write the microcode code checksum to the microcode
14804 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
14806 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
14807 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
14808 code_sum = 0;
14809 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
14810 for (word = begin_addr; word < end_addr; word += 2)
14812 code_sum += AdvReadWordAutoIncLram(iop_base);
14814 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
14817 * Read and save microcode version and date.
14819 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
14820 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
14823 * Set the chip type to indicate the ASC3550.
14825 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550);
14828 * If the PCI Configuration Command Register "Parity Error Response
14829 * Control" Bit was clear (0), then set the microcode variable
14830 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
14831 * to ignore DMA parity errors.
14833 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
14835 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14836 word |= CONTROL_FLAG_IGNORE_PERR;
14837 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
14841 * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO
14842 * threshold of 128 bytes. This register is only accessible to the host.
14844 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
14845 START_CTL_EMFU | READ_CMD_MRM);
14848 * Microcode operating variables for WDTR, SDTR, and command tag
14849 * queuing will be set in AdvInquiryHandling() based on what a
14850 * device reports it is capable of in Inquiry byte 7.
14852 * If SCSI Bus Resets have been disabled, then directly set
14853 * SDTR and WDTR from the EEPROM configuration. This will allow
14854 * the BIOS and warm boot to work without a SCSI bus hang on
14855 * the Inquiry caused by host and target mismatched DTR values.
14856 * Without the SCSI Bus Reset, before an Inquiry a device can't
14857 * be assumed to be in Asynchronous, Narrow mode.
14859 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
14861 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
14862 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
14866 * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2,
14867 * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID
14868 * bitmask. These values determine the maximum SDTR speed negotiated
14869 * with a device.
14871 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
14872 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
14873 * without determining here whether the device supports SDTR.
14875 * 4-bit speed SDTR speed name
14876 * =========== ===============
14877 * 0000b (0x0) SDTR disabled
14878 * 0001b (0x1) 5 Mhz
14879 * 0010b (0x2) 10 Mhz
14880 * 0011b (0x3) 20 Mhz (Ultra)
14881 * 0100b (0x4) 40 Mhz (LVD/Ultra2)
14882 * 0101b (0x5) 80 Mhz (LVD2/Ultra3)
14883 * 0110b (0x6) Undefined
14885 * 1111b (0xF) Undefined
14887 word = 0;
14888 for (tid = 0; tid <= ADV_MAX_TID; tid++)
14890 if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able)
14892 /* Set Ultra speed for TID 'tid'. */
14893 word |= (0x3 << (4 * (tid % 4)));
14894 } else
14896 /* Set Fast speed for TID 'tid'. */
14897 word |= (0x2 << (4 * (tid % 4)));
14899 if (tid == 3) /* Check if done with sdtr_speed1. */
14901 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word);
14902 word = 0;
14903 } else if (tid == 7) /* Check if done with sdtr_speed2. */
14905 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word);
14906 word = 0;
14907 } else if (tid == 11) /* Check if done with sdtr_speed3. */
14909 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word);
14910 word = 0;
14911 } else if (tid == 15) /* Check if done with sdtr_speed4. */
14913 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word);
14914 /* End of loop. */
14919 * Set microcode operating variable for the disconnect per TID bitmask.
14921 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
14924 * Set SCSI_CFG0 Microcode Default Value.
14926 * The microcode will set the SCSI_CFG0 register using this value
14927 * after it is started below.
14929 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
14930 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
14931 asc_dvc->chip_scsi_id);
14934 * Determine SCSI_CFG1 Microcode Default Value.
14936 * The microcode will set the SCSI_CFG1 register using this value
14937 * after it is started below.
14940 /* Read current SCSI_CFG1 Register value. */
14941 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
14944 * If all three connectors are in use, return an error.
14946 if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 ||
14947 (scsi_cfg1 & CABLE_ILLEGAL_B) == 0)
14949 asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION;
14950 return ADV_ERROR;
14954 * If the internal narrow cable is reversed all of the SCSI_CTRL
14955 * register signals will be set. Check for and return an error if
14956 * this condition is found.
14958 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
14960 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
14961 return ADV_ERROR;
14965 * If this is a differential board and a single-ended device
14966 * is attached to one of the connectors, return an error.
14968 if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0)
14970 asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE;
14971 return ADV_ERROR;
14975 * If automatic termination control is enabled, then set the
14976 * termination value based on a table listed in a_condor.h.
14978 * If manual termination was specified with an EEPROM setting
14979 * then 'termination' was set-up in AdvInitFrom3550EEPROM() and
14980 * is ready to be 'ored' into SCSI_CFG1.
14982 if (asc_dvc->cfg->termination == 0)
14985 * The software always controls termination by setting TERM_CTL_SEL.
14986 * If TERM_CTL_SEL were set to 0, the hardware would set termination.
14988 asc_dvc->cfg->termination |= TERM_CTL_SEL;
14990 switch(scsi_cfg1 & CABLE_DETECT)
14992 /* TERM_CTL_H: on, TERM_CTL_L: on */
14993 case 0x3: case 0x7: case 0xB: case 0xD: case 0xE: case 0xF:
14994 asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L);
14995 break;
14997 /* TERM_CTL_H: on, TERM_CTL_L: off */
14998 case 0x1: case 0x5: case 0x9: case 0xA: case 0xC:
14999 asc_dvc->cfg->termination |= TERM_CTL_H;
15000 break;
15002 /* TERM_CTL_H: off, TERM_CTL_L: off */
15003 case 0x2: case 0x6:
15004 break;
15009 * Clear any set TERM_CTL_H and TERM_CTL_L bits.
15011 scsi_cfg1 &= ~TERM_CTL;
15014 * Invert the TERM_CTL_H and TERM_CTL_L bits and then
15015 * set 'scsi_cfg1'. The TERM_POL bit does not need to be
15016 * referenced, because the hardware internally inverts
15017 * the Termination High and Low bits if TERM_POL is set.
15019 scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL));
15022 * Set SCSI_CFG1 Microcode Default Value
15024 * Set filter value and possibly modified termination control
15025 * bits in the Microcode SCSI_CFG1 Register Value.
15027 * The microcode will set the SCSI_CFG1 register using this value
15028 * after it is started below.
15030 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1,
15031 FLTR_DISABLE | scsi_cfg1);
15034 * Set MEM_CFG Microcode Default Value
15036 * The microcode will set the MEM_CFG register using this value
15037 * after it is started below.
15039 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15040 * are defined.
15042 * ASC-3550 has 8KB internal memory.
15044 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15045 BIOS_EN | RAM_SZ_8KB);
15048 * Set SEL_MASK Microcode Default Value
15050 * The microcode will set the SEL_MASK register using this value
15051 * after it is started below.
15053 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15054 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15057 * Build carrier freelist.
15059 * Driver must have already allocated memory and set 'carrier_buf'.
15061 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15063 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15064 asc_dvc->carr_freelist = NULL;
15065 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
15067 buf_size = ADV_CARRIER_BUFSIZE;
15068 } else
15070 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15073 do {
15075 * Get physical address of the carrier 'carrp'.
15077 contig_len = sizeof(ADV_CARR_T);
15078 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
15079 (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
15081 buf_size -= sizeof(ADV_CARR_T);
15084 * If the current carrier is not physically contiguous, then
15085 * maybe there was a page crossing. Try the next carrier aligned
15086 * start address.
15088 if (contig_len < sizeof(ADV_CARR_T))
15090 carrp++;
15091 continue;
15094 carrp->carr_pa = carr_paddr;
15095 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15098 * Insert the carrier at the beginning of the freelist.
15100 carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15101 asc_dvc->carr_freelist = carrp;
15103 carrp++;
15105 while (buf_size > 0);
15108 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15111 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
15113 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15114 return ADV_ERROR;
15116 asc_dvc->carr_freelist = (ADV_CARR_T *)
15117 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15120 * The first command issued will be placed in the stopper carrier.
15122 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15125 * Set RISC ICQ physical address start value.
15127 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15130 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15132 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
15134 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15135 return ADV_ERROR;
15137 asc_dvc->carr_freelist = (ADV_CARR_T *)
15138 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15141 * The first command completed by the RISC will be placed in
15142 * the stopper.
15144 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15145 * completed the RISC will set the ASC_RQ_STOPPER bit.
15147 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15150 * Set RISC IRQ physical address start value.
15152 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15153 asc_dvc->carr_pending_cnt = 0;
15155 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15156 (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
15158 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15159 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15161 /* finally, finally, gentlemen, start your engine */
15162 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15165 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15166 * Resets should be performed. The RISC has to be running
15167 * to issue a SCSI Bus Reset.
15169 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
15172 * If the BIOS Signature is present in memory, restore the
15173 * BIOS Handshake Configuration Table and do not perform
15174 * a SCSI Bus Reset.
15176 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
15179 * Restore per TID negotiated values.
15181 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15182 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15183 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15184 for (tid = 0; tid <= ADV_MAX_TID; tid++)
15186 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15187 max_cmd[tid]);
15189 } else
15191 if (AdvResetSB(asc_dvc) != ADV_TRUE)
15193 warn_code = ASC_WARN_BUSRESET_ERROR;
15198 return warn_code;
15202 * Initialize the ASC-38C0800.
15204 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
15206 * For a non-fatal error return a warning code. If there are no warnings
15207 * then 0 is returned.
15209 * Needed after initialization for error recovery.
15211 STATIC int
15212 AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
15214 AdvPortAddr iop_base;
15215 ushort warn_code;
15216 ADV_DCNT sum;
15217 int begin_addr;
15218 int end_addr;
15219 ushort code_sum;
15220 int word;
15221 int j;
15222 int adv_asc38C0800_expanded_size;
15223 ADV_CARR_T *carrp;
15224 ADV_DCNT contig_len;
15225 ADV_SDCNT buf_size;
15226 ADV_PADDR carr_paddr;
15227 int i;
15228 ushort scsi_cfg1;
15229 uchar byte;
15230 uchar tid;
15231 ushort bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
15232 ushort wdtr_able, sdtr_able, tagqng_able;
15233 uchar max_cmd[ADV_MAX_TID + 1];
15235 /* If there is already an error, don't continue. */
15236 if (asc_dvc->err_code != 0)
15238 return ADV_ERROR;
15242 * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800.
15244 if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800)
15246 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
15247 return ADV_ERROR;
15250 warn_code = 0;
15251 iop_base = asc_dvc->iop_base;
15254 * Save the RISC memory BIOS region before writing the microcode.
15255 * The BIOS may already be loaded and using its RISC LRAM region
15256 * so its region must be saved and restored.
15258 * Note: This code makes the assumption, which is currently true,
15259 * that a chip reset does not clear RISC LRAM.
15261 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15263 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15267 * Save current per TID negotiated values.
15269 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15270 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15271 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15272 for (tid = 0; tid <= ADV_MAX_TID; tid++)
15274 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15275 max_cmd[tid]);
15279 * RAM BIST (RAM Built-In Self Test)
15281 * Address : I/O base + offset 0x38h register (byte).
15282 * Function: Bit 7-6(RW) : RAM mode
15283 * Normal Mode : 0x00
15284 * Pre-test Mode : 0x40
15285 * RAM Test Mode : 0x80
15286 * Bit 5 : unused
15287 * Bit 4(RO) : Done bit
15288 * Bit 3-0(RO) : Status
15289 * Host Error : 0x08
15290 * Int_RAM Error : 0x04
15291 * RISC Error : 0x02
15292 * SCSI Error : 0x01
15293 * No Error : 0x00
15295 * Note: RAM BIST code should be put right here, before loading the
15296 * microcode and after saving the RISC memory BIOS region.
15300 * LRAM Pre-test
15302 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15303 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15304 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15305 * to NORMAL_MODE, return an error too.
15307 for (i = 0; i < 2; i++)
15309 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15310 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15311 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15312 if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE)
15314 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15315 return ADV_ERROR;
15318 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15319 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15320 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15321 != NORMAL_VALUE)
15323 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15324 return ADV_ERROR;
15329 * LRAM Test - It takes about 1.5 ms to run through the test.
15331 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15332 * If Done bit not set or Status not 0, save register byte, set the
15333 * err_code, and return an error.
15335 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15336 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
15338 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15339 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0)
15341 /* Get here if Done bit not set or Status not 0. */
15342 asc_dvc->bist_err_code = byte; /* for BIOS display message */
15343 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15344 return ADV_ERROR;
15347 /* We need to reset back to normal mode after LRAM test passes. */
15348 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15351 * Load the Microcode
15353 * Write the microcode image to RISC memory starting at address 0.
15356 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15358 /* Assume the following compressed format of the microcode buffer:
15360 * 254 word (508 byte) table indexed by byte code followed
15361 * by the following byte codes:
15363 * 1-Byte Code:
15364 * 00: Emit word 0 in table.
15365 * 01: Emit word 1 in table.
15367 * FD: Emit word 253 in table.
15369 * Multi-Byte Code:
15370 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15371 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
15373 word = 0;
15374 for (i = 253 * 2; i < _adv_asc38C0800_size; i++)
15376 if (_adv_asc38C0800_buf[i] == 0xff)
15378 for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++)
15380 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15381 _adv_asc38C0800_buf[i + 3] << 8) |
15382 _adv_asc38C0800_buf[i + 2]));
15383 word++;
15385 i += 3;
15386 } else if (_adv_asc38C0800_buf[i] == 0xfe)
15388 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15389 _adv_asc38C0800_buf[i + 2] << 8) |
15390 _adv_asc38C0800_buf[i + 1]));
15391 i += 2;
15392 word++;
15393 } else
15395 AdvWriteWordAutoIncLram(iop_base, (((ushort)
15396 _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) |
15397 _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2]));
15398 word++;
15403 * Set 'word' for later use to clear the rest of memory and save
15404 * the expanded mcode size.
15406 word *= 2;
15407 adv_asc38C0800_expanded_size = word;
15410 * Clear the rest of ASC-38C0800 Internal RAM (16KB).
15412 for (; word < ADV_38C0800_MEMSIZE; word += 2)
15414 AdvWriteWordAutoIncLram(iop_base, 0);
15418 * Verify the microcode checksum.
15420 sum = 0;
15421 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15423 for (word = 0; word < adv_asc38C0800_expanded_size; word += 2)
15425 sum += AdvReadWordAutoIncLram(iop_base);
15427 ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i);
15429 ASC_DBG2(1,
15430 "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n",
15431 (ulong) sum, (ulong) _adv_asc38C0800_chksum);
15433 if (sum != _adv_asc38C0800_chksum)
15435 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
15436 return ADV_ERROR;
15440 * Restore the RISC memory BIOS region.
15442 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15444 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15448 * Calculate and write the microcode code checksum to the microcode
15449 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
15451 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
15452 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
15453 code_sum = 0;
15454 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
15455 for (word = begin_addr; word < end_addr; word += 2)
15457 code_sum += AdvReadWordAutoIncLram(iop_base);
15459 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
15462 * Read microcode version and date.
15464 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
15465 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
15468 * Set the chip type to indicate the ASC38C0800.
15470 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800);
15473 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
15474 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
15475 * cable detection and then we are able to read C_DET[3:0].
15477 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
15478 * Microcode Default Value' section below.
15480 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15481 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV);
15484 * If the PCI Configuration Command Register "Parity Error Response
15485 * Control" Bit was clear (0), then set the microcode variable
15486 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
15487 * to ignore DMA parity errors.
15489 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
15491 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15492 word |= CONTROL_FLAG_IGNORE_PERR;
15493 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
15497 * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2]
15498 * bits for the default FIFO threshold.
15500 * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes.
15502 * For DMA Errata #4 set the BC_THRESH_ENB bit.
15504 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
15505 BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
15508 * Microcode operating variables for WDTR, SDTR, and command tag
15509 * queuing will be set in AdvInquiryHandling() based on what a
15510 * device reports it is capable of in Inquiry byte 7.
15512 * If SCSI Bus Resets have been disabled, then directly set
15513 * SDTR and WDTR from the EEPROM configuration. This will allow
15514 * the BIOS and warm boot to work without a SCSI bus hang on
15515 * the Inquiry caused by host and target mismatched DTR values.
15516 * Without the SCSI Bus Reset, before an Inquiry a device can't
15517 * be assumed to be in Asynchronous, Narrow mode.
15519 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
15521 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
15522 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
15526 * Set microcode operating variables for DISC and SDTR_SPEED1,
15527 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
15528 * configuration values.
15530 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
15531 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
15532 * without determining here whether the device supports SDTR.
15534 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
15535 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
15536 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
15537 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
15538 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
15541 * Set SCSI_CFG0 Microcode Default Value.
15543 * The microcode will set the SCSI_CFG0 register using this value
15544 * after it is started below.
15546 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
15547 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
15548 asc_dvc->chip_scsi_id);
15551 * Determine SCSI_CFG1 Microcode Default Value.
15553 * The microcode will set the SCSI_CFG1 register using this value
15554 * after it is started below.
15557 /* Read current SCSI_CFG1 Register value. */
15558 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
15561 * If the internal narrow cable is reversed all of the SCSI_CTRL
15562 * register signals will be set. Check for and return an error if
15563 * this condition is found.
15565 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
15567 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
15568 return ADV_ERROR;
15572 * All kind of combinations of devices attached to one of four connectors
15573 * are acceptable except HVD device attached. For example, LVD device can
15574 * be attached to SE connector while SE device attached to LVD connector.
15575 * If LVD device attached to SE connector, it only runs up to Ultra speed.
15577 * If an HVD device is attached to one of LVD connectors, return an error.
15578 * However, there is no way to detect HVD device attached to SE connectors.
15580 if (scsi_cfg1 & HVD)
15582 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
15583 return ADV_ERROR;
15587 * If either SE or LVD automatic termination control is enabled, then
15588 * set the termination value based on a table listed in a_condor.h.
15590 * If manual termination was specified with an EEPROM setting then
15591 * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to
15592 * be 'ored' into SCSI_CFG1.
15594 if ((asc_dvc->cfg->termination & TERM_SE) == 0)
15596 /* SE automatic termination control is enabled. */
15597 switch(scsi_cfg1 & C_DET_SE)
15599 /* TERM_SE_HI: on, TERM_SE_LO: on */
15600 case 0x1: case 0x2: case 0x3:
15601 asc_dvc->cfg->termination |= TERM_SE;
15602 break;
15604 /* TERM_SE_HI: on, TERM_SE_LO: off */
15605 case 0x0:
15606 asc_dvc->cfg->termination |= TERM_SE_HI;
15607 break;
15611 if ((asc_dvc->cfg->termination & TERM_LVD) == 0)
15613 /* LVD automatic termination control is enabled. */
15614 switch(scsi_cfg1 & C_DET_LVD)
15616 /* TERM_LVD_HI: on, TERM_LVD_LO: on */
15617 case 0x4: case 0x8: case 0xC:
15618 asc_dvc->cfg->termination |= TERM_LVD;
15619 break;
15621 /* TERM_LVD_HI: off, TERM_LVD_LO: off */
15622 case 0x0:
15623 break;
15628 * Clear any set TERM_SE and TERM_LVD bits.
15630 scsi_cfg1 &= (~TERM_SE & ~TERM_LVD);
15633 * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'.
15635 scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0);
15638 * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits
15639 * and set possibly modified termination control bits in the Microcode
15640 * SCSI_CFG1 Register Value.
15642 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE);
15645 * Set SCSI_CFG1 Microcode Default Value
15647 * Set possibly modified termination control and reset DIS_TERM_DRV
15648 * bits in the Microcode SCSI_CFG1 Register Value.
15650 * The microcode will set the SCSI_CFG1 register using this value
15651 * after it is started below.
15653 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
15656 * Set MEM_CFG Microcode Default Value
15658 * The microcode will set the MEM_CFG register using this value
15659 * after it is started below.
15661 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
15662 * are defined.
15664 * ASC-38C0800 has 16KB internal memory.
15666 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
15667 BIOS_EN | RAM_SZ_16KB);
15670 * Set SEL_MASK Microcode Default Value
15672 * The microcode will set the SEL_MASK register using this value
15673 * after it is started below.
15675 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
15676 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
15679 * Build the carrier freelist.
15681 * Driver must have already allocated memory and set 'carrier_buf'.
15683 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
15685 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
15686 asc_dvc->carr_freelist = NULL;
15687 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
15689 buf_size = ADV_CARRIER_BUFSIZE;
15690 } else
15692 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
15695 do {
15697 * Get physical address for the carrier 'carrp'.
15699 contig_len = sizeof(ADV_CARR_T);
15700 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
15701 (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
15703 buf_size -= sizeof(ADV_CARR_T);
15706 * If the current carrier is not physically contiguous, then
15707 * maybe there was a page crossing. Try the next carrier aligned
15708 * start address.
15710 if (contig_len < sizeof(ADV_CARR_T))
15712 carrp++;
15713 continue;
15716 carrp->carr_pa = carr_paddr;
15717 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
15720 * Insert the carrier at the beginning of the freelist.
15722 carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
15723 asc_dvc->carr_freelist = carrp;
15725 carrp++;
15727 while (buf_size > 0);
15730 * Set-up the Host->RISC Initiator Command Queue (ICQ).
15733 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
15735 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15736 return ADV_ERROR;
15738 asc_dvc->carr_freelist = (ADV_CARR_T *)
15739 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
15742 * The first command issued will be placed in the stopper carrier.
15744 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15747 * Set RISC ICQ physical address start value.
15748 * carr_pa is LE, must be native before write
15750 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
15753 * Set-up the RISC->Host Initiator Response Queue (IRQ).
15755 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
15757 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
15758 return ADV_ERROR;
15760 asc_dvc->carr_freelist = (ADV_CARR_T *)
15761 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
15764 * The first command completed by the RISC will be placed in
15765 * the stopper.
15767 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
15768 * completed the RISC will set the ASC_RQ_STOPPER bit.
15770 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
15773 * Set RISC IRQ physical address start value.
15775 * carr_pa is LE, must be native before write *
15777 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
15778 asc_dvc->carr_pending_cnt = 0;
15780 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
15781 (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
15783 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
15784 AdvWriteWordRegister(iop_base, IOPW_PC, word);
15786 /* finally, finally, gentlemen, start your engine */
15787 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
15790 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
15791 * Resets should be performed. The RISC has to be running
15792 * to issue a SCSI Bus Reset.
15794 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
15797 * If the BIOS Signature is present in memory, restore the
15798 * BIOS Handshake Configuration Table and do not perform
15799 * a SCSI Bus Reset.
15801 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
15804 * Restore per TID negotiated values.
15806 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15807 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15808 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15809 for (tid = 0; tid <= ADV_MAX_TID; tid++)
15811 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15812 max_cmd[tid]);
15814 } else
15816 if (AdvResetSB(asc_dvc) != ADV_TRUE)
15818 warn_code = ASC_WARN_BUSRESET_ERROR;
15823 return warn_code;
15827 * Initialize the ASC-38C1600.
15829 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
15831 * For a non-fatal error return a warning code. If there are no warnings
15832 * then 0 is returned.
15834 * Needed after initialization for error recovery.
15836 STATIC int
15837 AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
15839 AdvPortAddr iop_base;
15840 ushort warn_code;
15841 ADV_DCNT sum;
15842 int begin_addr;
15843 int end_addr;
15844 ushort code_sum;
15845 long word;
15846 int j;
15847 int adv_asc38C1600_expanded_size;
15848 ADV_CARR_T *carrp;
15849 ADV_DCNT contig_len;
15850 ADV_SDCNT buf_size;
15851 ADV_PADDR carr_paddr;
15852 int i;
15853 ushort scsi_cfg1;
15854 uchar byte;
15855 uchar tid;
15856 ushort bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory 0x40-0x8F. */
15857 ushort wdtr_able, sdtr_able, ppr_able, tagqng_able;
15858 uchar max_cmd[ASC_MAX_TID + 1];
15860 /* If there is already an error, don't continue. */
15861 if (asc_dvc->err_code != 0)
15863 return ADV_ERROR;
15867 * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600.
15869 if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600)
15871 asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE;
15872 return ADV_ERROR;
15875 warn_code = 0;
15876 iop_base = asc_dvc->iop_base;
15879 * Save the RISC memory BIOS region before writing the microcode.
15880 * The BIOS may already be loaded and using its RISC LRAM region
15881 * so its region must be saved and restored.
15883 * Note: This code makes the assumption, which is currently true,
15884 * that a chip reset does not clear RISC LRAM.
15886 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
15888 AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
15892 * Save current per TID negotiated values.
15894 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
15895 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
15896 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
15897 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
15898 for (tid = 0; tid <= ASC_MAX_TID; tid++)
15900 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
15901 max_cmd[tid]);
15905 * RAM BIST (Built-In Self Test)
15907 * Address : I/O base + offset 0x38h register (byte).
15908 * Function: Bit 7-6(RW) : RAM mode
15909 * Normal Mode : 0x00
15910 * Pre-test Mode : 0x40
15911 * RAM Test Mode : 0x80
15912 * Bit 5 : unused
15913 * Bit 4(RO) : Done bit
15914 * Bit 3-0(RO) : Status
15915 * Host Error : 0x08
15916 * Int_RAM Error : 0x04
15917 * RISC Error : 0x02
15918 * SCSI Error : 0x01
15919 * No Error : 0x00
15921 * Note: RAM BIST code should be put right here, before loading the
15922 * microcode and after saving the RISC memory BIOS region.
15926 * LRAM Pre-test
15928 * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds.
15929 * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return
15930 * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset
15931 * to NORMAL_MODE, return an error too.
15933 for (i = 0; i < 2; i++)
15935 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE);
15936 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15937 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15938 if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != PRE_TEST_VALUE)
15940 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15941 return ADV_ERROR;
15944 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15945 DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */
15946 if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST)
15947 != NORMAL_VALUE)
15949 asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST;
15950 return ADV_ERROR;
15955 * LRAM Test - It takes about 1.5 ms to run through the test.
15957 * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds.
15958 * If Done bit not set or Status not 0, save register byte, set the
15959 * err_code, and return an error.
15961 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE);
15962 DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */
15964 byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST);
15965 if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0)
15967 /* Get here if Done bit not set or Status not 0. */
15968 asc_dvc->bist_err_code = byte; /* for BIOS display message */
15969 asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST;
15970 return ADV_ERROR;
15973 /* We need to reset back to normal mode after LRAM test passes. */
15974 AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
15977 * Load the Microcode
15979 * Write the microcode image to RISC memory starting at address 0.
15982 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
15985 * Assume the following compressed format of the microcode buffer:
15987 * 254 word (508 byte) table indexed by byte code followed
15988 * by the following byte codes:
15990 * 1-Byte Code:
15991 * 00: Emit word 0 in table.
15992 * 01: Emit word 1 in table.
15994 * FD: Emit word 253 in table.
15996 * Multi-Byte Code:
15997 * FE WW WW: (3 byte code) Word to emit is the next word WW WW.
15998 * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW.
16000 word = 0;
16001 for (i = 253 * 2; i < _adv_asc38C1600_size; i++)
16003 if (_adv_asc38C1600_buf[i] == 0xff)
16005 for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++)
16007 AdvWriteWordAutoIncLram(iop_base, (((ushort)
16008 _adv_asc38C1600_buf[i + 3] << 8) |
16009 _adv_asc38C1600_buf[i + 2]));
16010 word++;
16012 i += 3;
16013 } else if (_adv_asc38C1600_buf[i] == 0xfe)
16015 AdvWriteWordAutoIncLram(iop_base, (((ushort)
16016 _adv_asc38C1600_buf[i + 2] << 8) |
16017 _adv_asc38C1600_buf[i + 1]));
16018 i += 2;
16019 word++;
16020 } else
16022 AdvWriteWordAutoIncLram(iop_base, (((ushort)
16023 _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) |
16024 _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2]));
16025 word++;
16030 * Set 'word' for later use to clear the rest of memory and save
16031 * the expanded mcode size.
16033 word *= 2;
16034 adv_asc38C1600_expanded_size = word;
16037 * Clear the rest of ASC-38C1600 Internal RAM (32KB).
16039 for (; word < ADV_38C1600_MEMSIZE; word += 2)
16041 AdvWriteWordAutoIncLram(iop_base, 0);
16045 * Verify the microcode checksum.
16047 sum = 0;
16048 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0);
16050 for (word = 0; word < adv_asc38C1600_expanded_size; word += 2)
16052 sum += AdvReadWordAutoIncLram(iop_base);
16055 if (sum != _adv_asc38C1600_chksum)
16057 asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
16058 return ADV_ERROR;
16062 * Restore the RISC memory BIOS region.
16064 for (i = 0; i < ASC_MC_BIOSLEN/2; i++)
16066 AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]);
16070 * Calculate and write the microcode code checksum to the microcode
16071 * code checksum location ASC_MC_CODE_CHK_SUM (0x2C).
16073 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr);
16074 AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr);
16075 code_sum = 0;
16076 AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr);
16077 for (word = begin_addr; word < end_addr; word += 2)
16079 code_sum += AdvReadWordAutoIncLram(iop_base);
16081 AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum);
16084 * Read microcode version and date.
16086 AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, asc_dvc->cfg->mcode_date);
16087 AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, asc_dvc->cfg->mcode_version);
16090 * Set the chip type to indicate the ASC38C1600.
16092 AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600);
16095 * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register.
16096 * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current
16097 * cable detection and then we are able to read C_DET[3:0].
16099 * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1
16100 * Microcode Default Value' section below.
16102 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
16103 AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, scsi_cfg1 | DIS_TERM_DRV);
16106 * If the PCI Configuration Command Register "Parity Error Response
16107 * Control" Bit was clear (0), then set the microcode variable
16108 * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode
16109 * to ignore DMA parity errors.
16111 if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR)
16113 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16114 word |= CONTROL_FLAG_IGNORE_PERR;
16115 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16119 * If the BIOS control flag AIPP (Asynchronous Information
16120 * Phase Protection) disable bit is not set, then set the firmware
16121 * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable
16122 * AIPP checking and encoding.
16124 if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0)
16126 AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16127 word |= CONTROL_FLAG_ENABLE_AIPP;
16128 AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word);
16132 * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4],
16133 * and START_CTL_TH [3:2].
16135 AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0,
16136 FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM);
16139 * Microcode operating variables for WDTR, SDTR, and command tag
16140 * queuing will be set in AdvInquiryHandling() based on what a
16141 * device reports it is capable of in Inquiry byte 7.
16143 * If SCSI Bus Resets have been disabled, then directly set
16144 * SDTR and WDTR from the EEPROM configuration. This will allow
16145 * the BIOS and warm boot to work without a SCSI bus hang on
16146 * the Inquiry caused by host and target mismatched DTR values.
16147 * Without the SCSI Bus Reset, before an Inquiry a device can't
16148 * be assumed to be in Asynchronous, Narrow mode.
16150 if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0)
16152 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, asc_dvc->wdtr_able);
16153 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, asc_dvc->sdtr_able);
16157 * Set microcode operating variables for DISC and SDTR_SPEED1,
16158 * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM
16159 * configuration values.
16161 * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2,
16162 * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them
16163 * without determining here whether the device supports SDTR.
16165 AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, asc_dvc->cfg->disc_enable);
16166 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1);
16167 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2);
16168 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3);
16169 AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4);
16172 * Set SCSI_CFG0 Microcode Default Value.
16174 * The microcode will set the SCSI_CFG0 register using this value
16175 * after it is started below.
16177 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0,
16178 PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN |
16179 asc_dvc->chip_scsi_id);
16182 * Calculate SCSI_CFG1 Microcode Default Value.
16184 * The microcode will set the SCSI_CFG1 register using this value
16185 * after it is started below.
16187 * Each ASC-38C1600 function has only two cable detect bits.
16188 * The bus mode override bits are in IOPB_SOFT_OVER_WR.
16190 scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1);
16193 * If the cable is reversed all of the SCSI_CTRL register signals
16194 * will be set. Check for and return an error if this condition is
16195 * found.
16197 if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07)
16199 asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE;
16200 return ADV_ERROR;
16204 * Each ASC-38C1600 function has two connectors. Only an HVD device
16205 * can not be connected to either connector. An LVD device or SE device
16206 * may be connected to either connecor. If an SE device is connected,
16207 * then at most Ultra speed (20 Mhz) can be used on both connectors.
16209 * If an HVD device is attached, return an error.
16211 if (scsi_cfg1 & HVD)
16213 asc_dvc->err_code |= ASC_IERR_HVD_DEVICE;
16214 return ADV_ERROR;
16218 * Each function in the ASC-38C1600 uses only the SE cable detect and
16219 * termination because there are two connectors for each function. Each
16220 * function may use either LVD or SE mode. Corresponding the SE automatic
16221 * termination control EEPROM bits are used for each function. Each
16222 * function has its own EEPROM. If SE automatic control is enabled for
16223 * the function, then set the termination value based on a table listed
16224 * in a_condor.h.
16226 * If manual termination is specified in the EEPROM for the function,
16227 * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is
16228 * ready to be 'ored' into SCSI_CFG1.
16230 if ((asc_dvc->cfg->termination & TERM_SE) == 0)
16232 /* SE automatic termination control is enabled. */
16233 switch(scsi_cfg1 & C_DET_SE)
16235 /* TERM_SE_HI: on, TERM_SE_LO: on */
16236 case 0x1: case 0x2: case 0x3:
16237 asc_dvc->cfg->termination |= TERM_SE;
16238 break;
16240 case 0x0:
16241 if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0)
16243 /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */
16245 else
16247 /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */
16248 asc_dvc->cfg->termination |= TERM_SE_HI;
16250 break;
16255 * Clear any set TERM_SE bits.
16257 scsi_cfg1 &= ~TERM_SE;
16260 * Invert the TERM_SE bits and then set 'scsi_cfg1'.
16262 scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE);
16265 * Clear Big Endian and Terminator Polarity bits and set possibly
16266 * modified termination control bits in the Microcode SCSI_CFG1
16267 * Register Value.
16269 * Big Endian bit is not used even on big endian machines.
16271 scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL);
16274 * Set SCSI_CFG1 Microcode Default Value
16276 * Set possibly modified termination control bits in the Microcode
16277 * SCSI_CFG1 Register Value.
16279 * The microcode will set the SCSI_CFG1 register using this value
16280 * after it is started below.
16282 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1);
16285 * Set MEM_CFG Microcode Default Value
16287 * The microcode will set the MEM_CFG register using this value
16288 * after it is started below.
16290 * MEM_CFG may be accessed as a word or byte, but only bits 0-7
16291 * are defined.
16293 * ASC-38C1600 has 32KB internal memory.
16295 * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come
16296 * out a special 16K Adv Library and Microcode version. After the issue
16297 * resolved, we should turn back to the 32K support. Both a_condor.h and
16298 * mcode.sas files also need to be updated.
16300 * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG,
16301 * BIOS_EN | RAM_SZ_32KB);
16303 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, BIOS_EN | RAM_SZ_16KB);
16306 * Set SEL_MASK Microcode Default Value
16308 * The microcode will set the SEL_MASK register using this value
16309 * after it is started below.
16311 AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK,
16312 ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id));
16315 * Build the carrier freelist.
16317 * Driver must have already allocated memory and set 'carrier_buf'.
16320 ASC_ASSERT(asc_dvc->carrier_buf != NULL);
16322 carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf);
16323 asc_dvc->carr_freelist = NULL;
16324 if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf)
16326 buf_size = ADV_CARRIER_BUFSIZE;
16327 } else
16329 buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T);
16332 do {
16334 * Get physical address for the carrier 'carrp'.
16336 contig_len = sizeof(ADV_CARR_T);
16337 carr_paddr = cpu_to_le32(DvcGetPhyAddr(asc_dvc, NULL, (uchar *) carrp,
16338 (ADV_SDCNT *) &contig_len, ADV_IS_CARRIER_FLAG));
16340 buf_size -= sizeof(ADV_CARR_T);
16343 * If the current carrier is not physically contiguous, then
16344 * maybe there was a page crossing. Try the next carrier aligned
16345 * start address.
16347 if (contig_len < sizeof(ADV_CARR_T))
16349 carrp++;
16350 continue;
16353 carrp->carr_pa = carr_paddr;
16354 carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp));
16357 * Insert the carrier at the beginning of the freelist.
16359 carrp->next_vpa = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
16360 asc_dvc->carr_freelist = carrp;
16362 carrp++;
16364 while (buf_size > 0);
16367 * Set-up the Host->RISC Initiator Command Queue (ICQ).
16369 if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL)
16371 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16372 return ADV_ERROR;
16374 asc_dvc->carr_freelist = (ADV_CARR_T *)
16375 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa));
16378 * The first command issued will be placed in the stopper carrier.
16380 asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16383 * Set RISC ICQ physical address start value. Initialize the
16384 * COMMA register to the same value otherwise the RISC will
16385 * prematurely detect a command is available.
16387 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa);
16388 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
16389 le32_to_cpu(asc_dvc->icq_sp->carr_pa));
16392 * Set-up the RISC->Host Initiator Response Queue (IRQ).
16394 if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL)
16396 asc_dvc->err_code |= ASC_IERR_NO_CARRIER;
16397 return ADV_ERROR;
16399 asc_dvc->carr_freelist = (ADV_CARR_T *)
16400 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa));
16403 * The first command completed by the RISC will be placed in
16404 * the stopper.
16406 * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is
16407 * completed the RISC will set the ASC_RQ_STOPPER bit.
16409 asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
16412 * Set RISC IRQ physical address start value.
16414 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa);
16415 asc_dvc->carr_pending_cnt = 0;
16417 AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES,
16418 (ADV_INTR_ENABLE_HOST_INTR | ADV_INTR_ENABLE_GLOBAL_INTR));
16419 AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word);
16420 AdvWriteWordRegister(iop_base, IOPW_PC, word);
16422 /* finally, finally, gentlemen, start your engine */
16423 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN);
16426 * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus
16427 * Resets should be performed. The RISC has to be running
16428 * to issue a SCSI Bus Reset.
16430 if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS)
16433 * If the BIOS Signature is present in memory, restore the
16434 * per TID microcode operating variables.
16436 if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA)
16439 * Restore per TID negotiated values.
16441 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
16442 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
16443 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
16444 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
16445 for (tid = 0; tid <= ASC_MAX_TID; tid++)
16447 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
16448 max_cmd[tid]);
16450 } else
16452 if (AdvResetSB(asc_dvc) != ADV_TRUE)
16454 warn_code = ASC_WARN_BUSRESET_ERROR;
16459 return warn_code;
16463 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16464 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16465 * all of this is done.
16467 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16469 * For a non-fatal error return a warning code. If there are no warnings
16470 * then 0 is returned.
16472 * Note: Chip is stopped on entry.
16474 STATIC int __init
16475 AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc)
16477 AdvPortAddr iop_base;
16478 ushort warn_code;
16479 ADVEEP_3550_CONFIG eep_config;
16480 int i;
16482 iop_base = asc_dvc->iop_base;
16484 warn_code = 0;
16487 * Read the board's EEPROM configuration.
16489 * Set default values if a bad checksum is found.
16491 if (AdvGet3550EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16493 warn_code |= ASC_WARN_EEPROM_CHKSUM;
16496 * Set EEPROM default values.
16498 for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++)
16500 *((uchar *) &eep_config + i) =
16501 *((uchar *) &Default_3550_EEPROM_Config + i);
16505 * Assume the 6 byte board serial number that was read
16506 * from EEPROM is correct even if the EEPROM checksum
16507 * failed.
16509 eep_config.serial_number_word3 =
16510 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16512 eep_config.serial_number_word2 =
16513 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16515 eep_config.serial_number_word1 =
16516 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16518 AdvSet3550EEPConfig(iop_base, &eep_config);
16521 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16522 * EEPROM configuration that was read.
16524 * This is the mapping of EEPROM fields to Adv Library fields.
16526 asc_dvc->wdtr_able = eep_config.wdtr_able;
16527 asc_dvc->sdtr_able = eep_config.sdtr_able;
16528 asc_dvc->ultra_able = eep_config.ultra_able;
16529 asc_dvc->tagqng_able = eep_config.tagqng_able;
16530 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16531 asc_dvc->max_host_qng = eep_config.max_host_qng;
16532 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16533 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16534 asc_dvc->start_motor = eep_config.start_motor;
16535 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16536 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16537 asc_dvc->no_scam = eep_config.scam_tolerant;
16538 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16539 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16540 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16543 * Set the host maximum queuing (max. 253, min. 16) and the per device
16544 * maximum queuing (max. 63, min. 4).
16546 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
16548 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16549 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
16551 /* If the value is zero, assume it is uninitialized. */
16552 if (eep_config.max_host_qng == 0)
16554 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16555 } else
16557 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16561 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
16563 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16564 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
16566 /* If the value is zero, assume it is uninitialized. */
16567 if (eep_config.max_dvc_qng == 0)
16569 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16570 } else
16572 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16577 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16578 * set 'max_dvc_qng' to 'max_host_qng'.
16580 if (eep_config.max_dvc_qng > eep_config.max_host_qng)
16582 eep_config.max_dvc_qng = eep_config.max_host_qng;
16586 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16587 * values based on possibly adjusted EEPROM values.
16589 asc_dvc->max_host_qng = eep_config.max_host_qng;
16590 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16594 * If the EEPROM 'termination' field is set to automatic (0), then set
16595 * the ADV_DVC_CFG 'termination' field to automatic also.
16597 * If the termination is specified with a non-zero 'termination'
16598 * value check that a legal value is set and set the ADV_DVC_CFG
16599 * 'termination' field appropriately.
16601 if (eep_config.termination == 0)
16603 asc_dvc->cfg->termination = 0; /* auto termination */
16604 } else
16606 /* Enable manual control with low off / high off. */
16607 if (eep_config.termination == 1)
16609 asc_dvc->cfg->termination = TERM_CTL_SEL;
16611 /* Enable manual control with low off / high on. */
16612 } else if (eep_config.termination == 2)
16614 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H;
16616 /* Enable manual control with low on / high on. */
16617 } else if (eep_config.termination == 3)
16619 asc_dvc->cfg->termination = TERM_CTL_SEL | TERM_CTL_H | TERM_CTL_L;
16620 } else
16623 * The EEPROM 'termination' field contains a bad value. Use
16624 * automatic termination instead.
16626 asc_dvc->cfg->termination = 0;
16627 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16631 return warn_code;
16635 * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and
16636 * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while
16637 * all of this is done.
16639 * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR.
16641 * For a non-fatal error return a warning code. If there are no warnings
16642 * then 0 is returned.
16644 * Note: Chip is stopped on entry.
16646 STATIC int __init
16647 AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc)
16649 AdvPortAddr iop_base;
16650 ushort warn_code;
16651 ADVEEP_38C0800_CONFIG eep_config;
16652 int i;
16653 uchar tid, termination;
16654 ushort sdtr_speed = 0;
16656 iop_base = asc_dvc->iop_base;
16658 warn_code = 0;
16661 * Read the board's EEPROM configuration.
16663 * Set default values if a bad checksum is found.
16665 if (AdvGet38C0800EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16667 warn_code |= ASC_WARN_EEPROM_CHKSUM;
16670 * Set EEPROM default values.
16672 for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++)
16674 *((uchar *) &eep_config + i) =
16675 *((uchar *) &Default_38C0800_EEPROM_Config + i);
16679 * Assume the 6 byte board serial number that was read
16680 * from EEPROM is correct even if the EEPROM checksum
16681 * failed.
16683 eep_config.serial_number_word3 =
16684 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16686 eep_config.serial_number_word2 =
16687 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16689 eep_config.serial_number_word1 =
16690 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16692 AdvSet38C0800EEPConfig(iop_base, &eep_config);
16695 * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the
16696 * EEPROM configuration that was read.
16698 * This is the mapping of EEPROM fields to Adv Library fields.
16700 asc_dvc->wdtr_able = eep_config.wdtr_able;
16701 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16702 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16703 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16704 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16705 asc_dvc->tagqng_able = eep_config.tagqng_able;
16706 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16707 asc_dvc->max_host_qng = eep_config.max_host_qng;
16708 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16709 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ADV_MAX_TID);
16710 asc_dvc->start_motor = eep_config.start_motor;
16711 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16712 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16713 asc_dvc->no_scam = eep_config.scam_tolerant;
16714 asc_dvc->cfg->serial1 = eep_config.serial_number_word1;
16715 asc_dvc->cfg->serial2 = eep_config.serial_number_word2;
16716 asc_dvc->cfg->serial3 = eep_config.serial_number_word3;
16719 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16720 * are set, then set an 'sdtr_able' bit for it.
16722 asc_dvc->sdtr_able = 0;
16723 for (tid = 0; tid <= ADV_MAX_TID; tid++)
16725 if (tid == 0)
16727 sdtr_speed = asc_dvc->sdtr_speed1;
16728 } else if (tid == 4)
16730 sdtr_speed = asc_dvc->sdtr_speed2;
16731 } else if (tid == 8)
16733 sdtr_speed = asc_dvc->sdtr_speed3;
16734 } else if (tid == 12)
16736 sdtr_speed = asc_dvc->sdtr_speed4;
16738 if (sdtr_speed & ADV_MAX_TID)
16740 asc_dvc->sdtr_able |= (1 << tid);
16742 sdtr_speed >>= 4;
16746 * Set the host maximum queuing (max. 253, min. 16) and the per device
16747 * maximum queuing (max. 63, min. 4).
16749 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
16751 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16752 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
16754 /* If the value is zero, assume it is uninitialized. */
16755 if (eep_config.max_host_qng == 0)
16757 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
16758 } else
16760 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
16764 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
16766 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16767 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
16769 /* If the value is zero, assume it is uninitialized. */
16770 if (eep_config.max_dvc_qng == 0)
16772 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
16773 } else
16775 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
16780 * If 'max_dvc_qng' is greater than 'max_host_qng', then
16781 * set 'max_dvc_qng' to 'max_host_qng'.
16783 if (eep_config.max_dvc_qng > eep_config.max_host_qng)
16785 eep_config.max_dvc_qng = eep_config.max_host_qng;
16789 * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng'
16790 * values based on possibly adjusted EEPROM values.
16792 asc_dvc->max_host_qng = eep_config.max_host_qng;
16793 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16796 * If the EEPROM 'termination' field is set to automatic (0), then set
16797 * the ADV_DVC_CFG 'termination' field to automatic also.
16799 * If the termination is specified with a non-zero 'termination'
16800 * value check that a legal value is set and set the ADV_DVC_CFG
16801 * 'termination' field appropriately.
16803 if (eep_config.termination_se == 0)
16805 termination = 0; /* auto termination for SE */
16806 } else
16808 /* Enable manual control with low off / high off. */
16809 if (eep_config.termination_se == 1)
16811 termination = 0;
16813 /* Enable manual control with low off / high on. */
16814 } else if (eep_config.termination_se == 2)
16816 termination = TERM_SE_HI;
16818 /* Enable manual control with low on / high on. */
16819 } else if (eep_config.termination_se == 3)
16821 termination = TERM_SE;
16822 } else
16825 * The EEPROM 'termination_se' field contains a bad value.
16826 * Use automatic termination instead.
16828 termination = 0;
16829 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16833 if (eep_config.termination_lvd == 0)
16835 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
16836 } else
16838 /* Enable manual control with low off / high off. */
16839 if (eep_config.termination_lvd == 1)
16841 asc_dvc->cfg->termination = termination;
16843 /* Enable manual control with low off / high on. */
16844 } else if (eep_config.termination_lvd == 2)
16846 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
16848 /* Enable manual control with low on / high on. */
16849 } else if (eep_config.termination_lvd == 3)
16851 asc_dvc->cfg->termination =
16852 termination | TERM_LVD;
16853 } else
16856 * The EEPROM 'termination_lvd' field contains a bad value.
16857 * Use automatic termination instead.
16859 asc_dvc->cfg->termination = termination;
16860 warn_code |= ASC_WARN_EEPROM_TERMINATION;
16864 return warn_code;
16868 * Read the board's EEPROM configuration. Set fields in ASC_DVC_VAR and
16869 * ASC_DVC_CFG based on the EEPROM settings. The chip is stopped while
16870 * all of this is done.
16872 * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR.
16874 * For a non-fatal error return a warning code. If there are no warnings
16875 * then 0 is returned.
16877 * Note: Chip is stopped on entry.
16879 STATIC int __init
16880 AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc)
16882 AdvPortAddr iop_base;
16883 ushort warn_code;
16884 ADVEEP_38C1600_CONFIG eep_config;
16885 int i;
16886 uchar tid, termination;
16887 ushort sdtr_speed = 0;
16889 iop_base = asc_dvc->iop_base;
16891 warn_code = 0;
16894 * Read the board's EEPROM configuration.
16896 * Set default values if a bad checksum is found.
16898 if (AdvGet38C1600EEPConfig(iop_base, &eep_config) != eep_config.check_sum)
16900 warn_code |= ASC_WARN_EEPROM_CHKSUM;
16903 * Set EEPROM default values.
16905 for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++)
16907 if (i == 1 && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) != 0)
16910 * Set Function 1 EEPROM Word 0 MSB
16912 * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11)
16913 * EEPROM bits.
16915 * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and
16916 * old Mac system booting problem. The Expansion ROM must
16917 * be disabled in Function 1 for these systems.
16920 *((uchar *) &eep_config + i) =
16921 ((*((uchar *) &Default_38C1600_EEPROM_Config + i)) &
16922 (~(((ADV_EEPROM_BIOS_ENABLE | ADV_EEPROM_INTAB) >> 8) &
16923 0xFF)));
16926 * Set the INTAB (bit 11) if the GPIO 0 input indicates
16927 * the Function 1 interrupt line is wired to INTA.
16929 * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input:
16930 * 1 - Function 1 interrupt line wired to INT A.
16931 * 0 - Function 1 interrupt line wired to INT B.
16933 * Note: Adapter boards always have Function 0 wired to INTA.
16934 * Put all 5 GPIO bits in input mode and then read
16935 * their input values.
16937 AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0);
16938 if (AdvReadByteRegister(iop_base, IOPB_GPIO_DATA) & 0x01)
16940 /* Function 1 interrupt wired to INTA; Set EEPROM bit. */
16941 *((uchar *) &eep_config + i) |=
16942 ((ADV_EEPROM_INTAB >> 8) & 0xFF);
16945 else
16947 *((uchar *) &eep_config + i) =
16948 *((uchar *) &Default_38C1600_EEPROM_Config + i);
16953 * Assume the 6 byte board serial number that was read
16954 * from EEPROM is correct even if the EEPROM checksum
16955 * failed.
16957 eep_config.serial_number_word3 =
16958 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1);
16960 eep_config.serial_number_word2 =
16961 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2);
16963 eep_config.serial_number_word1 =
16964 AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3);
16966 AdvSet38C1600EEPConfig(iop_base, &eep_config);
16970 * Set ASC_DVC_VAR and ASC_DVC_CFG variables from the
16971 * EEPROM configuration that was read.
16973 * This is the mapping of EEPROM fields to Adv Library fields.
16975 asc_dvc->wdtr_able = eep_config.wdtr_able;
16976 asc_dvc->sdtr_speed1 = eep_config.sdtr_speed1;
16977 asc_dvc->sdtr_speed2 = eep_config.sdtr_speed2;
16978 asc_dvc->sdtr_speed3 = eep_config.sdtr_speed3;
16979 asc_dvc->sdtr_speed4 = eep_config.sdtr_speed4;
16980 asc_dvc->ppr_able = 0;
16981 asc_dvc->tagqng_able = eep_config.tagqng_able;
16982 asc_dvc->cfg->disc_enable = eep_config.disc_enable;
16983 asc_dvc->max_host_qng = eep_config.max_host_qng;
16984 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
16985 asc_dvc->chip_scsi_id = (eep_config.adapter_scsi_id & ASC_MAX_TID);
16986 asc_dvc->start_motor = eep_config.start_motor;
16987 asc_dvc->scsi_reset_wait = eep_config.scsi_reset_delay;
16988 asc_dvc->bios_ctrl = eep_config.bios_ctrl;
16989 asc_dvc->no_scam = eep_config.scam_tolerant;
16992 * For every Target ID if any of its 'sdtr_speed[1234]' bits
16993 * are set, then set an 'sdtr_able' bit for it.
16995 asc_dvc->sdtr_able = 0;
16996 for (tid = 0; tid <= ASC_MAX_TID; tid++)
16998 if (tid == 0)
17000 sdtr_speed = asc_dvc->sdtr_speed1;
17001 } else if (tid == 4)
17003 sdtr_speed = asc_dvc->sdtr_speed2;
17004 } else if (tid == 8)
17006 sdtr_speed = asc_dvc->sdtr_speed3;
17007 } else if (tid == 12)
17009 sdtr_speed = asc_dvc->sdtr_speed4;
17011 if (sdtr_speed & ASC_MAX_TID)
17013 asc_dvc->sdtr_able |= (1 << tid);
17015 sdtr_speed >>= 4;
17019 * Set the host maximum queuing (max. 253, min. 16) and the per device
17020 * maximum queuing (max. 63, min. 4).
17022 if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG)
17024 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17025 } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG)
17027 /* If the value is zero, assume it is uninitialized. */
17028 if (eep_config.max_host_qng == 0)
17030 eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG;
17031 } else
17033 eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG;
17037 if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG)
17039 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17040 } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG)
17042 /* If the value is zero, assume it is uninitialized. */
17043 if (eep_config.max_dvc_qng == 0)
17045 eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG;
17046 } else
17048 eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG;
17053 * If 'max_dvc_qng' is greater than 'max_host_qng', then
17054 * set 'max_dvc_qng' to 'max_host_qng'.
17056 if (eep_config.max_dvc_qng > eep_config.max_host_qng)
17058 eep_config.max_dvc_qng = eep_config.max_host_qng;
17062 * Set ASC_DVC_VAR 'max_host_qng' and ASC_DVC_VAR 'max_dvc_qng'
17063 * values based on possibly adjusted EEPROM values.
17065 asc_dvc->max_host_qng = eep_config.max_host_qng;
17066 asc_dvc->max_dvc_qng = eep_config.max_dvc_qng;
17069 * If the EEPROM 'termination' field is set to automatic (0), then set
17070 * the ASC_DVC_CFG 'termination' field to automatic also.
17072 * If the termination is specified with a non-zero 'termination'
17073 * value check that a legal value is set and set the ASC_DVC_CFG
17074 * 'termination' field appropriately.
17076 if (eep_config.termination_se == 0)
17078 termination = 0; /* auto termination for SE */
17079 } else
17081 /* Enable manual control with low off / high off. */
17082 if (eep_config.termination_se == 1)
17084 termination = 0;
17086 /* Enable manual control with low off / high on. */
17087 } else if (eep_config.termination_se == 2)
17089 termination = TERM_SE_HI;
17091 /* Enable manual control with low on / high on. */
17092 } else if (eep_config.termination_se == 3)
17094 termination = TERM_SE;
17095 } else
17098 * The EEPROM 'termination_se' field contains a bad value.
17099 * Use automatic termination instead.
17101 termination = 0;
17102 warn_code |= ASC_WARN_EEPROM_TERMINATION;
17106 if (eep_config.termination_lvd == 0)
17108 asc_dvc->cfg->termination = termination; /* auto termination for LVD */
17109 } else
17111 /* Enable manual control with low off / high off. */
17112 if (eep_config.termination_lvd == 1)
17114 asc_dvc->cfg->termination = termination;
17116 /* Enable manual control with low off / high on. */
17117 } else if (eep_config.termination_lvd == 2)
17119 asc_dvc->cfg->termination = termination | TERM_LVD_HI;
17121 /* Enable manual control with low on / high on. */
17122 } else if (eep_config.termination_lvd == 3)
17124 asc_dvc->cfg->termination =
17125 termination | TERM_LVD;
17126 } else
17129 * The EEPROM 'termination_lvd' field contains a bad value.
17130 * Use automatic termination instead.
17132 asc_dvc->cfg->termination = termination;
17133 warn_code |= ASC_WARN_EEPROM_TERMINATION;
17137 return warn_code;
17141 * Read EEPROM configuration into the specified buffer.
17143 * Return a checksum based on the EEPROM configuration read.
17145 STATIC ushort __init
17146 AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
17148 ushort wval, chksum;
17149 ushort *wbuf;
17150 int eep_addr;
17151 ushort *charfields;
17153 charfields = (ushort *) &ADVEEP_3550_Config_Field_IsChar;
17154 wbuf = (ushort *) cfg_buf;
17155 chksum = 0;
17157 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17158 eep_addr < ADV_EEP_DVC_CFG_END;
17159 eep_addr++, wbuf++)
17161 wval = AdvReadEEPWord(iop_base, eep_addr);
17162 chksum += wval; /* Checksum is calculated from word values. */
17163 if (*charfields++) {
17164 *wbuf = le16_to_cpu(wval);
17165 } else {
17166 *wbuf = wval;
17169 /* Read checksum word. */
17170 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17171 wbuf++; charfields++;
17173 /* Read rest of EEPROM not covered by the checksum. */
17174 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17175 eep_addr < ADV_EEP_MAX_WORD_ADDR;
17176 eep_addr++, wbuf++)
17178 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17179 if (*charfields++) {
17180 *wbuf = le16_to_cpu(*wbuf);
17183 return chksum;
17187 * Read EEPROM configuration into the specified buffer.
17189 * Return a checksum based on the EEPROM configuration read.
17191 STATIC ushort __init
17192 AdvGet38C0800EEPConfig(AdvPortAddr iop_base,
17193 ADVEEP_38C0800_CONFIG *cfg_buf)
17195 ushort wval, chksum;
17196 ushort *wbuf;
17197 int eep_addr;
17198 ushort *charfields;
17200 charfields = (ushort *) &ADVEEP_38C0800_Config_Field_IsChar;
17201 wbuf = (ushort *) cfg_buf;
17202 chksum = 0;
17204 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17205 eep_addr < ADV_EEP_DVC_CFG_END;
17206 eep_addr++, wbuf++)
17208 wval = AdvReadEEPWord(iop_base, eep_addr);
17209 chksum += wval; /* Checksum is calculated from word values. */
17210 if (*charfields++) {
17211 *wbuf = le16_to_cpu(wval);
17212 } else {
17213 *wbuf = wval;
17216 /* Read checksum word. */
17217 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17218 wbuf++; charfields++;
17220 /* Read rest of EEPROM not covered by the checksum. */
17221 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17222 eep_addr < ADV_EEP_MAX_WORD_ADDR;
17223 eep_addr++, wbuf++)
17225 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17226 if (*charfields++) {
17227 *wbuf = le16_to_cpu(*wbuf);
17230 return chksum;
17234 * Read EEPROM configuration into the specified buffer.
17236 * Return a checksum based on the EEPROM configuration read.
17238 STATIC ushort __init
17239 AdvGet38C1600EEPConfig(AdvPortAddr iop_base,
17240 ADVEEP_38C1600_CONFIG *cfg_buf)
17242 ushort wval, chksum;
17243 ushort *wbuf;
17244 int eep_addr;
17245 ushort *charfields;
17247 charfields = (ushort*) &ADVEEP_38C1600_Config_Field_IsChar;
17248 wbuf = (ushort *) cfg_buf;
17249 chksum = 0;
17251 for (eep_addr = ADV_EEP_DVC_CFG_BEGIN;
17252 eep_addr < ADV_EEP_DVC_CFG_END;
17253 eep_addr++, wbuf++)
17255 wval = AdvReadEEPWord(iop_base, eep_addr);
17256 chksum += wval; /* Checksum is calculated from word values. */
17257 if (*charfields++) {
17258 *wbuf = le16_to_cpu(wval);
17259 } else {
17260 *wbuf = wval;
17263 /* Read checksum word. */
17264 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17265 wbuf++; charfields++;
17267 /* Read rest of EEPROM not covered by the checksum. */
17268 for (eep_addr = ADV_EEP_DVC_CTL_BEGIN;
17269 eep_addr < ADV_EEP_MAX_WORD_ADDR;
17270 eep_addr++, wbuf++)
17272 *wbuf = AdvReadEEPWord(iop_base, eep_addr);
17273 if (*charfields++) {
17274 *wbuf = le16_to_cpu(*wbuf);
17277 return chksum;
17281 * Read the EEPROM from specified location
17283 STATIC ushort __init
17284 AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr)
17286 AdvWriteWordRegister(iop_base, IOPW_EE_CMD,
17287 ASC_EEP_CMD_READ | eep_word_addr);
17288 AdvWaitEEPCmd(iop_base);
17289 return AdvReadWordRegister(iop_base, IOPW_EE_DATA);
17293 * Wait for EEPROM command to complete
17295 STATIC void __init
17296 AdvWaitEEPCmd(AdvPortAddr iop_base)
17298 int eep_delay_ms;
17300 for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++)
17302 if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE)
17304 break;
17306 DvcSleepMilliSecond(1);
17308 if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == 0)
17310 ASC_ASSERT(0);
17312 return;
17316 * Write the EEPROM from 'cfg_buf'.
17318 void __init
17319 AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf)
17321 ushort *wbuf;
17322 ushort addr, chksum;
17323 ushort *charfields;
17325 wbuf = (ushort *) cfg_buf;
17326 charfields = (ushort *) &ADVEEP_3550_Config_Field_IsChar;
17327 chksum = 0;
17329 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17330 AdvWaitEEPCmd(iop_base);
17333 * Write EEPROM from word 0 to word 20.
17335 for (addr = ADV_EEP_DVC_CFG_BEGIN;
17336 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17338 ushort word;
17340 if (*charfields++) {
17341 word = cpu_to_le16(*wbuf);
17342 } else {
17343 word = *wbuf;
17345 chksum += *wbuf; /* Checksum is calculated from word values. */
17346 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17347 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17348 AdvWaitEEPCmd(iop_base);
17349 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17353 * Write EEPROM checksum at word 21.
17355 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17356 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17357 AdvWaitEEPCmd(iop_base);
17358 wbuf++; charfields++;
17361 * Write EEPROM OEM name at words 22 to 29.
17363 for (addr = ADV_EEP_DVC_CTL_BEGIN;
17364 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17366 ushort word;
17368 if (*charfields++) {
17369 word = cpu_to_le16(*wbuf);
17370 } else {
17371 word = *wbuf;
17373 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17374 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17375 AdvWaitEEPCmd(iop_base);
17377 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17378 AdvWaitEEPCmd(iop_base);
17379 return;
17383 * Write the EEPROM from 'cfg_buf'.
17385 void __init
17386 AdvSet38C0800EEPConfig(AdvPortAddr iop_base,
17387 ADVEEP_38C0800_CONFIG *cfg_buf)
17389 ushort *wbuf;
17390 ushort *charfields;
17391 ushort addr, chksum;
17393 wbuf = (ushort *) cfg_buf;
17394 charfields = (ushort *) &ADVEEP_38C0800_Config_Field_IsChar;
17395 chksum = 0;
17397 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17398 AdvWaitEEPCmd(iop_base);
17401 * Write EEPROM from word 0 to word 20.
17403 for (addr = ADV_EEP_DVC_CFG_BEGIN;
17404 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17406 ushort word;
17408 if (*charfields++) {
17409 word = cpu_to_le16(*wbuf);
17410 } else {
17411 word = *wbuf;
17413 chksum += *wbuf; /* Checksum is calculated from word values. */
17414 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17415 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17416 AdvWaitEEPCmd(iop_base);
17417 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17421 * Write EEPROM checksum at word 21.
17423 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17424 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17425 AdvWaitEEPCmd(iop_base);
17426 wbuf++; charfields++;
17429 * Write EEPROM OEM name at words 22 to 29.
17431 for (addr = ADV_EEP_DVC_CTL_BEGIN;
17432 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17434 ushort word;
17436 if (*charfields++) {
17437 word = cpu_to_le16(*wbuf);
17438 } else {
17439 word = *wbuf;
17441 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17442 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17443 AdvWaitEEPCmd(iop_base);
17445 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17446 AdvWaitEEPCmd(iop_base);
17447 return;
17451 * Write the EEPROM from 'cfg_buf'.
17453 void __init
17454 AdvSet38C1600EEPConfig(AdvPortAddr iop_base,
17455 ADVEEP_38C1600_CONFIG *cfg_buf)
17457 ushort *wbuf;
17458 ushort *charfields;
17459 ushort addr, chksum;
17461 wbuf = (ushort *) cfg_buf;
17462 charfields = (ushort *) &ADVEEP_38C1600_Config_Field_IsChar;
17463 chksum = 0;
17465 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE);
17466 AdvWaitEEPCmd(iop_base);
17469 * Write EEPROM from word 0 to word 20.
17471 for (addr = ADV_EEP_DVC_CFG_BEGIN;
17472 addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++)
17474 ushort word;
17476 if (*charfields++) {
17477 word = cpu_to_le16(*wbuf);
17478 } else {
17479 word = *wbuf;
17481 chksum += *wbuf; /* Checksum is calculated from word values. */
17482 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17483 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17484 AdvWaitEEPCmd(iop_base);
17485 DvcSleepMilliSecond(ADV_EEP_DELAY_MS);
17489 * Write EEPROM checksum at word 21.
17491 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum);
17492 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17493 AdvWaitEEPCmd(iop_base);
17494 wbuf++; charfields++;
17497 * Write EEPROM OEM name at words 22 to 29.
17499 for (addr = ADV_EEP_DVC_CTL_BEGIN;
17500 addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++)
17502 ushort word;
17504 if (*charfields++) {
17505 word = cpu_to_le16(*wbuf);
17506 } else {
17507 word = *wbuf;
17509 AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word);
17510 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr);
17511 AdvWaitEEPCmd(iop_base);
17513 AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE);
17514 AdvWaitEEPCmd(iop_base);
17515 return;
17518 /* a_advlib.c */
17520 * AdvExeScsiQueue() - Send a request to the RISC microcode program.
17522 * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q,
17523 * add the carrier to the ICQ (Initiator Command Queue), and tickle the
17524 * RISC to notify it a new command is ready to be executed.
17526 * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be
17527 * set to SCSI_MAX_RETRY.
17529 * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode
17530 * for DMA addresses or math operations are byte swapped to little-endian
17531 * order.
17533 * Return:
17534 * ADV_SUCCESS(1) - The request was successfully queued.
17535 * ADV_BUSY(0) - Resource unavailable; Retry again after pending
17536 * request completes.
17537 * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure
17538 * host IC error.
17540 STATIC int
17541 AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc,
17542 ADV_SCSI_REQ_Q *scsiq)
17544 ulong last_int_level;
17545 AdvPortAddr iop_base;
17546 ADV_DCNT req_size;
17547 ADV_PADDR req_paddr;
17548 ADV_CARR_T *new_carrp;
17550 ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */
17553 * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID.
17555 if (scsiq->target_id > ADV_MAX_TID)
17557 scsiq->host_status = QHSTA_M_INVALID_DEVICE;
17558 scsiq->done_status = QD_WITH_ERROR;
17559 return ADV_ERROR;
17562 iop_base = asc_dvc->iop_base;
17564 last_int_level = DvcEnterCritical();
17567 * Allocate a carrier ensuring at least one carrier always
17568 * remains on the freelist and initialize fields.
17570 if ((new_carrp = asc_dvc->carr_freelist) == NULL)
17572 DvcLeaveCritical(last_int_level);
17573 return ADV_BUSY;
17575 asc_dvc->carr_freelist = (ADV_CARR_T *)
17576 ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa));
17577 asc_dvc->carr_pending_cnt++;
17580 * Set the carrier to be a stopper by setting 'next_vpa'
17581 * to the stopper value. The current stopper will be changed
17582 * below to point to the new stopper.
17584 new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER);
17587 * Clear the ADV_SCSI_REQ_Q done flag.
17589 scsiq->a_flag &= ~ADV_SCSIQ_DONE;
17591 req_size = sizeof(ADV_SCSI_REQ_Q);
17592 req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *) scsiq,
17593 (ADV_SDCNT *) &req_size, ADV_IS_SCSIQ_FLAG);
17595 ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr);
17596 ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q));
17598 /* Wait for assertion before making little-endian */
17599 req_paddr = cpu_to_le32(req_paddr);
17601 /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */
17602 scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq));
17603 scsiq->scsiq_rptr = req_paddr;
17605 scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp));
17607 * Every ADV_CARR_T.carr_pa is byte swapped to little-endian
17608 * order during initialization.
17610 scsiq->carr_pa = asc_dvc->icq_sp->carr_pa;
17613 * Use the current stopper to send the ADV_SCSI_REQ_Q command to
17614 * the microcode. The newly allocated stopper will become the new
17615 * stopper.
17617 asc_dvc->icq_sp->areq_vpa = req_paddr;
17620 * Set the 'next_vpa' pointer for the old stopper to be the
17621 * physical address of the new stopper. The RISC can only
17622 * follow physical addresses.
17624 asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa;
17627 * Set the host adapter stopper pointer to point to the new carrier.
17629 asc_dvc->icq_sp = new_carrp;
17631 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17632 asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
17635 * Tickle the RISC to tell it to read its Command Queue Head pointer.
17637 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
17638 if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
17641 * Clear the tickle value. In the ASC-3550 the RISC flag
17642 * command 'clr_tickle_a' does not work unless the host
17643 * value is cleared.
17645 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17647 } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17650 * Notify the RISC a carrier is ready by writing the physical
17651 * address of the new carrier stopper to the COMMA register.
17653 AdvWriteDWordRegister(iop_base, IOPDW_COMMA,
17654 le32_to_cpu(new_carrp->carr_pa));
17657 DvcLeaveCritical(last_int_level);
17659 return ADV_SUCCESS;
17663 * Reset SCSI Bus and purge all outstanding requests.
17665 * Return Value:
17666 * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset.
17667 * ADV_FALSE(0) - Microcode command failed.
17668 * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC
17669 * may be hung which requires driver recovery.
17671 STATIC int
17672 AdvResetSB(ADV_DVC_VAR *asc_dvc)
17674 int status;
17677 * Send the SCSI Bus Reset idle start idle command which asserts
17678 * the SCSI Bus Reset signal.
17680 status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_START, 0L);
17681 if (status != ADV_TRUE)
17683 return status;
17687 * Delay for the specified SCSI Bus Reset hold time.
17689 * The hold time delay is done on the host because the RISC has no
17690 * microsecond accurate timer.
17692 DvcDelayMicroSecond(asc_dvc, (ushort) ASC_SCSI_RESET_HOLD_TIME_US);
17695 * Send the SCSI Bus Reset end idle command which de-asserts
17696 * the SCSI Bus Reset signal and purges any pending requests.
17698 status = AdvSendIdleCmd(asc_dvc, (ushort) IDLE_CMD_SCSI_RESET_END, 0L);
17699 if (status != ADV_TRUE)
17701 return status;
17704 DvcSleepMilliSecond((ADV_DCNT) asc_dvc->scsi_reset_wait * 1000);
17706 return status;
17710 * Reset chip and SCSI Bus.
17712 * Return Value:
17713 * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful.
17714 * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure.
17716 STATIC int
17717 AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc)
17719 int status;
17720 ushort wdtr_able, sdtr_able, tagqng_able;
17721 ushort ppr_able = 0;
17722 uchar tid, max_cmd[ADV_MAX_TID + 1];
17723 AdvPortAddr iop_base;
17724 ushort bios_sig;
17726 iop_base = asc_dvc->iop_base;
17729 * Save current per TID negotiated values.
17731 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17732 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17733 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17735 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17737 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17738 for (tid = 0; tid <= ADV_MAX_TID; tid++)
17740 AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17741 max_cmd[tid]);
17745 * Force the AdvInitAsc3550/38C0800Driver() function to
17746 * perform a SCSI Bus Reset by clearing the BIOS signature word.
17747 * The initialization functions assumes a SCSI Bus Reset is not
17748 * needed if the BIOS signature word is present.
17750 AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17751 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0);
17754 * Stop chip and reset it.
17756 AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP);
17757 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET);
17758 DvcSleepMilliSecond(100);
17759 AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_WR_IO_REG);
17762 * Reset Adv Library error code, if any, and try
17763 * re-initializing the chip.
17765 asc_dvc->err_code = 0;
17766 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17768 status = AdvInitAsc38C1600Driver(asc_dvc);
17770 else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
17772 status = AdvInitAsc38C0800Driver(asc_dvc);
17773 } else
17775 status = AdvInitAsc3550Driver(asc_dvc);
17778 /* Translate initialization return value to status value. */
17779 if (status == 0)
17781 status = ADV_TRUE;
17782 } else
17784 status = ADV_FALSE;
17788 * Restore the BIOS signature word.
17790 AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig);
17793 * Restore per TID negotiated values.
17795 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able);
17796 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able);
17797 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600)
17799 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able);
17801 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able);
17802 for (tid = 0; tid <= ADV_MAX_TID; tid++)
17804 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
17805 max_cmd[tid]);
17808 return status;
17812 * Adv Library Interrupt Service Routine
17814 * This function is called by a driver's interrupt service routine.
17815 * The function disables and re-enables interrupts.
17817 * When a microcode idle command is completed, the ADV_DVC_VAR
17818 * 'idle_cmd_done' field is set to ADV_TRUE.
17820 * Note: AdvISR() can be called when interrupts are disabled or even
17821 * when there is no hardware interrupt condition present. It will
17822 * always check for completed idle commands and microcode requests.
17823 * This is an important feature that shouldn't be changed because it
17824 * allows commands to be completed from polling mode loops.
17826 * Return:
17827 * ADV_TRUE(1) - interrupt was pending
17828 * ADV_FALSE(0) - no interrupt was pending
17830 STATIC int
17831 AdvISR(ADV_DVC_VAR *asc_dvc)
17833 AdvPortAddr iop_base;
17834 uchar int_stat;
17835 ushort target_bit;
17836 ADV_CARR_T *free_carrp;
17837 ADV_VADDR irq_next_vpa;
17838 int flags;
17839 ADV_SCSI_REQ_Q *scsiq;
17841 flags = DvcEnterCritical();
17843 iop_base = asc_dvc->iop_base;
17845 /* Reading the register clears the interrupt. */
17846 int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG);
17848 if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB |
17849 ADV_INTR_STATUS_INTRC)) == 0)
17851 DvcLeaveCritical(flags);
17852 return ADV_FALSE;
17856 * Notify the driver of an asynchronous microcode condition by
17857 * calling the ADV_DVC_VAR.async_callback function. The function
17858 * is passed the microcode ASC_MC_INTRB_CODE byte value.
17860 if (int_stat & ADV_INTR_STATUS_INTRB)
17862 uchar intrb_code;
17864 AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code);
17866 if (asc_dvc->chip_type == ADV_CHIP_ASC3550 ||
17867 asc_dvc->chip_type == ADV_CHIP_ASC38C0800)
17869 if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE &&
17870 asc_dvc->carr_pending_cnt != 0)
17872 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A);
17873 if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
17875 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
17880 if (asc_dvc->async_callback != 0)
17882 (*asc_dvc->async_callback)(asc_dvc, intrb_code);
17887 * Check if the IRQ stopper carrier contains a completed request.
17889 while (((irq_next_vpa =
17890 le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0)
17893 * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure.
17894 * The RISC will have set 'areq_vpa' to a virtual address.
17896 * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr
17897 * field to the carrier ADV_CARR_T.areq_vpa field. The conversion
17898 * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr'
17899 * in AdvExeScsiQueue().
17901 scsiq = (ADV_SCSI_REQ_Q *)
17902 ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa));
17905 * Request finished with good status and the queue was not
17906 * DMAed to host memory by the firmware. Set all status fields
17907 * to indicate good status.
17909 if ((irq_next_vpa & ASC_RQ_GOOD) != 0)
17911 scsiq->done_status = QD_NO_ERROR;
17912 scsiq->host_status = scsiq->scsi_status = 0;
17913 scsiq->data_cnt = 0L;
17917 * Advance the stopper pointer to the next carrier
17918 * ignoring the lower four bits. Free the previous
17919 * stopper carrier.
17921 free_carrp = asc_dvc->irq_sp;
17922 asc_dvc->irq_sp = (ADV_CARR_T *)
17923 ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa));
17925 free_carrp->next_vpa =
17926 cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist));
17927 asc_dvc->carr_freelist = free_carrp;
17928 asc_dvc->carr_pending_cnt--;
17930 ASC_ASSERT(scsiq != NULL);
17931 target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id);
17934 * Clear request microcode control flag.
17936 scsiq->cntl = 0;
17939 * If the command that completed was a SCSI INQUIRY and
17940 * LUN 0 was sent the command, then process the INQUIRY
17941 * command information for the device.
17943 * Note: If data returned were either VPD or CmdDt data,
17944 * don't process the INQUIRY command information for
17945 * the device, otherwise may erroneously set *_able bits.
17947 if (scsiq->done_status == QD_NO_ERROR &&
17948 scsiq->cdb[0] == INQUIRY &&
17949 scsiq->target_lun == 0 &&
17950 (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT)
17951 == ADV_INQ_RTN_STD_INQUIRY_DATA)
17953 AdvInquiryHandling(asc_dvc, scsiq);
17957 * Notify the driver of the completed request by passing
17958 * the ADV_SCSI_REQ_Q pointer to its callback function.
17960 scsiq->a_flag |= ADV_SCSIQ_DONE;
17961 (*asc_dvc->isr_callback)(asc_dvc, scsiq);
17963 * Note: After the driver callback function is called, 'scsiq'
17964 * can no longer be referenced.
17966 * Fall through and continue processing other completed
17967 * requests...
17971 * Disable interrupts again in case the driver inadvertently
17972 * enabled interrupts in its callback function.
17974 * The DvcEnterCritical() return value is ignored, because
17975 * the 'flags' saved when AdvISR() was first entered will be
17976 * used to restore the interrupt flag on exit.
17978 (void) DvcEnterCritical();
17980 DvcLeaveCritical(flags);
17981 return ADV_TRUE;
17985 * Send an idle command to the chip and wait for completion.
17987 * Command completion is polled for once per microsecond.
17989 * The function can be called from anywhere including an interrupt handler.
17990 * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical()
17991 * functions to prevent reentrancy.
17993 * Return Values:
17994 * ADV_TRUE - command completed successfully
17995 * ADV_FALSE - command failed
17996 * ADV_ERROR - command timed out
17998 STATIC int
17999 AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc,
18000 ushort idle_cmd,
18001 ADV_DCNT idle_cmd_parameter)
18003 ulong last_int_level;
18004 int result;
18005 ADV_DCNT i, j;
18006 AdvPortAddr iop_base;
18008 last_int_level = DvcEnterCritical();
18010 iop_base = asc_dvc->iop_base;
18013 * Clear the idle command status which is set by the microcode
18014 * to a non-zero value to indicate when the command is completed.
18015 * The non-zero result is one of the IDLE_CMD_STATUS_* values
18016 * defined in a_advlib.h.
18018 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort) 0);
18021 * Write the idle command value after the idle command parameter
18022 * has been written to avoid a race condition. If the order is not
18023 * followed, the microcode may process the idle command before the
18024 * parameters have been written to LRAM.
18026 AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER,
18027 cpu_to_le32(idle_cmd_parameter));
18028 AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd);
18031 * Tickle the RISC to tell it to process the idle command.
18033 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B);
18034 if (asc_dvc->chip_type == ADV_CHIP_ASC3550)
18037 * Clear the tickle value. In the ASC-3550 the RISC flag
18038 * command 'clr_tickle_b' does not work unless the host
18039 * value is cleared.
18041 AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP);
18044 /* Wait for up to 100 millisecond for the idle command to timeout. */
18045 for (i = 0; i < SCSI_WAIT_100_MSEC; i++)
18047 /* Poll once each microsecond for command completion. */
18048 for (j = 0; j < SCSI_US_PER_MSEC; j++)
18050 AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, result);
18051 if (result != 0)
18053 DvcLeaveCritical(last_int_level);
18054 return result;
18056 DvcDelayMicroSecond(asc_dvc, (ushort) 1);
18060 ASC_ASSERT(0); /* The idle command should never timeout. */
18061 DvcLeaveCritical(last_int_level);
18062 return ADV_ERROR;
18066 * Inquiry Information Byte 7 Handling
18068 * Handle SCSI Inquiry Command information for a device by setting
18069 * microcode operating variables that affect WDTR, SDTR, and Tag
18070 * Queuing.
18072 STATIC void
18073 AdvInquiryHandling(
18074 ADV_DVC_VAR *asc_dvc,
18075 ADV_SCSI_REQ_Q *scsiq)
18077 AdvPortAddr iop_base;
18078 uchar tid;
18079 ADV_SCSI_INQUIRY *inq;
18080 ushort tidmask;
18081 ushort cfg_word;
18084 * AdvInquiryHandling() requires up to INQUIRY information Byte 7
18085 * to be available.
18087 * If less than 8 bytes of INQUIRY information were requested or less
18088 * than 8 bytes were transferred, then return. cdb[4] is the request
18089 * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the
18090 * microcode to the transfer residual count.
18093 if (scsiq->cdb[4] < 8 ||
18094 (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8)
18096 return;
18099 iop_base = asc_dvc->iop_base;
18100 tid = scsiq->target_id;
18102 inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr;
18105 * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices.
18107 if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2)
18109 return;
18110 } else
18113 * INQUIRY Byte 7 Handling
18115 * Use a device's INQUIRY byte 7 to determine whether it
18116 * supports WDTR, SDTR, and Tag Queuing. If the feature
18117 * is enabled in the EEPROM and the device supports the
18118 * feature, then enable it in the microcode.
18121 tidmask = ADV_TID_TO_TIDMASK(tid);
18124 * Wide Transfers
18126 * If the EEPROM enabled WDTR for the device and the device
18127 * supports wide bus (16 bit) transfers, then turn on the
18128 * device's 'wdtr_able' bit and write the new value to the
18129 * microcode.
18131 if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq))
18133 AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
18134 if ((cfg_word & tidmask) == 0)
18136 cfg_word |= tidmask;
18137 AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word);
18140 * Clear the microcode "SDTR negotiation" and "WDTR
18141 * negotiation" done indicators for the target to cause
18142 * it to negotiate with the new setting set above.
18143 * WDTR when accepted causes the target to enter
18144 * asynchronous mode, so SDTR must be negotiated.
18146 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18147 cfg_word &= ~tidmask;
18148 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18149 AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
18150 cfg_word &= ~tidmask;
18151 AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word);
18156 * Synchronous Transfers
18158 * If the EEPROM enabled SDTR for the device and the device
18159 * supports synchronous transfers, then turn on the device's
18160 * 'sdtr_able' bit. Write the new value to the microcode.
18162 if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq))
18164 AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
18165 if ((cfg_word & tidmask) == 0)
18167 cfg_word |= tidmask;
18168 AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word);
18171 * Clear the microcode "SDTR negotiation" done indicator
18172 * for the target to cause it to negotiate with the new
18173 * setting set above.
18175 AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18176 cfg_word &= ~tidmask;
18177 AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word);
18181 * If the Inquiry data included enough space for the SPI-3
18182 * Clocking field, then check if DT mode is supported.
18184 if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 &&
18185 (scsiq->cdb[4] >= 57 ||
18186 (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57))
18189 * PPR (Parallel Protocol Request) Capable
18191 * If the device supports DT mode, then it must be PPR capable.
18192 * The PPR message will be used in place of the SDTR and WDTR
18193 * messages to negotiate synchronous speed and offset, transfer
18194 * width, and protocol options.
18196 if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY)
18198 AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, asc_dvc->ppr_able);
18199 asc_dvc->ppr_able |= tidmask;
18200 AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, asc_dvc->ppr_able);
18205 * If the EEPROM enabled Tag Queuing for the device and the
18206 * device supports Tag Queueing, then turn on the device's
18207 * 'tagqng_enable' bit in the microcode and set the microcode
18208 * maximum command count to the ADV_DVC_VAR 'max_dvc_qng'
18209 * value.
18211 * Tag Queuing is disabled for the BIOS which runs in polled
18212 * mode and would see no benefit from Tag Queuing. Also by
18213 * disabling Tag Queuing in the BIOS devices with Tag Queuing
18214 * bugs will at least work with the BIOS.
18216 if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq))
18218 AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
18219 cfg_word |= tidmask;
18220 AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word);
18222 AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid,
18223 asc_dvc->max_dvc_qng);
18227 MODULE_LICENSE("Dual BSD/GPL");